import { useState } from 'react';
import { Wand2 } from 'lucide-react';
import type { Campaign, Npc } from '@/lib/schemas';
import { npcsRepo } from '@/lib/db/repositories';
import { getSystem } from '@/lib/rules';
import { complete } from '@/lib/llm/client';
import { getLlmConfig, useAssistantStore } from '@/stores/assistantStore';
import { buildNpcPrompt, npcQuickSchema, fallbackNpc, type NpcQuick } from '@/lib/assistant/session';
import { useDebouncedCallback } from '@/lib/useDebouncedCallback';
import { useNpcs } from './hooks';
import { Page, PageHeader, EmptyState, RequireCampaign } from '@/components/ui/Page';
import { Button } from '@/components/ui/Button';
import { Input, Select } from '@/components/ui/Input';

const STATUS: Npc['status'][] = ['alive', 'dead', 'unknown'];

export function NpcsPage() {
  return <RequireCampaign>{(c) => <Npcs campaign={c} />}</RequireCampaign>;
}

function Npcs({ campaign }: { campaign: Campaign }) {
  const npcs = useNpcs(campaign.id);
  const [query, setQuery] = useState('');
  const filtered = npcs
    .filter((n) => n.name.toLowerCase().includes(query.toLowerCase()) || n.faction.toLowerCase().includes(query.toLowerCase()))
    .sort((a, b) => a.name.localeCompare(b.name));

  return (
    <Page>
      <PageHeader
        title="NPCs"
        subtitle={campaign.name}
        actions={<Button variant="primary" onClick={() => npcsRepo.create(campaign.id, 'New NPC')}>+ New NPC</Button>}
      />
      {npcs.length === 0 ? (
        <EmptyState title="No NPCs yet" hint="Track the people your party meets — allies, villains, shopkeepers." action={<Button variant="primary" onClick={() => npcsRepo.create(campaign.id, 'New NPC')}>+ New NPC</Button>} />
      ) : (
        <>
          <Input className="mb-3 max-w-sm" value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search NPCs…" aria-label="Search NPCs" />
          <div className="grid gap-3 md:grid-cols-2">
            {filtered.map((n) => <NpcCard key={n.id} npc={n} campaign={campaign} />)}
          </div>
        </>
      )}
    </Page>
  );
}

function NpcCard({ npc, campaign }: { npc: Npc; campaign: Campaign }) {
  const [n, setN] = useState(npc);
  const [genState, setGenState] = useState<'idle' | 'loading'>('idle');
  const llmEnabled = useAssistantStore((s) => s.enabled);
  const hasKey = useAssistantStore((s) => !!s.apiKey);
  const canUseLlm = llmEnabled && hasKey;

  const save = useDebouncedCallback((next: Npc) => void npcsRepo.update(next.id, {
    name: next.name, role: next.role, location: next.location, faction: next.faction, status: next.status, description: next.description,
  }), 350);
  const update = (patch: Partial<Npc>) => setN((p) => { const next = { ...p, ...patch }; save(next); return next; });

  const generateDetails = async () => {
    setGenState('loading');
    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 hint = [n.name, n.role].filter(Boolean).join(', ');
    let result: NpcQuick | null = null;
    if (canUseLlm) {
      const { system, user } = buildNpcPrompt(ctx, hint || undefined);
      const res = await complete<NpcQuick>(getLlmConfig(), { system, user, schema: npcQuickSchema });
      if (res.ok && 'data' in res) result = res.data;
    }
    if (!result) result = fallbackNpc();
    const desc = `Motivation: ${result.motivation}\n\nSecret: ${result.secret}\n\nIntro hook: ${result.hook}`;
    update({ description: desc, role: result.role || n.role });
    setGenState('idle');
  };

  return (
    <div className="rounded-lg border border-line bg-panel p-4">
      <div className="flex items-center gap-2">
        <Input className="font-display font-semibold" value={n.name} onChange={(e) => update({ name: e.target.value })} aria-label="NPC name" />
        <Select className="w-auto py-1 text-xs" value={n.status} onChange={(e) => update({ status: e.target.value as Npc['status'] })} aria-label="Status">
          {STATUS.map((s) => <option key={s} value={s}>{s}</option>)}
        </Select>
        <Button size="sm" variant="ghost" disabled={genState === 'loading'} onClick={() => void generateDetails()} title="Fill description with generated details" aria-label="Generate NPC details">
          <Wand2 size={13} aria-hidden />
        </Button>
        <Button size="icon" variant="ghost" className="text-danger" onClick={() => npcsRepo.remove(npc.id)} aria-label={`Delete ${n.name}`}>✕</Button>
      </div>
      <div className="mt-2 grid grid-cols-3 gap-2">
        <Input className="text-xs" value={n.role} onChange={(e) => update({ role: e.target.value })} placeholder="Role" aria-label="Role" />
        <Input className="text-xs" value={n.location} onChange={(e) => update({ location: e.target.value })} placeholder="Location" aria-label="Location" />
        <Input className="text-xs" value={n.faction} onChange={(e) => update({ faction: e.target.value })} placeholder="Faction" aria-label="Faction" />
      </div>
      <textarea
        value={n.description}
        onChange={(e) => update({ description: e.target.value })}
        placeholder="Appearance, motives, voice, secrets…"
        className="mt-2 min-h-20 w-full resize-y rounded-md border border-line bg-surface px-3 py-2 text-sm text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/60"
      />
    </div>
  );
}
