/* ============================================================
   THE DEFUSER — a "Keep Talking and Nobody Explodes" comms trap.
   • DefuserMainView   — the whole trap + countdown + strikes (shared truth)
   • DefuserModuleView — one module's live state (Main + operator phone)
   • DefuserPlayerOverlay — operator controls AND/OR reader rules per player
   ============================================================ */
const { useState: useS_df, useEffect: useE_df, useRef: useR_df } = React;

const DF_WIRE_HEX = { Red:'#d9534f', Blue:'#5a8fd6', Green:'#52b07a', Gold:'#f0a836', White:'#e8e2d6' };
const DF_GLYPH = { Moon:'☾', Sun:'☀', Eye:'◉', Serpent:'§', Thorn:'⚚', Wave:'≈' };
const DF_KIND_ICON = { wires:'✂', glyphs:'◑', levers:'⇅', sequence:'⌘' };

function dfFmt(ms){
  const s = Math.max(0, Math.ceil(ms/1000));
  return `${String(Math.floor(s/60)).padStart(2,'0')}:${String(s%60).padStart(2,'0')}`;
}

/* ---------- ONE MODULE — live state; interactive only for its operator ---------- */
function DefuserModuleView({ module, interactive, compact }){
  const m = module, st = m.state, locked = m.locked;
  const fire = (action)=>{
    if(!interactive || locked) return;
    Game.operateModule(m.id, action);
    haptic(HAPTIC.card);
    try{ audio.play('beat'); }catch(_){}
  };
  return (
    <div className={`df-mod ${locked?'locked':''} ${compact?'compact':''}`}>
      <div className="df-mod-head">
        <span className="df-mod-icon">{DF_KIND_ICON[m.kind]}</span>
        <span className="df-mod-label">{m.label}</span>
        {locked && <span className="df-mod-ok">✓ locked</span>}
      </div>

      {m.kind==='wires' && (
        <div className="df-wires">
          {st.wires.map((w,i)=>{
            const isCut = st.cut.includes(i);
            return (
              <div key={i} className={`df-wire ${isCut?'cut':''}`}>
                <span className="df-wire-n">{i+1}</span>
                <span className="df-wire-line" style={{ '--wc':DF_WIRE_HEX[w.color] }}>
                  <span className="df-wire-seg a"></span><span className="df-wire-seg b"></span>
                </span>
                <span className="df-wire-name" style={{ color:DF_WIRE_HEX[w.color] }}>{w.color}</span>
                {interactive && !isCut && !locked && (
                  <button className="df-cut-btn" onClick={()=>fire({type:'cut', index:i})}>cut</button>
                )}
              </div>
            );
          })}
        </div>
      )}

      {m.kind==='glyphs' && (
        <div className="df-dials">
          {st.dials.map((g,i)=>(
            <div key={i} className="df-dial">
              <div className="df-dial-face">{DF_GLYPH[st.glyphs[g]]}</div>
              <div className="df-dial-name">{st.glyphs[g]}</div>
              {interactive && !locked && (
                <button className="df-dial-btn" onClick={()=>fire({type:'rotate', dial:i})}>↻ turn</button>
              )}
            </div>
          ))}
        </div>
      )}

      {m.kind==='levers' && (
        <div className="df-levers">
          {st.levers.map((up,i)=>(
            <div key={i} className={`df-lever ${up?'up':'down'}`}>
              <button className="df-lever-track" disabled={!interactive||locked} onClick={()=>fire({type:'flip', index:i})}>
                <span className="df-lever-knob"></span>
              </button>
              <span className="df-lever-n">{i+1}</span>
            </div>
          ))}
        </div>
      )}

      {m.kind==='sequence' && (
        <div className="df-seq">
          <div className="df-seq-progress">
            {st.symbols.map((_,i)=>(
              <span key={i} className={`df-seq-pip ${i<st.pressed.length?'on':''}`}></span>
            ))}
          </div>
          <div className="df-seq-keys">
            {st.symbols.map((s,i)=>(
              <button key={i} className="df-seq-key" disabled={!interactive||locked} onClick={()=>fire({type:'press', index:i})}>{s}</button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
window.DefuserModuleView = DefuserModuleView;

/* ============================================================
   MAIN SCREEN — the whole trap, the source of truth
   ============================================================ */
function DefuserMainView({ defuser }){
  const game = useGame();
  const d = defuser;
  const [left, setLeft] = useS_df(Math.max(0, d.endsAt - Date.now()));
  const [strikeN, setStrikeN] = useS_df(0);

  useGameEvents((ev)=>{
    if(ev.type==='defuser-strike'){ try{ audio.play('miss'); }catch(_){} setStrikeN(k=>k+1); }
    else if(ev.type==='defuser-lock'){ try{ audio.play('beat'); }catch(_){} }
    else if(ev.type==='defuser-disarm'){ try{ audio.play('gateOpen'); }catch(_){} }
    else if(ev.type==='defuser-boom'){ try{ audio.play('boom'); }catch(_){} }
  });

  // the Main screen owns the countdown; expiry triggers the boom
  useE_df(()=>{
    if(d.status!=='live'){ setLeft(Math.max(0, d.endsAt-Date.now())); return; }
    const tick=()=>{ const l=d.endsAt-Date.now(); setLeft(Math.max(0,l)); if(l<=0) Game.onBoom(); };
    tick(); const id=setInterval(tick, 200); return ()=>clearInterval(id);
  }, [d.status, d.endsAt]);

  const low = left < 30000 && d.status==='live';
  const hintRule = d.hintRuleId ? d.rules.find(r=>r.id===d.hintRuleId) : null;
  const solved = d.modules.filter(m=>m.locked).length;

  return (
    <div className={`defuser-stage ${d.status} ${strikeN>0?'':''}`}>
      <Embers count={20}/>
      <div key={'zap'+d.struckId} className={d.struckId?'df-zap':''}></div>

      <div className="df-topbar">
        <div className="df-title display">The Defuser</div>
        <div className={`df-timer ${low?'low':''}`}>{dfFmt(left)}</div>
        <div className="df-strikes">
          {Array.from({length:d.maxStrikes}).map((_,i)=>(
            <span key={i} className={`df-strike ${i<d.strikes?'hit':''}`}>✖</span>
          ))}
        </div>
      </div>

      <div className={`trap ${d.struckId?'':''}`}>
        <div className="df-grid" style={{ '--cols': Math.min(d.modules.length,2) }}>
          {d.modules.map(m=>(
            <div key={m.id} className={`df-cell module ${m.locked?'locked':''} ${d.struckModule===m.id && d.status==='live'?'struck':''}`}>
              <DefuserModuleView module={m} interactive={false}/>
              <div className="df-cell-owner">
                {(()=>{ const op=game.players.find(p=>p.id===m.operator); return op?`Operated by ${op.name.split(' ')[0]}`:'Unassigned'; })()}
              </div>
            </div>
          ))}
        </div>
      </div>

      <div className="df-foot">
        {d.status==='live' && (
          <div className="df-foot-status">
            <span className="df-foot-count">{solved}/{d.modules.length} modules disarmed</span>
            <span className="df-foot-hint">Operators describe · Readers direct · talk it out</span>
          </div>
        )}
        {hintRule && d.status==='live' && (
          <div className="df-revealed-rule">
            <span className="df-rr-title">{hintRule.title}</span>
            <span className="df-rr-text">{hintRule.text}</span>
          </div>
        )}
        {d.status==='disarmed' && <div className="df-end disarmed display">TRAP DISARMED</div>}
        {d.status==='boom' && <div className="df-end boom display">THE TRAP TRIGGERS</div>}
      </div>
    </div>
  );
}
window.DefuserMainView = DefuserMainView;

/* ============================================================
   PLAYER SCREEN — operator controls and/or reader rules
   ============================================================ */
function DefuserPlayerOverlay({ player }){
  const game = useGame();
  const d = game.defuser;
  const [left, setLeft] = useS_df(Math.max(0, d.endsAt-Date.now()));
  useGameEvents((ev)=>{ if(ev.type==='defuser-strike'){ haptic(HAPTIC.damage); } else if(ev.type==='defuser-boom'){ haptic(HAPTIC.death); } });
  useE_df(()=>{
    if(!d.open || d.status!=='live') return;
    const id=setInterval(()=>setLeft(Math.max(0, d.endsAt-Date.now())), 250); return ()=>clearInterval(id);
  }, [d.open, d.status, d.endsAt]);
  if(!d.open) return null;

  const myModules = d.modules.filter(m=>m.operator===player.id);
  const myRules = d.rules.filter(r=>r.reader===player.id);
  const done = d.status!=='live';

  return (
    <div className={`defuser-overlay ${d.status}`}>
      <Embers count={12}/>
      <div className="df-ov-inner animate-fade-rise">
        <div className="df-ov-top">
          <span className="df-ov-eyebrow">☠ The Defuser</span>
          {!done && <span className={`df-ov-timer ${left<30000?'low':''}`}>{dfFmt(left)}</span>}
        </div>

        {done ? (
          <div className={`df-ov-end ${d.status}`}>
            <h2 className="display">{d.status==='disarmed'?'Disarmed':'It went off'}</h2>
            <p className="muted" style={{textTransform:'none'}}>{d.status==='disarmed'?'The trap is silent. Move on.':'The trap sprang — the Keeper decides the cost.'}</p>
          </div>
        ) : (myModules.length===0 && myRules.length===0) ? (
          <div className="df-ov-idle">
            <h2 className="display">Stand ready</h2>
            <p className="muted" style={{textTransform:'none'}}>The Keeper hasn't handed you a panel or a page yet. Watch the trap and help the table think.</p>
          </div>
        ) : (
          <>
            {myModules.length>0 && (
              <div className="df-ov-section">
                <div className="df-ov-role op">You operate — no rules here</div>
                <p className="df-ov-cue">Describe exactly what you see. A Reader holds the rule that tells you what to do.</p>
                {myModules.map(m=><DefuserModuleView key={m.id} module={m} interactive={true} compact={true}/>)}
              </div>
            )}
            {myRules.length>0 && (
              <div className="df-ov-section reader">
                <div className="df-ov-role rd">You read the manual — no controls here</div>
                <p className="df-ov-cue">Read these aloud and direct whoever holds the panel. Don't touch — describe.</p>
                {myRules.map(r=>(
                  <div key={r.id} className="df-rule">
                    <div className="df-rule-title">{r.title}</div>
                    <div className="df-rule-text">{r.text}</div>
                  </div>
                ))}
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}
window.DefuserPlayerOverlay = DefuserPlayerOverlay;
