import { useState } from 'react';
import { useNavigate } from '@tanstack/react-router';
import type { Campaign } from '@/lib/schemas';
import { npcsRepo } from '@/lib/db/repositories';
import { complete } from '@/lib/llm/client';
import { getLlmConfig, useAssistantStore } from '@/stores/assistantStore';
import { buildNpcPrompt, npcQuickSchema, fallbackNpc, type NpcQuick } from '@/lib/assistant/session';
import { getSystem } from '@/lib/rules';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';

interface Props {
  campaign: Campaign;
}

export function NpcGenCard({ campaign }: Props) {
  const navigate = useNavigate();
  const llmEnabled = useAssistantStore((s) => s.enabled);
  const hasKey = useAssistantStore((s) => !!s.apiKey);
  const canUseLlm = llmEnabled && hasKey;

  const [hint, setHint] = useState('');
  const [state, setState] = useState<'idle' | 'loading' | 'ready' | 'error'>('idle');
  const [npc, setNpc] = useState<NpcQuick | null>(null);
  const [message, setMessage] = useState<string | null>(null);

  const ctx = {
    systemConstraint: `Only use ${getSystem(campaign.system).label} setting, names, and context.`,
    systemLabel: getSystem(campaign.system).label,
    questsSummary: 'No active quests.',
    notesSummary: 'No notes yet.',
  };

  const generate = async () => {
    setState('loading');
    setMessage(null);

    if (canUseLlm) {
      const { system, user } = buildNpcPrompt(ctx, hint || undefined);
      const result = await complete<NpcQuick>(getLlmConfig(), { system, user, schema: npcQuickSchema });
      if (result.ok && 'data' in result) {
        setNpc(result.data);
        setState('ready');
        return;
      }
      setMessage(`AI unavailable${!result.ok ? ` (${result.error})` : ''}. Showing template NPC instead.`);
    }

    setNpc(fallbackNpc());
    setState('ready');
  };

  const addToCampaign = async () => {
    if (!npc) return;
    const created = await npcsRepo.create(campaign.id, npc.name);
    await npcsRepo.update(created.id, {
      role: npc.role,
      description: `Motivation: ${npc.motivation}\n\nSecret: ${npc.secret}\n\nIntro hook: ${npc.hook}`,
    });
    void navigate({ to: '/npcs' });
  };

  return (
    <div className="rounded-lg border border-line bg-panel p-4">
      <p className="mb-3 text-sm text-muted">
        Generate a ready-to-use NPC with motivation, secret, and an intro hook for the table.
      </p>
      <div className="flex gap-2">
        <Input
          value={hint}
          onChange={(e) => setHint(e.target.value)}
          placeholder={`Optional: "a nervous blacksmith" or "a corrupt city guard"`}
          className="flex-1 text-sm"
          aria-label="NPC hint"
        />
        <Button variant="secondary" disabled={state === 'loading'} onClick={() => void generate()}>
          {state === 'loading' ? 'Thinking…' : canUseLlm ? 'Generate (AI)' : 'Generate'}
        </Button>
      </div>

      {message && <p className="mt-2 text-xs text-muted">{message}</p>}

      {state === 'ready' && npc && (
        <div className="mt-4 rounded-md border border-line bg-surface-2 p-3 text-sm">
          <div className="mb-2 flex items-start justify-between gap-2">
            <div>
              <span className="font-display text-lg font-semibold text-ink">{npc.name}</span>
              <span className="ml-2 text-xs text-muted">{npc.role}</span>
            </div>
            <Button size="sm" variant="primary" onClick={() => void addToCampaign()}>
              Add to campaign
            </Button>
          </div>
          <dl className="space-y-1.5 text-xs">
            <NpcField label="Motivation" value={npc.motivation} />
            <NpcField label="Secret" value={npc.secret} />
            <NpcField label="Intro hook" value={npc.hook} />
          </dl>
        </div>
      )}
    </div>
  );
}

function NpcField({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <dt className="inline font-semibold text-ink">{label}: </dt>
      <dd className="inline text-muted">{value}</dd>
    </div>
  );
}
