/* ===================================================================
   hotbar.jsx — player action bar + keyboard bindings

   A bottom-centre toolbar (mirrors the DM's controls) giving every player
   their spells / attacks and a set of harmless throwables, all bound to
   keys they can press even while it isn't their turn ("not in play").

   Rules of the table:
     • Damage actions (attack / damage rolls) require a dice roll BEFORE any
       damage is dealt — either rolled here, or the player can submit the
       total from their own physical dice.
     • Non-damage keys throw a harmless object instead (rock, small flame,
       stick, water). The throw is shown in both layers: a 2D overlay flies
       across the battle map, and a physics prop is tossed in the 3D world
       (App posts embers:throw to the world iframe).

   No-build/global-scope rules: this loads before app.jsx, so it must use
   React.useState/useEffect/etc. (not destructured) to avoid redeclaring the
   shared React hook locals other files already pull in.
   =================================================================== */
const HOTBAR_THROWS = [
  { id: 'rock',  key: 'q', glyph: '🪨', name: 'Rock' },
  { id: 'flame', key: 'w', glyph: '🔥', name: 'Small flame' },
  { id: 'stick', key: 'e', glyph: '🪵', name: 'Stick' },
  { id: 'water', key: 'r', glyph: '💧', name: 'Water' },
];

const HOTBAR_DEFAULT_ACTIONS = [
  { id: 'atk', label: 'Attack', formula: '1d20+5', tag: 'attack' },
  { id: 'dmg', label: 'Damage', formula: '1d8+3',  tag: 'damage' },
  { id: 'cast', label: 'Cantrip', formula: '1d10', tag: 'damage' },
];

function PlayerHotbar({ activeRef, getEnt, addRoll, onThrow }) {
  const allRolls = (typeof SAVED_ROLLS !== 'undefined' && SAVED_ROLLS) || [];
  const myRolls = allRolls.filter(r => r.who === activeRef);
  const actions = (myRolls.length ? myRolls : HOTBAR_DEFAULT_ACTIONS).slice(0, 5);
  const slots = actions.map((a, i) => ({ ...a, key: String(i + 1) }));

  const [pending, setPending] = React.useState(null);   // damage action awaiting a roll
  const [manual, setManual] = React.useState('');

  const fireRoll = React.useCallback((a, manualTotal) => {
    let res;
    if (manualTotal != null && manualTotal !== '') {
      const n = parseInt(manualTotal, 10);
      res = { total: isNaN(n) ? 0 : n, dice: [], formula: `${a.formula} (physical)` };
    } else {
      res = window.rollFormula(a.formula);
    }
    addRoll({ ...res, label: a.label, who: activeRef });
    setPending(null);
    setManual('');
  }, [addRoll, activeRef]);

  const triggerAction = React.useCallback((a) => {
    const dealsDamage = a.tag === 'damage' || a.tag === 'attack';
    if (dealsDamage) setPending(a);   // gate: must roll before damage is dealt
    else fireRoll(a);                  // heal/util resolves immediately
  }, [fireRoll]);

  const doThrow = React.useCallback((t) => { onThrow && onThrow(t); }, [onThrow]);

  // Global keybindings — ignored while typing in a field or with a modifier held.
  React.useEffect(() => {
    const onKey = (e) => {
      const el = document.activeElement;
      if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)) return;
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      const k = (e.key || '').toLowerCase();
      const t = HOTBAR_THROWS.find(x => x.key === k);
      if (t) { e.preventDefault(); doThrow(t); return; }
      const s = slots.find(x => x.key === k);
      if (s) { e.preventDefault(); triggerAction(s); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [slots, triggerAction, doThrow]);

  return (
    <div className="hotbar leather stitched" role="toolbar" aria-label="Your action bar">
      <div className="hb-group hb-actions">
        {slots.map(s => (
          <button key={s.id} className="hb-slot" onClick={() => triggerAction(s)}
            aria-label={`${s.label}, ${s.formula} (key ${s.key})`} title={`${s.label} — ${s.formula}`}>
            <span className="hb-key" aria-hidden="true">{s.key}</span>
            <span className="hb-name">{s.label}</span>
            <span className="hb-sub">{s.formula}</span>
          </button>
        ))}
      </div>

      <div className="hb-sep" aria-hidden="true" />

      <div className="hb-group hb-throws">
        {HOTBAR_THROWS.map(t => (
          <button key={t.id} className="hb-throw" onClick={() => doThrow(t)}
            aria-label={`Throw ${t.name} (key ${t.key})`} title={`Throw ${t.name} — key ${t.key.toUpperCase()}`}>
            <span className="hb-glyph" aria-hidden="true">{t.glyph}</span>
            <span className="hb-key" aria-hidden="true">{t.key}</span>
          </button>
        ))}
      </div>

      {pending && (
        <div className="hb-roll" role="dialog" aria-label={`Roll for ${pending.label}`}>
          <div className="hb-roll-hd">{pending.label} — roll to deal damage</div>
          <div className="hb-roll-row">
            <button className="btn" onClick={() => fireRoll(pending)}>Roll {pending.formula}</button>
            <span className="hb-or">or</span>
            <input className="hb-manual" type="number" inputMode="numeric" placeholder="physical total"
              value={manual} onChange={e => setManual(e.target.value)}
              aria-label="Enter the total from your physical dice" />
            <button className="btn ghost" disabled={manual === ''} onClick={() => fireRoll(pending, manual)}>Submit</button>
            <button className="composer-x" aria-label="Cancel roll" onClick={() => { setPending(null); setManual(''); }}>✕</button>
          </div>
        </div>
      )}
    </div>
  );
}
window.PlayerHotbar = PlayerHotbar;
