import { useEffect, useCallback, useMemo } from "react";
import { useConfigStore } from "@/store/configStore";
import { useSwipeBack } from "@/hooks/useSwipeBack";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Users } from "lucide-react";
import {
  EditorPanel,
  EditorPanelEmptyState,
  FieldGroup,
  HistoryContextSection,
} from "@/components/shared";
import { useForm, Controller } from "react-hook-form";
import { Team } from "@/types/config";
import { useScopedConfigValidation } from "@/hooks/useScopedConfigValidation";

const AGENT_POLICY_UNAVAILABLE_REASON =
  "Agent policy preview is unavailable. Save or refresh to validate team eligibility.";

export function TeamEditor() {
  const {
    teams,
    agents,
    rooms,
    selectedTeamId,
    updateTeam,
    deleteTeam,
    saveConfig,
    agentPoliciesByAgent,
    config,
    isDirty,
    isLoading,
    selectTeam,
  } = useConfigStore();

  const selectedTeam = teams.find((t) => t.id === selectedTeamId);
  const validationPrefix = useMemo<Array<string | number> | null>(
    () => (selectedTeamId == null ? null : ["teams", selectedTeamId]),
    [selectedTeamId],
  );
  const validationErrorForPath = useScopedConfigValidation(validationPrefix);
  const teamRootError = validationErrorForPath([], true);
  const displayNameError = validationErrorForPath(["display_name"], true);
  const roleError = validationErrorForPath(["role"], true);
  const modeError = validationErrorForPath(["mode"], true);
  const modelError = validationErrorForPath(["model"], true);
  const numHistoryRunsError = validationErrorForPath(
    ["num_history_runs"],
    true,
  );
  const numHistoryMessagesError = validationErrorForPath(
    ["num_history_messages"],
    true,
  );
  const maxToolCallsFromHistoryError = validationErrorForPath(
    ["max_tool_calls_from_history"],
    true,
  );
  const compactionError = validationErrorForPath(["compaction"], true);
  const membersError = validationErrorForPath(["agents"]);
  const roomsError = validationErrorForPath(["rooms"]);

  // Enable swipe back on mobile
  useSwipeBack({
    onSwipeBack: () => selectTeam(null),
    enabled: !!selectedTeamId && window.innerWidth < 1024,
  });

  const { control, reset, setValue, getValues } = useForm<Team>({
    defaultValues: selectedTeam || {
      id: "",
      display_name: "",
      role: "",
      agents: [],
      rooms: [],
      mode: "coordinate",
      compaction: undefined,
    },
  });
  // Reset form when selected team changes
  useEffect(() => {
    if (selectedTeam) {
      reset({
        ...selectedTeam,
        compaction: selectedTeam.compaction ?? undefined,
      });
    }
  }, [selectedTeam, reset]);

  // Let the store normalize against current state so sequential UI updates do not
  // reuse stale render-time team data.
  const handleFieldChange = useCallback(
    <K extends keyof Team>(fieldName: K, value: Team[K]) => {
      if (selectedTeamId) {
        updateTeam(selectedTeamId, { [fieldName]: value });
      }
    },
    [selectedTeamId, updateTeam],
  );

  const updateCompaction = useCallback(
    (nextCompaction: Team["compaction"]) => {
      setValue("compaction", nextCompaction);
      handleFieldChange("compaction", nextCompaction);
    },
    [handleFieldChange, setValue],
  );

  const mutateCompaction = useCallback(
    (mutator: (current: Team["compaction"]) => Team["compaction"]) => {
      updateCompaction(mutator(getValues("compaction")));
    },
    [getValues, updateCompaction],
  );

  const handleDelete = () => {
    if (
      selectedTeamId &&
      confirm("Are you sure you want to delete this team?")
    ) {
      deleteTeam(selectedTeamId);
    }
  };

  const handleSave = async () => {
    return saveConfig();
  };

  if (!selectedTeam) {
    return (
      <EditorPanelEmptyState icon={Users} message="Select a team to edit" />
    );
  }

  return (
    <EditorPanel
      icon={Users}
      title="Team Details"
      isDirty={isDirty}
      onSave={handleSave}
      onDelete={handleDelete}
      disableSave={isLoading}
      onBack={() => selectTeam(null)}
    >
      {teamRootError && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-sm text-destructive">
          {teamRootError}
        </div>
      )}

      {/* Display Name */}
      <FieldGroup
        label="Display Name"
        helperText="Human-readable name for the team"
        htmlFor="display_name"
        error={displayNameError}
      >
        <Controller
          name="display_name"
          control={control}
          render={({ field }) => (
            <Input
              {...field}
              id="display_name"
              placeholder="Team display name"
              onChange={(e) => {
                field.onChange(e);
                handleFieldChange("display_name", e.target.value);
              }}
            />
          )}
        />
      </FieldGroup>

      {/* Role */}
      <FieldGroup
        label="Team Purpose"
        helperText="Description of the team's purpose and what it does"
        htmlFor="role"
        error={roleError}
      >
        <Controller
          name="role"
          control={control}
          render={({ field }) => (
            <Textarea
              {...field}
              id="role"
              placeholder="What this team does..."
              rows={2}
              onChange={(e) => {
                field.onChange(e);
                handleFieldChange("role", e.target.value);
              }}
            />
          )}
        />
      </FieldGroup>

      {/* Collaboration Mode */}
      <FieldGroup
        label="Collaboration Mode"
        helperText="How agents work together: sequential (coordinate) or parallel (collaborate)"
        htmlFor="mode"
        error={modeError}
      >
        <Controller
          name="mode"
          control={control}
          render={({ field }) => (
            <Select
              value={field.value}
              onValueChange={(value) => {
                field.onChange(value);
                handleFieldChange(
                  "mode",
                  value as "coordinate" | "collaborate",
                );
              }}
            >
              <SelectTrigger id="mode">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="coordinate">
                  Coordinate (Sequential - agents work one after another)
                </SelectItem>
                <SelectItem value="collaborate">
                  Collaborate (Parallel - agents work simultaneously)
                </SelectItem>
              </SelectContent>
            </Select>
          )}
        />
      </FieldGroup>

      {/* Model Selection */}
      <FieldGroup
        label="Team Model (Optional)"
        helperText="Override model for all agents in this team"
        htmlFor="model"
        error={modelError}
      >
        <Controller
          name="model"
          control={control}
          render={({ field }) => (
            <Select
              value={field.value || "default_model"}
              onValueChange={(value) => {
                const newValue = value === "default_model" ? undefined : value;
                field.onChange(newValue);
                handleFieldChange("model", newValue);
              }}
            >
              <SelectTrigger id="model">
                <SelectValue placeholder="Use default model" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="default_model">Use default model</SelectItem>
                {config &&
                  Object.keys(config.models).map((modelId) => (
                    <SelectItem key={modelId} value={modelId}>
                      {modelId}
                    </SelectItem>
                  ))}
              </SelectContent>
            </Select>
          )}
        />
      </FieldGroup>

      <HistoryContextSection
        control={control}
        resetKey={selectedTeamId}
        defaults={config?.defaults}
        onFieldChange={(fieldName, value) =>
          handleFieldChange(fieldName as keyof Team, value as Team[keyof Team])
        }
        updateCompaction={updateCompaction}
        mutateCompaction={mutateCompaction}
        historyRunsHelperText={`Number of prior team-scoped runs to include as replay. Leave empty to use default${
          config?.defaults.num_history_runs != null
            ? ` (${config.defaults.num_history_runs})`
            : " (all)"
        }.`}
        historyMessagesHelperText={`Max replay messages from team-scoped history. Leave empty to use default${
          config?.defaults.num_history_messages != null
            ? ` (${config.defaults.num_history_messages})`
            : " (all)"
        }.`}
        maxToolCallsHelperText={`Max tool call messages replayed from team history. Leave empty to use default${
          config?.defaults.max_tool_calls_from_history != null
            ? ` (${config.defaults.max_tool_calls_from_history})`
            : " (no limit)"
        }.`}
        autoCompactionHelperText="Automatically compact older team-scoped history before the next run when raw replay exceeds the hard context budget."
        thresholdTokensHelperText="Soft replay budget in tokens. Crossing it records planning metadata; destructive compaction waits for the hard budget."
        compactionModelPlaceholder={
          config?.defaults.compaction?.model ?? "Default: team run model"
        }
        numHistoryRunsError={numHistoryRunsError}
        numHistoryMessagesError={numHistoryMessagesError}
        maxToolCallsFromHistoryError={maxToolCallsFromHistoryError}
        compactionError={compactionError}
      />

      {/* Team Members (Agents) */}
      <FieldGroup
        label="Team Members"
        helperText="Select agents that compose this team"
        error={membersError}
      >
        <div className="space-y-2">
          {agents.map((agent) => (
            <Controller
              key={agent.id}
              name="agents"
              control={control}
              render={({ field }) => {
                const isChecked = field.value.includes(agent.id);
                const agentPolicy = agentPoliciesByAgent[agent.id];
                const eligibilityReason =
                  agentPolicy?.team_eligibility_reason ??
                  (agentPolicy == null
                    ? AGENT_POLICY_UNAVAILABLE_REASON
                    : null);
                const isSelectable =
                  agentPolicy != null && eligibilityReason == null;
                return (
                  <div className="flex items-center space-x-3 sm:space-x-2 p-3 sm:p-2 rounded-lg hover:bg-gray-50 dark:hover:bg-white/5 transition-all duration-200">
                    <Checkbox
                      id={`agent-${agent.id}`}
                      checked={isChecked}
                      disabled={!isSelectable && !isChecked}
                      onCheckedChange={(checked) => {
                        if (!isSelectable && checked === true) {
                          return;
                        }
                        const newAgents = checked
                          ? [...field.value, agent.id]
                          : field.value.filter((a) => a !== agent.id);
                        field.onChange(newAgents);
                        handleFieldChange("agents", newAgents);
                      }}
                      className="h-5 w-5 sm:h-4 sm:w-4"
                    />
                    <label
                      htmlFor={`agent-${agent.id}`}
                      className="flex-1 cursor-pointer select-none"
                    >
                      <div className="font-medium">{agent.display_name}</div>
                      <div className="text-sm text-gray-500 dark:text-gray-400">
                        {agent.role}
                      </div>
                      {eligibilityReason != null && (
                        <div className="text-xs text-amber-600 dark:text-amber-400">
                          {eligibilityReason}
                        </div>
                      )}
                    </label>
                  </div>
                );
              }}
            />
          ))}
        </div>
      </FieldGroup>

      {/* Rooms */}
      <FieldGroup
        label="Team Rooms"
        helperText="Select rooms where this team can operate"
        error={roomsError}
      >
        <Controller
          name="rooms"
          control={control}
          render={({ field }) => (
            <div className="space-y-2 max-h-48 overflow-y-auto border rounded-lg p-2">
              {rooms.length === 0 ? (
                <p className="text-sm text-muted-foreground text-center py-2">
                  No rooms available. Create rooms in the Rooms tab.
                </p>
              ) : (
                rooms.map((room) => {
                  const isChecked = field.value.includes(room.id);
                  return (
                    <div
                      key={room.id}
                      className="flex items-center space-x-3 sm:space-x-2 p-3 sm:p-2 rounded-lg hover:bg-gray-50 dark:hover:bg-white/5 transition-all duration-200"
                    >
                      <Checkbox
                        id={`room-${room.id}`}
                        checked={isChecked}
                        onCheckedChange={(checked) => {
                          const newRooms = checked
                            ? [...field.value, room.id]
                            : field.value.filter((r) => r !== room.id);
                          field.onChange(newRooms);
                          handleFieldChange("rooms", newRooms);
                        }}
                        className="h-5 w-5 sm:h-4 sm:w-4"
                      />
                      <label
                        htmlFor={`room-${room.id}`}
                        className="flex-1 cursor-pointer select-none"
                      >
                        <div className="font-medium text-sm">
                          {room.display_name}
                        </div>
                        {room.description && (
                          <div className="text-xs text-gray-500 dark:text-gray-400">
                            {room.description}
                          </div>
                        )}
                      </label>
                    </div>
                  );
                })
              )}
            </div>
          )}
        />
      </FieldGroup>
    </EditorPanel>
  );
}
