
import { useState } from 'react';
import { Minus, Plus, Skull, Star } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { NumberField } from '@/components/ui/NumberField';
import { maxDying, isDead, recoveryDc, knockOut, applyRecovery, heroPointRescue } from '@/lib/mechanics';
import type { Degree } from '@/lib/dice/check';
import type { Condition } from '@/lib/schemas/common';
import { SheetSection, type SectionProps } from './common';

function Pips({ count, filled, onToggle, label }: { count: number; filled: number; onToggle: (n: number) => void; label: string }) {
  return (
    <div className="flex items-center gap-1" role="group" aria-label={label}>
      {Array.from({ length: count }, (_, i) => (
        <button
          key={i}
          onClick={() => onToggle(i + 1 === filled ? i : i + 1)}
          aria-label={`${label} ${i + 1}`}
          aria-pressed={i < filled}
          className={
            'h-5 w-5 rounded-full border ' +
            (i < filled ? 'border-accent bg-accent' : 'border-line bg-surface')
          }
        />
      ))}
    </div>
  );
}

/** PF2e dying/wounded/doomed with knock-out + human-rolled recovery checks. */
function Pf2eDefenses({ c, update }: SectionProps) {
  const d = c.defenses;
  const [fromCrit, setFromCrit] = useState(false);
  const dead = isDead(d.dying, d.doomed);

  const withUnconscious = (conds: Condition[]): Condition[] =>
    conds.some((x) => x.name.trim().toLowerCase() === 'unconscious') ? conds : [...conds, { name: 'Unconscious' }];
  const withoutUnconscious = (conds: Condition[]): Condition[] =>
    conds.filter((x) => x.name.trim().toLowerCase() !== 'unconscious');

  const setDefenses = (p: Partial<typeof d>) => update({ defenses: { ...d, ...p } });
  // You stay Unconscious at 0 HP even after recovering out of dying — only healing
  // above 0 HP (or the GM) wakes you. So the sync is: dying>0 OR hp<=0 ⇒ unconscious.
  const syncUnconscious = (dying: number, hpCurrent: number) =>
    dying > 0 || hpCurrent <= 0 ? withUnconscious(c.conditions) : withoutUnconscious(c.conditions);
  /** Set dying and keep the Unconscious condition in sync. */
  const setDying = (dying: number) =>
    update({ defenses: { ...d, dying }, conditions: syncUnconscious(dying, c.hp.current) });

  const doKnockOut = () => {
    const { dying } = knockOut(d, fromCrit);
    // Knocked out = at 0 HP and dying; drop HP to 0 so the sheet state is coherent.
    update({ defenses: { ...d, dying }, conditions: withUnconscious(c.conditions), hp: { ...c.hp, current: Math.min(0, c.hp.current) } });
  };
  const doRecover = (degree: Degree) => {
    const res = applyRecovery(d, degree);
    update({ defenses: { ...d, ...res }, conditions: syncUnconscious(res.dying, c.hp.current) });
  };
  const doHeroRescue = () => {
    const res = heroPointRescue(d);
    if (!res) return;
    update({ defenses: { ...d, ...res }, conditions: syncUnconscious(0, c.hp.current) });
  };

  return (
    <div className="grid gap-3 sm:grid-cols-2">
      <Field label={`Dying (0–${maxDying(d.doomed)})`}>
        <div className="flex items-center gap-2">
          <NumberField className="w-16" value={d.dying} min={0} max={4} onChange={setDying} aria-label="Dying value" />
          {dead && <span className="flex items-center gap-1 rounded bg-danger/15 px-1.5 py-0.5 text-xs font-semibold text-danger"><Skull size={12} aria-hidden /> Dead</span>}
        </div>
      </Field>
      <Field label="Wounded">
        <NumberField className="w-20" value={d.wounded} min={0} onChange={(v) => setDefenses({ wounded: v })} aria-label="Wounded value" />
      </Field>
      <Field label="Doomed">
        <NumberField className="w-20" value={d.doomed} min={0} max={3} onChange={(v) => setDefenses({ doomed: v })} aria-label="Doomed value" />
      </Field>
      <Field label="Hero Points">
        <div className="flex items-center gap-2">
          <Button size="icon" variant="ghost" onClick={() => setDefenses({ heroPoints: Math.max(0, d.heroPoints - 1) })} aria-label="Spend hero point"><Minus size={14} aria-hidden /></Button>
          <span className="font-display text-xl font-semibold text-accent">{d.heroPoints}</span>
          <Button size="icon" variant="ghost" onClick={() => setDefenses({ heroPoints: d.heroPoints + 1 })} aria-label="Gain hero point"><Plus size={14} aria-hidden /></Button>
        </div>
      </Field>

      <div className="sm:col-span-2 rounded-md border border-line bg-panel px-3 py-2">
        {d.dying === 0 ? (
          <div className="flex items-center justify-between gap-2">
            <span className="text-xs text-muted">Knocked to 0 HP? Enter dying (adds your Wounded value{d.wounded > 0 ? ` of ${d.wounded}` : ''}).</span>
            <div className="flex items-center gap-2">
              <label className="flex items-center gap-1 text-[11px] text-muted">
                <input type="checkbox" checked={fromCrit} onChange={(e) => setFromCrit(e.target.checked)} /> crit
              </label>
              <Button size="sm" variant="danger" onClick={doKnockOut}>Knock out</Button>
            </div>
          </div>
        ) : (
          <div>
            <div className="mb-1 flex items-center justify-between">
              <span className="smallcaps">Recovery check</span>
              <span className="font-mono text-sm text-ink">DC {recoveryDc(d.dying)}</span>
            </div>
            <p className="mb-2 text-[11px] text-muted">Roll a flat d20 vs the DC, then record the result (success lowers Dying; reaching 0 makes you Wounded):</p>
            <div className="grid grid-cols-2 gap-1 sm:grid-cols-4">
              <Button size="sm" variant="secondary" onClick={() => doRecover('critical-success')}>Crit success −2</Button>
              <Button size="sm" variant="secondary" onClick={() => doRecover('success')}>Success −1</Button>
              <Button size="sm" variant="secondary" onClick={() => doRecover('failure')}>Failure +1</Button>
              <Button size="sm" variant="danger" onClick={() => doRecover('critical-failure')}>Crit fail +2</Button>
            </div>
            {d.heroPoints >= 1 && (
              <div className="mt-2 flex items-center justify-between gap-2 border-t border-line pt-2">
                <span className="text-[11px] text-muted">Heroic Recovery: spend ALL your Hero Points ({d.heroPoints}) to drop to Dying 0 and stabilize.</span>
                <Button size="sm" variant="primary" onClick={doHeroRescue}>Spend &amp; stabilize</Button>
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

export function DefensesSection({ c, update }: SectionProps) {
  const d = c.defenses;
  const setD = (p: Partial<typeof d>) => update({ defenses: { ...d, ...p } });

  return (
    <SheetSection title="Status & Defenses">
      {c.system === '5e' ? (
        <div className="grid gap-3 sm:grid-cols-2">
          <Field label="Death Saves">
            <div className="flex items-center gap-4">
              <span className="flex items-center gap-1 text-xs text-success">
                Successes
                <Pips count={3} filled={d.deathSaves.successes} label="Death save success" onToggle={(n) => setD({ deathSaves: { ...d.deathSaves, successes: n } })} />
              </span>
              <span className="flex items-center gap-1 text-xs text-danger">
                Failures
                <Pips count={3} filled={d.deathSaves.failures} label="Death save failure" onToggle={(n) => setD({ deathSaves: { ...d.deathSaves, failures: n } })} />
              </span>
            </div>
          </Field>
          <Field label="Inspiration">
            <Button size="sm" variant={d.inspiration ? 'primary' : 'secondary'} onClick={() => setD({ inspiration: !d.inspiration })}>
              {d.inspiration ? <><Star size={13} aria-hidden /> Inspired</> : 'Grant inspiration'}
            </Button>
          </Field>
          <Field label="Exhaustion (0–6)">
            <NumberField className="w-20" value={d.exhaustion} min={0} max={6} onChange={(v) => setD({ exhaustion: v })} aria-label="Exhaustion level" />
            {d.exhaustion >= 4 && <span className="ml-2 text-[11px] text-warning">Max HP halved</span>}
          </Field>
        </div>
      ) : (
        <Pf2eDefenses c={c} update={update} />
      )}
    </SheetSection>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="rounded-md border border-line bg-panel px-3 py-2">
      <div className="mb-1 smallcaps">{label}</div>
      {children}
    </div>
  );
}
