import type {
  Spell,
  MagicItem,
  Weapon5e,
  Armor5e,
  Feat5e,
  Condition5e,
  CompendiumEntry,
} from '@/lib/compendium/types';
import type { RulesetClass } from '@/lib/ruleset/normalize';
import { Badge } from '@/components/ui/Codex';

const cap = (s: string): string => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s);

/** Editorial header shared by every detail renderer: Spectral title + italic sub + gilt rule. */
function Header({
  title,
  subtitle,
  tone = 'text-accent-deep',
}: {
  title: string;
  subtitle?: string | undefined;
  tone?: string;
}) {
  return (
    <header>
      <h2 className={`font-display text-3xl font-semibold tracking-tight ${tone}`}>{title}</h2>
      {subtitle && <p className="text-sm italic text-muted">{subtitle}</p>}
    </header>
  );
}

/** A sunken fact well: smallcaps label over a serif value. */
function FactWell({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div className="flex flex-col gap-0.5 rounded-xl border border-line bg-surface-2 px-3 py-2">
      <span className="smallcaps" style={{ fontSize: 9 }}>{label}</span>
      <span className="font-display text-sm font-semibold text-ink">{value}</span>
    </div>
  );
}

function ClassRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex gap-2">
      <span className="smallcaps w-28 shrink-0">{label}</span>
      <span className="text-ink-soft">{value}</span>
    </div>
  );
}

export function ClassDetail({ c }: { c: RulesetClass }) {
  return (
    <div className="space-y-3 text-sm">
      {c.description && <p className="font-display leading-relaxed text-ink-soft">{c.description}</p>}
      <hr className="gilt-rule my-1" />
      <div className="space-y-2">
        <ClassRow label={c.system === 'pf2e' ? 'HP / level' : 'Hit die'} value={c.system === 'pf2e' ? String(c.hitDie) : `d${c.hitDie}`} />
        {c.keyAbilities.length > 0 && <ClassRow label="Key ability" value={c.keyAbilities.map(cap).join(' or ')} />}
        {c.saves.length > 0 && <ClassRow label="Saves" value={c.saves.map((s) => (c.saveRanks?.[s] ? `${cap(s)} (${c.saveRanks[s]})` : cap(s))).join(', ')} />}
        {c.perception && <ClassRow label="Perception" value={c.perception} />}
        <ClassRow label="Skills" value={`${c.skillCount}${c.skillChoices.length ? ` — from ${c.skillChoices.join(', ')}` : ''}`} />
        {c.caster !== 'none' && <ClassRow label="Spellcasting" value={cap(c.caster)} />}
        {c.weapons.length > 0 && <ClassRow label="Weapons" value={c.weapons.map(cap).join(', ')} />}
        {c.armor.length > 0 && <ClassRow label="Armor" value={c.armor.map(cap).join(', ')} />}
      </div>
      {c.subclasses.length > 0 && (
        <div>
          <div className="smallcaps mb-2">{c.system === 'pf2e' ? 'Options' : 'Subclasses'}</div>
          <ul className="list-disc space-y-0.5 pl-5 text-ink-soft">{c.subclasses.slice(0, 16).map((s) => <li key={s.name}>{s.name}</li>)}</ul>
        </div>
      )}
      <p className="pt-1 text-xs text-faint">Source: {c.source}{c.license ? ` · ${c.license}` : ''}</p>
    </div>
  );
}

function Traits({ traits }: { traits?: string[] | undefined }) {
  if (!traits || traits.length === 0) return null;
  return (
    <div className="flex flex-wrap gap-1">
      {traits.map((t) => (
        <Badge key={t}>{t}</Badge>
      ))}
    </div>
  );
}

export function Spell5eDetail({ entry: s }: { entry: Spell }) {
  return (
    <div className="space-y-3">
      <Header
        title={s.name}
        subtitle={s.level_int === 0 ? `${s.school} cantrip` : `Level ${s.level_int} ${s.school ?? ''}`}
        tone="text-info"
      />
      <hr className="gilt-rule my-1" />
      <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
        <FactWell label="Casting Time" value={s.casting_time} />
        <FactWell label="Range" value={s.range} />
        <FactWell label="Duration" value={s.duration} />
        <FactWell label="Components" value={s.components} />
      </div>
      <p className="whitespace-pre-wrap font-display text-[15px] leading-relaxed text-ink-soft">{s.desc}</p>
      {s.higher_level && (
        <p className="whitespace-pre-wrap text-sm text-muted">
          <strong className="italic text-ink">At Higher Levels.</strong> {s.higher_level}
        </p>
      )}
    </div>
  );
}

