'use client';

/**
 * AgentDefinitionEditor — edit a single CS agent definition.
 */

import { useMemo, useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { NumberInput } from '@/components/ui/primitives/NumberInput';
import { Textarea } from '@/components/ui/primitives/Textarea';
import { FormField } from '@/components/ui/primitives/FormField';
import { Checkbox } from '@/components/ui/primitives/Checkbox';
import { PageShellSkeleton } from '@/components/ui/feedback/Skeleton';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Row } from '@/components/ui/layout/Row';
import { Stack } from '@/components/ui/layout/Stack';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { Combobox } from '@/components/ui/inputs/Combobox';
import {
  useDefinition,
  useUpdateDefinition,
  useProviders,
  useProviderModels,
} from './internals/useAdminSupport';
import { QueryBoundary } from '@platform-modules/ui-primitives';

interface ChainEntry {
  id: string;
  llmProviderId: string;
  model: string;
}

interface AgentDefinitionDetail {
  slug: string;
  name: string;
  isActive: boolean;
  systemPromptTemplate: string;
  llmChain: { chain: ChainEntry[] };
  slaAiHours: number;
  slaHumanHours: number;
  aiConfidenceThreshold: string | number;
  maxToolCalls: number;
  maxCostCents: number;
}

interface LlmProviderOption {
  id: string;
  name: string;
}

interface EditorDraft {
  name: string;
  isActive: boolean;
  systemPromptTemplate: string;
  chain: ChainEntry[];
  slaAiHours: number;
  slaHumanHours: number;
  aiConfidenceThreshold: number;
  maxToolCalls: number;
  maxCostCents: number;
}

type AdminSupportT = ReturnType<typeof useT<'admin_support'>>;

interface ChainRowProps {
  entry: ChainEntry;
  index: number;
  chain: ChainEntry[];
  setChain: (next: ChainEntry[]) => void;
  providers: LlmProviderOption[];
  t: AdminSupportT;
  moveChain: (index: number, direction: -1 | 1) => void;
}

