"use client";

import { useCallback, useState } from "react";
import IconButton from "@/components/ui/IconButton";
import { FieldLabel, Input, Select, TextArea } from "@/components/ui/Field";
import { IconChevronDown, IconChevronRight } from "@/components/ui/icons";
import type { AgentProfileSummary, ModelConfig } from "@/lib/types";

export interface StepData {
  assignment: string;
  role: string;
  prompt: string;
  capacity?: number;
  timeout?: number | null;
}

export interface StepEditorProps {
  steps: Record<string, StepData>;
  roles: string[];
  agentProfiles?: AgentProfileSummary[];
  modelOverrides?: Record<string, ModelConfig>;
  onChange: (steps: Record<string, StepData>) => void;
}

function generateStepName(existing: Record<string, StepData>): string {
  let n = 1;
  while (Object.prototype.hasOwnProperty.call(existing, `step_${n}`)) {
    n += 1;
  }
  return `step_${n}`;
}

interface StepCardProps {
  stepKey: string;
  data: StepData;
  roles: string[];
  agentProfiles?: AgentProfileSummary[];
  modelOverrides?: Record<string, ModelConfig>;
  onChangeName: (oldKey: string, newKey: string) => void;
  onChangeField: (key: string, field: keyof StepData, value: StepData[keyof StepData]) => void;
  onDelete: (key: string) => void;
}

function StepCard({
  stepKey,
  data,
  roles,
  agentProfiles = [],
  modelOverrides = {},
  onChangeName,
  onChangeField,
  onDelete,
}: StepCardProps) {
  const [expanded, setExpanded] = useState(true);
  const [localName, setLocalName] = useState(stepKey);
  const [nameError, setNameError] = useState<string | null>(null);

  const handleNameBlur = useCallback(() => {
    const trimmed = localName.trim();
    if (!trimmed) {
      setLocalName(stepKey);
      setNameError(null);
      return;
    }
    if (trimmed === stepKey) {
      setNameError(null);
      return;
    }
    setNameError(null);
    onChangeName(stepKey, trimmed);
  }, [localName, stepKey, onChangeName]);

  const handleNameKeyDown = useCallback(
    (e: React.KeyboardEvent<HTMLInputElement>) => {
      if (e.key === "Enter") {
        e.currentTarget.blur();
      } else if (e.key === "Escape") {
        setLocalName(stepKey);
        setNameError(null);
        e.currentTarget.blur();
      }
    },
    [stepKey],
  );

  return (
    <div className="rounded border border-edge bg-surface-raised p-4">
      {/* Card header */}
      <div className="flex items-center justify-between gap-3">
        <IconButton
          aria-label={expanded ? "Collapse step" : "Expand step"}
          aria-expanded={expanded}
          onClick={() => setExpanded((v) => !v)}
        >
          <span aria-hidden="true" className="flex items-center">
            {expanded ? (
              <IconChevronDown size={10} strokeWidth={2.25} />
            ) : (
              <IconChevronRight size={10} strokeWidth={2.25} />
            )}
          </span>
        </IconButton>

        <input
          type="text"
          value={localName}
          onChange={(e) => setLocalName(e.target.value)}
          onBlur={handleNameBlur}
          onKeyDown={handleNameKeyDown}
          aria-label="Step name"
          className="min-w-0 flex-1 rounded border border-transparent bg-transparent px-1 py-0.5 font-data text-body font-semibold text-content-primary hover:border-edge focus:border-edge-strong focus:outline-none"
        />

        {nameError ? (
          <span className="shrink-0 text-meta text-status-error">{nameError}</span>
        ) : null}

        <button
          type="button"
          onClick={() => onDelete(stepKey)}
          aria-label={`Delete step ${stepKey}`}
          className="shrink-0 rounded px-2 py-0.5 text-meta text-content-muted hover:bg-surface-overlay hover:text-status-error focus:outline-none"
        >
          delete
        </button>
      </div>

      {/* Collapsible body */}
      {expanded ? (
        <div className="mt-4 flex flex-col gap-3">
          {/* Role */}
          <FieldLabel label="Role">
            {roles.length > 0 ? (
              <Select
                id={`${stepKey}-role`}
                value={data.role}
                onChange={(e) => onChangeField(stepKey, "role", e.target.value)}
              >
                <option value="">— select role —</option>
                {roles.map((r) => {
                  const isProfile = agentProfiles.some((p) => p.name === r);
                  const isOverride = r in modelOverrides;
                  const suffix =
                    isProfile && isOverride
                      ? " (profile + override)"
                      : isProfile
                        ? " (profile)"
                        : isOverride
                          ? " (override)"
                          : "";
                  return (
                    <option key={r} value={r}>
                      {r}
                      {suffix}
                    </option>
                  );
                })}
              </Select>
            ) : (
              <Input
                id={`${stepKey}-role`}
                type="text"
                value={data.role}
                onChange={(e) => onChangeField(stepKey, "role", e.target.value)}
                placeholder="e.g. implementer"
              />
            )}

            {/* Resolved config badge */}
            {data.role &&
              (() => {
                const profile = agentProfiles.find((p) => p.name === data.role);
                const override = modelOverrides[data.role];
                if (!profile && !override) return null;

                const provider = override?.provider ?? profile?.provider ?? "—";
                const model = override?.model ?? profile?.model ?? "—";
                const source = override ? (profile ? "override" : "worker") : "profile";

                return (
                  <div className="flex items-center gap-2 rounded border border-edge bg-surface-overlay px-2 py-1 text-meta text-content-muted">
                    <span>via {source}:</span>
                    <span className="font-data text-content-secondary">
                      {provider}/{model}
                    </span>
                  </div>
                );
              })()}
          </FieldLabel>

          {/* Assignment */}
          <FieldLabel label="Assignment">
            <Input
              id={`${stepKey}-assignment`}
              type="text"
              value={data.assignment}
              onChange={(e) => onChangeField(stepKey, "assignment", e.target.value)}
              placeholder="inputs -> outputs"
            />
          </FieldLabel>

          {/* Prompt template */}
          <FieldLabel label="Prompt Template">
            <TextArea
              id={`${stepKey}-prompt`}
              value={data.prompt}
              onChange={(e) => onChangeField(stepKey, "prompt", e.target.value)}
              placeholder={
                "Use {field} syntax to reference inputs.\nExample: Analyze {task} and produce a {plan}."
              }
              rows={3}
              mono
            />
          </FieldLabel>

          {/* Capacity + Timeout row */}
          <div className="flex gap-3">
            <FieldLabel label="Capacity" className="flex-1">
              <Input
                id={`${stepKey}-capacity`}
                type="number"
                min={1}
                value={data.capacity ?? 1}
                onChange={(e) => {
                  const v = e.target.value === "" ? 1 : Number(e.target.value);
                  onChangeField(stepKey, "capacity", v);
                }}
              />
            </FieldLabel>

            <FieldLabel label="Timeout (s)" className="flex-1">
              <Input
                id={`${stepKey}-timeout`}
                type="number"
                min={0}
                value={data.timeout ?? ""}
                placeholder="none"
                onChange={(e) => {
                  const v = e.target.value === "" ? null : Number(e.target.value);
                  onChangeField(stepKey, "timeout", v);
                }}
              />
            </FieldLabel>
          </div>
        </div>
      ) : null}
    </div>
  );
}

