import { useState } from 'react';
import { Link } from '@tanstack/react-router';
import { Heart, Shield } from 'lucide-react';
import { charactersRepo } from '@/lib/db/repositories';
import type { Campaign, Character } from '@/lib/schemas';
import { getSystem } from '@/lib/rules';
import { exportCharacter, parseCharacterImport, CharacterImportError } from '@/lib/io/character';
import { pickTextFile } from '@/lib/io/file';
import { useCharacters, useAllPcs } from './hooks';
import { Page, PageHeader, EmptyState, RequireCampaign } from '@/components/ui/Page';
import { Button } from '@/components/ui/Button';
import { Avatar, Badge } from '@/components/ui/Codex';
import { Modal } from '@/components/ui/Modal';
import { CreationWizard } from './builder/CreationWizard';

export function CharactersPage() {
  return <RequireCampaign>{(campaign) => <CharactersList campaign={campaign} />}</RequireCampaign>;
}

function CharactersList({ campaign }: { campaign: Campaign }) {
  // PCs are campaign-agnostic — show every player character; NPCs stay per-campaign.
  const pcs = useAllPcs();
  const npcs = useCharacters(campaign.id).filter((c) => c.kind === 'npc');
  const [creating, setCreating] = useState(false);
  const [importError, setImportError] = useState<string | null>(null);

  const importCharacter = async () => {
    setImportError(null);
    const text = await pickTextFile();
    if (text === null) return;
    try {
      const character = parseCharacterImport(text, campaign.id);
      await charactersRepo.insert(character);
    } catch (e) {
      setImportError(e instanceof CharacterImportError ? e.message : 'Import failed.');
    }
  };

  return (
    <Page>
      <PageHeader
        eyebrow="The Roster"
        title="Characters"
        subtitle={campaign.name}
        actions={
          <>
            <Button variant="secondary" onClick={importCharacter}>
              Import
            </Button>
            <Button variant="primary" onClick={() => setCreating(true)}>
              + New character
            </Button>
          </>
        }
      />

      {importError && (
        <p className="mb-4 rounded-md border border-danger/40 bg-danger/10 px-3 py-2 text-sm text-danger">
          {importError}
        </p>
      )}

      {pcs.length === 0 && npcs.length === 0 ? (
        <EmptyState
          title="No characters yet"
          hint="Add player characters and NPCs, or import a character file."
          action={
            <Button variant="primary" onClick={() => setCreating(true)}>
              + New character
            </Button>
          }
        />
      ) : (
        <div className="space-y-6">
          <CharacterGroup title="Player Characters" items={pcs} />
          <CharacterGroup title="NPCs" items={npcs} />
        </div>
      )}

      {creating && <CreationWizard campaign={campaign} onClose={() => setCreating(false)} />}
    </Page>
  );
}

function CharacterGroup({ title, items }: { title: string; items: Character[] }) {
  if (items.length === 0) return null;
  return (
    <section>
      <h2 className="smallcaps mb-3">{title}</h2>
      <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
        {items.map((c) => (
          <CharacterCard key={c.id} c={c} />
        ))}
      </div>
    </section>
  );
}

function CharacterCard({ c }: { c: Character }) {
  const [confirming, setConfirming] = useState(false);
  const ac = getSystem(c.system).baseArmorClass({ level: c.level, abilities: c.abilities, armorBonus: c.armorBonus, ...(c.equippedArmor ? { equippedArmor: c.equippedArmor } : {}) });

  return (
    <div className="paper-grain flex flex-col rounded-xl border border-line bg-panel transition-[border-color,box-shadow,transform] hover:-translate-y-0.5 hover:border-accent/50 hover:shadow-[0_8px_24px_-12px_var(--app-accent-glow)]">
      <Link
        to="/characters/$characterId"
        params={{ characterId: c.id }}
        className="block p-4"
      >
        <div className="flex items-start gap-3">
          {c.portrait ? (
            <img
              src={c.portrait}
              alt=""
              className="h-12 w-12 shrink-0 rounded-full border border-line object-cover"
            />
          ) : (
            <Avatar name={c.name} size={48} />
          )}
          <div className="min-w-0 flex-1">
            <div className="flex items-start justify-between gap-2">
              <h3 className="truncate font-display text-lg font-semibold text-ink">{c.name}</h3>
              <Badge tone="gold">Lv {c.level}</Badge>
            </div>
            <p className="mt-0.5 truncate text-sm text-muted">
              {[c.ancestry, c.className].filter(Boolean).join(' ') || '—'}
            </p>
          </div>
        </div>
        <div className="mt-3 grid grid-cols-2 gap-2">
          <span className="flex items-center justify-center gap-1.5 rounded-lg border border-line bg-surface-2 px-2 py-1.5 text-sm">
            <Heart className="h-3.5 w-3.5 text-danger" aria-hidden />
            <span className="smallcaps text-[10px]">HP</span>
            <span className="font-mono font-semibold text-ink">{c.hp.current}/{c.hp.max}</span>
          </span>
          <span className="flex items-center justify-center gap-1.5 rounded-lg border border-line bg-surface-2 px-2 py-1.5 text-sm">
            <Shield className="h-3.5 w-3.5 text-accent-deep" aria-hidden />
            <span className="smallcaps text-[10px]">AC</span>
            <span className="font-mono font-semibold text-ink">{ac}</span>
          </span>
        </div>
      </Link>
      <div className="flex items-center gap-1 border-t border-line px-2 py-1.5">
        <Button size="sm" variant="ghost" onClick={() => exportCharacter(c)} title="Export to JSON file">
          Export
        </Button>
        <Button
          size="sm"
          variant="ghost"
          className="ml-auto text-danger hover:bg-danger/10"
          onClick={() => setConfirming(true)}
        >
          Delete
        </Button>
      </div>

      <Modal
        open={confirming}
        onClose={() => setConfirming(false)}
        title="Delete character?"
        footer={
          <>
            <Button variant="ghost" onClick={() => setConfirming(false)}>
              Cancel
            </Button>
            <Button
              variant="danger"
              onClick={async () => {
                await charactersRepo.remove(c.id);
                setConfirming(false);
              }}
            >
              Delete
            </Button>
          </>
        }
      >
        <p className="text-sm text-muted">
          Permanently delete <strong className="text-ink">{c.name}</strong>? This cannot be undone.
          {' '}Consider exporting first.
        </p>
      </Modal>
    </div>
  );
}