export function Item5eDetail({ entry: item }: { entry: MagicItem }) {
  return (
    <div className="space-y-3">
      <Header
        title={item.name}
        subtitle={
          [item.type, item.rarity].filter(Boolean).join(', ') +
          (item.requires_attunement ? ` (requires attunement ${item.requires_attunement})` : '')
        }
      />
      <hr className="gilt-rule my-1" />
      <p className="whitespace-pre-wrap font-display text-[15px] leading-relaxed text-ink-soft">{item.desc}</p>
    </div>
  );
}

export function Weapon5eDetail({ entry: w }: { entry: Weapon5e }) {
  return (
    <div className="space-y-3">
      <Header title={w.name} subtitle={w.category} />
      <hr className="gilt-rule my-1" />
      <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
        <FactWell label="Damage" value={`${w.damage_dice} ${w.damage_type}`} />
        <FactWell label="Cost" value={w.cost ?? '—'} />
        <FactWell label="Weight" value={w.weight ?? '—'} />
      </div>
      {w.properties && w.properties.length > 0 && (
        <p className="text-sm text-muted"><strong className="text-ink">Properties</strong> {w.properties.join(', ')}</p>
      )}
    </div>
  );
}

export function Armor5eDetail({ entry: a }: { entry: Armor5e }) {
  return (
    <div className="space-y-3">
      <Header title={a.name} subtitle={`${a.type ?? ''} armor`} />
      <hr className="gilt-rule my-1" />
      <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
        <FactWell label="AC" value={a.ac} />
        <FactWell label="Cost" value={a.cost ?? '—'} />
        <FactWell label="Weight" value={`${a.weight ?? '—'} lb`} />
        <FactWell label="Stealth" value={a.stealthPenalty ? 'Disadvantage' : '—'} />
      </div>
    </div>
  );
}

export function Feat5eDetail({ entry: f }: { entry: Feat5e }) {
  return (
    <div className="space-y-3">
      <Header title={f.name} subtitle="Feat" />
      <hr className="gilt-rule my-1" />
      <p className="whitespace-pre-wrap font-display text-[15px] leading-relaxed text-ink-soft">{f.description}</p>
    </div>
  );
}

export function Condition5eDetail({ entry: c }: { entry: Condition5e }) {
  return (
    <div className="space-y-3">
      <Header title={c.name} subtitle="Condition" />
      <hr className="gilt-rule my-1" />
      {c.description && <p className="font-display text-[15px] leading-relaxed text-ink-soft">{c.description}</p>}
      {c.effects && c.effects.length > 0 && (
        <ul className="list-disc space-y-1 pl-5 text-sm text-muted">
          {c.effects.map((e, i) => <li key={i}>{e}</li>)}
        </ul>
      )}
    </div>
  );
}

/** Renderer for homebrew entries: header, field facts, description. */
export function HomebrewDetail({ entry }: { entry: CompendiumEntry }) {
  const skip = new Set(['name', 'slug', 'description', '__homebrew', '__kind']);
  const facts = Object.entries(entry).filter(([k, v]) => !skip.has(k) && v !== undefined && v !== '');
  const kind = typeof entry.__kind === 'string' ? entry.__kind : 'homebrew';
  return (
    <div className="space-y-3">
      <Header title={entry.name} subtitle={`Homebrew ${kind}`} />
      <hr className="gilt-rule my-1" />
      {facts.length > 0 && (
        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
          {facts.map(([k, v]) => (
            <FactWell key={k} label={k} value={String(v)} />
          ))}
        </div>
      )}
      {entry.description ? <p className="whitespace-pre-wrap font-display text-[15px] leading-relaxed text-ink-soft">{String(entry.description)}</p> : null}
    </div>
  );
}

/** Generic renderer for PF2e (AoN) entries: header, traits, key facts, text body. */
export function Pf2eDetail({ entry }: { entry: CompendiumEntry }) {
  const traits = (entry.trait as string[] | undefined) ?? undefined;
  const facts: [string, unknown][] = [
    ['Level', entry.level],
    ['Rarity', entry.rarity],
    ['Tradition', entry.tradition],
    ['Actions', entry.actions],
    ['Price', entry.price],
    ['AC', entry.ac],
    ['HP', entry.hp],
    ['Damage', entry.damage],
    ['Source', entry.source],
  ];
  const shown = facts.filter(
    ([k, v]) => v !== undefined && v !== null && v !== '' && !(k === 'Rarity' && v === 'common'),
  );
  const text = (entry.text as string | undefined) ?? (entry.summary as string | undefined) ?? '';

  return (
    <div className="space-y-3">
      <Header title={entry.name} subtitle={(entry.type as string | undefined) ?? undefined} />
      <Traits traits={traits} />
      <hr className="gilt-rule my-1" />
      {shown.length > 0 && (
        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
          {shown.map(([k, v]) => (
            <FactWell key={k} label={k} value={String(v)} />
          ))}
        </div>
      )}
      <p className="whitespace-pre-line font-display text-[15px] leading-relaxed text-ink-soft">{text}</p>
    </div>
  );
}