export default function StepEditor({
  steps,
  roles,
  agentProfiles,
  modelOverrides,
  onChange,
}: StepEditorProps) {
  const handleChangeName = useCallback(
    (oldKey: string, newKey: string) => {
      if (newKey === oldKey) return;
      if (Object.prototype.hasOwnProperty.call(steps, newKey)) {
        // Silently ignore — duplicate name; StepCard resets to oldKey via blur logic
        return;
      }

      // Preserve insertion order: rebuild object replacing oldKey with newKey at same position
      const next: Record<string, StepData> = {};
      for (const [k, v] of Object.entries(steps)) {
        if (k === oldKey) {
          next[newKey] = v;
        } else {
          next[k] = v;
        }
      }
      onChange(next);
    },
    [steps, onChange],
  );

  const handleChangeField = useCallback(
    (key: string, field: keyof StepData, value: StepData[keyof StepData]) => {
      onChange({ ...steps, [key]: { ...steps[key], [field]: value } });
    },
    [steps, onChange],
  );

  const handleDelete = useCallback(
    (key: string) => {
      const next = { ...steps };
      delete next[key];
      onChange(next);
    },
    [steps, onChange],
  );

  const handleAddStep = useCallback(() => {
    const name = generateStepName(steps);
    onChange({
      ...steps,
      [name]: {
        assignment: "",
        role: roles.length > 0 ? roles[0] : "",
        prompt: "",
        capacity: 1,
        timeout: null,
      },
    });
  }, [steps, roles, onChange]);

  const stepEntries = Object.entries(steps);

  return (
    <div className="flex flex-col gap-3">
      {stepEntries.length === 0 ? (
        <p className="rounded border border-dashed border-edge px-4 py-6 text-center text-body text-content-muted">
          No steps defined. Add one below.
        </p>
      ) : (
        stepEntries.map(([key, data]) => (
          <StepCard
            key={key}
            stepKey={key}
            data={data}
            roles={roles}
            agentProfiles={agentProfiles}
            modelOverrides={modelOverrides}
            onChangeName={handleChangeName}
            onChangeField={handleChangeField}
            onDelete={handleDelete}
          />
        ))
      )}

      <button
        type="button"
        onClick={handleAddStep}
        className="self-start rounded border border-edge bg-surface-base px-4 py-1.5 text-body text-content-secondary hover:border-edge-strong hover:text-content-primary focus:outline-none"
      >
        + Add Step
      </button>
    </div>
  );
}