function ChainRow({ entry, index, chain, setChain, providers, t, moveChain }: ChainRowProps) {
  const modelsQuery = useProviderModels(entry.llmProviderId || undefined);
  const modelOptionsLoading = !!entry.llmProviderId && modelsQuery.isLoading;

  return (
    <Row gap="2" align="end" className="flex-wrap">
      <FormField label={t('definitions_chain_provider')} className="min-w-40 flex-1">
        <Select
          value={entry.llmProviderId || undefined}
          onValueChange={(v) => {
            const next = [...chain];
            const row = next[index];
            if (!row) return;
            next[index] = { ...row, llmProviderId: v };
            setChain(next);
          }}
        >
          <SelectTrigger className="w-full">
            <SelectValue placeholder={t('definitions_chain_provider')} />
          </SelectTrigger>
          <SelectContent>
            {providers.map((p) => (
              <SelectItem key={p.id} value={p.id}>
                {p.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </FormField>
      <FormField label={t('definitions_chain_model')} className="min-w-40 flex-1">
        <Combobox
          id={`agentdef-model-${index}`}
          dir="ltr"
          value={entry.model || undefined}
          onValueChange={(model) => {
            const next = [...chain];
            const row = next[index];
            if (!row) return;
            next[index] = { ...row, model };
            setChain(next);
          }}
          options={(modelsQuery.data?.models ?? []).map((m) => ({ value: m.id, label: m.label }))}
          loading={modelOptionsLoading}
          disabled={!entry.llmProviderId}
          placeholder={t('model_select_placeholder')}
          searchPlaceholder={t('model_search_placeholder')}
          emptyText={modelsQuery.data?.error ?? t('model_empty_hint')}
          pinnedValueHint={t('model_not_in_list')}
        />
      </FormField>
      <Row gap="1">
        <Button
          type="button"
          variant="ghost"
          size="sm"
          disabled={index === 0}
          onClick={() => moveChain(index, -1)}
          aria-label={t('definitions_chain_up')}
        >
          ↑
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          disabled={index === chain.length - 1}
          onClick={() => moveChain(index, 1)}
          aria-label={t('definitions_chain_down')}
        >
          ↓
        </Button>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          disabled={chain.length <= 1}
          onClick={() => setChain(chain.filter((_, i) => i !== index))}
          aria-label={t('definitions_chain_remove')}
        >
          ×
        </Button>
      </Row>
    </Row>
  );
}

function AgentDefinitionEditorInner({ slug }: { slug: string }) {
  const t = useT('admin_support');

  const definitionQuery = useDefinition(slug);
  const providersQuery = useProviders();
  const update = useUpdateDefinition(slug);

  const [overrides, setOverrides] = useState<Partial<EditorDraft>>({});
  const [saveError, setSaveError] = useState<string | null>(null);
  const [saved, setSaved] = useState(false);

  const definition = definitionQuery.data?.definition as AgentDefinitionDetail | undefined;
  const providers = (providersQuery.data?.providers as LlmProviderOption[] | undefined) ?? [];

  const loadedDraft = useMemo<EditorDraft | null>(() => {
    if (!definition) return null;
    const chain = definition.llmChain?.chain?.length
      ? definition.llmChain.chain.map((e) => ({
          id: crypto.randomUUID(),
          llmProviderId: e.llmProviderId,
          model: e.model,
        }))
      : [{ id: crypto.randomUUID(), llmProviderId: '', model: '' }];
    return {
      name: definition.name,
      isActive: definition.isActive,
      systemPromptTemplate: definition.systemPromptTemplate,
      chain,
      slaAiHours: definition.slaAiHours,
      slaHumanHours: definition.slaHumanHours,
      aiConfidenceThreshold: Number(definition.aiConfidenceThreshold),
      maxToolCalls: definition.maxToolCalls,
      maxCostCents: definition.maxCostCents,
    };
  }, [definition]);

  const draft = loadedDraft ? { ...loadedDraft, ...overrides } : null;

  function patchDraft(patch: Partial<EditorDraft>) {
    setOverrides((o) => ({ ...o, ...patch }));
    setSaved(false);
  }

  function setChain(next: ChainEntry[]) {
    patchDraft({ chain: next });
  }

  function moveChain(index: number, direction: -1 | 1) {
    if (!draft) return;
    const next = [...draft.chain];
    const target = index + direction;
    if (target < 0 || target >= next.length) return;
    const tmp = next[index];
    const swap = next[target];
    if (!tmp || !swap) return;
    next[index] = swap;
    next[target] = tmp;
    setChain(next);
  }

  async function handleSave(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!draft) return;
    setSaveError(null);
    try {
      await update.mutateAsync({
        name: draft.name.trim(),
        is_active: draft.isActive,
        system_prompt_template: draft.systemPromptTemplate,
        llm_chain: {
          chain: draft.chain.filter((e) => e.llmProviderId && e.model.trim()),
        },
        sla_ai_hours: draft.slaAiHours,
        sla_human_hours: draft.slaHumanHours,
        ai_confidence_threshold: draft.aiConfidenceThreshold,
        max_tool_calls: draft.maxToolCalls,
        max_cost_cents: draft.maxCostCents,
      });
      setSaved(true);
    } catch (err) {
      setSaveError(err instanceof Error ? err.message : String(err));
    }
  }

  const editorTitle = t('definitions_editor_title').replace('{name}', draft?.name || slug);

  return (
    <QueryBoundary
      query={definitionQuery}
      skeleton={<PageShellSkeleton />}
      errorFallback={() => (
        <InlineNotice tone="danger" title={t('definitions_editor_load_error')} />
      )}
    >
      {() => (
        <QueryBoundary
          query={providersQuery}
          skeleton={<PageShellSkeleton />}
          errorFallback={() => (
            <InlineNotice tone="danger" title={String(providersQuery.error ?? '')} />
          )}
        >
          {() =>
            !draft ? null : (
              <form onSubmit={handleSave} noValidate>
                <Stack gap="6">
                  <Row gap="3" align="center">
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        window.location.href = '/admin/support/definitions';
                      }}
                    >
                      {t('definitions_back')}
                    </Button>
                    <PageHeader title={editorTitle} />
                  </Row>

                  {saved && <InlineNotice tone="success" title={t('definitions_saved')} />}
                  {saveError && <InlineNotice tone="danger" title={t('definitions_save_error')} />}

                  <section className="bg-surface-default rounded-2xl p-4 shadow-md">
                    <Stack gap="3">
                      <FormField label={t('definitions_name')} htmlFor="ade-name">
                        <Input
                          id="ade-name"
                          value={draft.name}
                          onChange={(e) => patchDraft({ name: e.target.value })}
                          required
                        />
                      </FormField>
                      <div className="flex items-center gap-2">
                        <Checkbox
                          id="ade-active"
                          checked={draft.isActive}
                          onCheckedChange={(checked) => patchDraft({ isActive: checked === true })}
                        />
                        <label htmlFor="ade-active" className="text-sm">
                          {t('definitions_active_agent')}
                        </label>
                      </div>
                    </Stack>
                  </section>

                  <section className="bg-surface-default rounded-2xl p-4 shadow-md">
                    <h3 className="text-text-primary mb-3 text-sm font-semibold">
                      {t('definitions_system_prompt')}
                    </h3>
                    <Textarea
                      rows={10}
                      dir="ltr"
                      className="font-mono text-sm"
                      value={draft.systemPromptTemplate}
                      onChange={(e) => patchDraft({ systemPromptTemplate: e.target.value })}
                    />
                    <p className="text-text-muted mt-1 text-xs">
                      {t('definitions_system_prompt_help')}
                    </p>
                  </section>

                  <section className="bg-surface-default rounded-2xl p-4 shadow-md">
                    <h3 className="text-text-primary text-sm font-semibold">
                      {t('definitions_chain_title')}
                    </h3>
                    <p className="text-text-muted mb-3 text-xs">
                      {t('definitions_chain_subtitle')}
                    </p>
                    <Stack gap="3">
                      {draft.chain.map((entry, index) => (
                        <ChainRow
                          key={entry.id}
                          entry={entry}
                          index={index}
                          chain={draft.chain}
                          setChain={setChain}
                          providers={providers}
                          t={t}
                          moveChain={moveChain}
                        />
                      ))}
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        onClick={() =>
                          setChain([
                            ...draft.chain,
                            { id: crypto.randomUUID(), llmProviderId: '', model: '' },
                          ])
                        }
                      >
                        {t('definitions_chain_add')}
                      </Button>
                    </Stack>
                  </section>

                  <section className="bg-surface-default rounded-2xl p-4 shadow-md">
                    <Stack gap="3">
                      <FormField label={t('definitions_sla_ai')} htmlFor="ade-sla-ai">
                        <NumberInput
                          id="ade-sla-ai"
                          value={draft.slaAiHours}
                          onChange={(n) => patchDraft({ slaAiHours: n })}
                          min={1}
                        />
                      </FormField>
                      <FormField label={t('definitions_sla_human')} htmlFor="ade-sla-human">
                        <NumberInput
                          id="ade-sla-human"
                          value={draft.slaHumanHours}
                          onChange={(n) => patchDraft({ slaHumanHours: n })}
                          min={1}
                        />
                      </FormField>
                      <FormField label={t('definitions_confidence')} htmlFor="ade-confidence">
                        <NumberInput
                          id="ade-confidence"
                          value={draft.aiConfidenceThreshold}
                          onChange={(n) => patchDraft({ aiConfidenceThreshold: n })}
                          min={0.1}
                          max={1}
                          step={0.01}
                        />
                      </FormField>
                      <FormField label={t('definitions_max_tools')} htmlFor="ade-max-tools">
                        <NumberInput
                          id="ade-max-tools"
                          value={draft.maxToolCalls}
                          onChange={(n) => patchDraft({ maxToolCalls: n })}
                          min={1}
                        />
                      </FormField>
                      <FormField label={t('definitions_max_cost')} htmlFor="ade-max-cost">
                        <NumberInput
                          id="ade-max-cost"
                          value={draft.maxCostCents}
                          onChange={(n) => patchDraft({ maxCostCents: n })}
                          min={1}
                        />
                        <p className="text-text-muted mt-1 text-xs">
                          {t('definitions_max_cost_help')}
                        </p>
                      </FormField>
                    </Stack>
                  </section>

                  <Row justify="end" gap="2">
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        window.location.href = '/admin/support/definitions';
                      }}
                    >
                      {t('definitions_cancel')}
                    </Button>
                    <Button type="submit" variant="primary" size="sm" disabled={update.isPending}>
                      {update.isPending ? `${t('definitions_save')}…` : t('definitions_save')}
                    </Button>
                  </Row>
                </Stack>
              </form>
            )
          }
        </QueryBoundary>
      )}
    </QueryBoundary>
  );
}

export function AgentDefinitionEditor({ slug }: { slug: string }) {
  return (
    <HydratedIsland>
      <AgentDefinitionEditorInner slug={slug} />
    </HydratedIsland>
  );
}
