import { useState } from 'react';
import type { Character, Combatant, Encounter, MapToken } from '@/lib/schemas';
import { Button } from '@/components/ui/Button';
import { Select } from '@/components/ui/Input';
import { KIND_COLOR, baseSpec, unplacedPcs, type TokenSpec } from './tokens';

export type { TokenSpec };

/** Left sidebar for one-click placement of party / encounter / blank tokens. */
export function TokenPalette({ characters, encounters, existingTokens, onPlace, onPlaceMany, onClose }: {
  characters: Character[];
  encounters: Encounter[];
  existingTokens: MapToken[];
  onPlace: (spec: TokenSpec) => void;
  onPlaceMany: (specs: TokenSpec[]) => void;
  onClose: () => void;
}) {
  const pcs = characters.filter((c) => c.kind === 'pc');
  // Any encounter that has combatants — planned OR active — can supply tokens.
  const withCombatants = encounters.filter((e) => e.combatants.length > 0);
  const [encId, setEncId] = useState('');
  const selectedEnc = withCombatants.find((e) => e.id === encId)
    ?? encounters.find((e) => e.status === 'active' && e.combatants.length > 0)
    ?? withCombatants[0] ?? null;

  const hasPc = (id: string) => existingTokens.some((t) => t.characterId === id);
  const hasCombatant = (cb: Combatant) => existingTokens.some((t) => t.combatantId === cb.id || (!t.combatantId && !t.characterId && t.label === cb.name));

  const placePc = (c: Character) => onPlace(baseSpec({ label: c.name, color: KIND_COLOR.pc, kind: 'pc', characterId: c.id, hp: c.hp }));
  const addAllPcs = () => onPlaceMany(
    unplacedPcs(pcs, existingTokens).map((c, i) => baseSpec({ label: c.name, color: KIND_COLOR.pc, kind: 'pc', characterId: c.id, hp: c.hp, col: i, row: 0 })),
  );
  const placeCombatant = (cb: Combatant) => onPlace(baseSpec({
    label: cb.name, color: KIND_COLOR[cb.kind], kind: cb.kind, hp: cb.hp, combatantId: cb.id,
    ...(cb.characterId ? { characterId: cb.characterId } : {}),
  }));

  return (
    <aside className="flex h-full min-h-0 flex-col gap-2 rounded-lg border border-line bg-panel p-2 text-sm">
      <div className="flex items-center justify-between">
        <h3 className="text-xs font-semibold uppercase tracking-wide text-muted">Tokens</h3>
        <button onClick={onClose} className="text-xs text-muted hover:text-ink" aria-label="Hide token palette">Hide</button>
      </div>

      <div className="min-h-0 flex-1 space-y-3 overflow-y-auto pr-1">
        <section>
          <div className="mb-1 flex items-center justify-between">
            <span className="text-xs font-medium text-ink">Party</span>
            <Button size="sm" variant="ghost" disabled={pcs.length === 0 || pcs.every((c) => hasPc(c.id))} onClick={addAllPcs}>+ All</Button>
          </div>
          {pcs.length === 0 ? (
            <p className="text-xs text-muted">No player characters in this campaign.</p>
          ) : (
            <ul className="space-y-1">
              {pcs.map((c) => (
                <li key={c.id}>
                  <button onClick={() => placePc(c)} className="flex w-full items-center gap-2 rounded-md border border-line bg-surface px-2 py-1 text-left hover:border-accent">
                    {c.portrait
                      ? <img src={c.portrait} alt="" className="h-5 w-5 shrink-0 rounded-full object-cover" />
                      : <span className="h-3 w-3 shrink-0 rounded-full" style={{ background: KIND_COLOR.pc }} />}
                    <span className="flex-1 truncate text-ink">{c.name}</span>
                    <span className="text-[10px] uppercase text-muted">{hasPc(c.id) ? 'placed' : `L${c.level}`}</span>
                  </button>
                </li>
              ))}
            </ul>
          )}
        </section>

        {selectedEnc && (
          <section>
            <div className="mb-1 flex items-center gap-1">
              <span className="text-xs font-medium text-ink">Encounter</span>
              <Button size="sm" variant="ghost" className="ml-auto h-6 px-1.5"
                disabled={selectedEnc.combatants.every((cb) => hasCombatant(cb))}
                onClick={() => onPlaceMany(selectedEnc.combatants.filter((cb) => !hasCombatant(cb)).map((cb, i) => baseSpec({
                  label: cb.name, color: KIND_COLOR[cb.kind], kind: cb.kind, hp: cb.hp, combatantId: cb.id, col: i, row: 1,
                  ...(cb.characterId ? { characterId: cb.characterId } : {}),
                })))}>+ All</Button>
            </div>
            {withCombatants.length > 1 ? (
              <Select className="mb-1 w-full px-2 py-1 pr-7 text-xs leading-tight" value={selectedEnc.id} onChange={(e) => setEncId(e.target.value)} aria-label="Encounter">
                {withCombatants.map((e) => (
                  <option key={e.id} value={e.id}>{e.status === 'active' ? '● ' : ''}{e.name} ({e.combatants.length})</option>
                ))}
              </Select>
            ) : (
              <div className="mb-1 truncate text-[11px] text-muted" title={selectedEnc.name}>{selectedEnc.status === 'active' ? '● ' : ''}{selectedEnc.name}</div>
            )}
            <ul className="space-y-1">
              {selectedEnc.combatants.map((cb) => {
                const placed = hasCombatant(cb);
                return (
                  <li key={cb.id}>
                    <button onClick={() => placeCombatant(cb)} disabled={placed} className="flex w-full items-center gap-2 rounded-md border border-line bg-surface px-2 py-1 text-left enabled:hover:border-accent disabled:opacity-50">
                      <span className="h-3 w-3 shrink-0 rounded-full" style={{ background: KIND_COLOR[cb.kind] }} />
                      <span className="flex-1 truncate text-ink">{cb.name}</span>
                      <span className="text-[10px] uppercase text-muted">{placed ? 'placed' : cb.kind}</span>
                    </button>
                  </li>
                );
              })}
            </ul>
          </section>
        )}

        <section>
          <div className="mb-1 text-xs font-medium text-ink">Add blank</div>
          <div className="flex flex-wrap gap-1">
            <Button size="sm" variant="secondary" onClick={() => onPlace(baseSpec({ label: 'NPC', color: KIND_COLOR.npc, kind: 'npc' }))}>NPC</Button>
            <Button size="sm" variant="secondary" onClick={() => onPlace(baseSpec({ label: 'Foe', color: KIND_COLOR.monster, kind: 'monster' }))}>Monster</Button>
            <Button size="sm" variant="secondary" onClick={() => onPlace(baseSpec({ label: '', color: KIND_COLOR.object, kind: 'object' }))}>Object</Button>
          </div>
        </section>
      </div>
    </aside>
  );
}
