/* ============================================================
   ENGINE VIEWS — the three role surfaces for the generalized
   GameRuntime, plus the driver and launcher. Every component
   self-gates on game.engine.active, so when no GameDef is running
   they render nothing and the app behaves exactly as before.

   • EngineDriver       — invisible; ticks the runtime + forwards
                          events (only the authority acts, inside RT).
   • EngineLauncher     — floating button + game picker (any device).
   • EngineMainView     — the shared-display phase frame.
   • EnginePlayerOverlay— the owning phone's PRIVATE role + actions.

   Private info (engine.deal[myId]) is read ONLY for the local player
   here and is never rendered on the Main.
   ============================================================ */
const { useState: useS_eng, useEffect: useE_eng, useRef: useR_eng } = React;

/* ---------- countdown hook (local, light) ---------- */
function useEngineCountdown(phase, startedAt){
  const [now, setNow] = useS_eng(Date.now());
  useE_eng(()=>{
    if(!phase || !phase.duration) return;
    const id = setInterval(()=> setNow(Date.now()), 500);
    return ()=> clearInterval(id);
  }, [phase && phase.id, startedAt]);
  if(!phase || !phase.duration) return null;
  return Math.max(0, Math.ceil(phase.duration - (now - (startedAt||0)) / 1000));
}
function fmtSecs(s){ if(s==null) return ''; const m = Math.floor(s/60), ss = s%60; return m>0 ? `${m}:${String(ss).padStart(2,'0')}` : `${ss}s`; }
function enginePhase(e){ return e && e.def && (e.def.phases||[]).find(p=> p.id===e.phaseId); }
function spyId(e){ const d = e.deal||{}; return Object.keys(d).find(pid=> d[pid] && d[pid].role==='spy'); }

/* ---------- 0 · DRIVER (invisible) ---------- */
function EngineDriver(){
  const game = useGame();
  const active = !!(game.engine && game.engine.active);
  useE_eng(()=>{
    if(!active) return;
    const id = setInterval(()=>{ try{ GameRuntime.tick(); }catch(_){} }, 250);
    return ()=> clearInterval(id);
  }, [active]);
  useGameEvents((ev)=>{ try{ GameRuntime.onEvent(ev); }catch(_){} });
  return null;
}
window.EngineDriver = EngineDriver;

/* ---------- 1 · LAUNCHER — pick & start a game (any device) ---------- */
function EngineLauncher(){
  const game = useGame();
  const e = game.engine || {};
  const [open, setOpen] = useS_eng(false);
  const games = window.BUILTIN_GAMES || [];
  const seated = (game.players||[]).filter(p=>!p.spectator).length;

  if(e.active){
    return (
      <button className="eng-fab end" onClick={()=>{ if(confirm('End the current game for everyone?')) GameRuntime.stop(); }}>
        ■ End {e.def ? e.def.title : 'game'}
      </button>
    );
  }
  return (
    <>
      <button className="eng-fab" onClick={()=>setOpen(true)}>🎭 Party Games</button>
      {open && (
        <div className="eng-modal" onClick={()=>setOpen(false)}>
          <div className="eng-modal-card liquid-glass" onClick={ev=>ev.stopPropagation()}>
            <div className="eng-modal-head">
              <h2 className="display">Party Games <span className="eng-beta">beta</span></h2>
              <button className="eng-x" onClick={()=>setOpen(false)}>✕</button>
            </div>
            <p className="muted" style={{textTransform:'none'}}>{seated} player{seated===1?'':'s'} seated. Everyone needs to be in the room first.</p>
            <div className="eng-game-list">
              {games.map(g=>{
                const ok = seated >= (g.players && g.players.min || 1);
                return (
                  <div key={g.id} className="eng-game-row">
                    <div className="eng-game-meta">
                      <b>{g.title}</b>
                      <span className="muted">{g.blurb||''}</span>
                      <span className="eng-game-tag">{g.players.min}–{g.players.max} · {g.needsModerator?'moderated':'auto-run'}</span>
                    </div>
                    <button className="chip-btn" disabled={!ok}
                      onClick={()=>{ GameRuntime.start(g); setOpen(false); }}>
                      {ok ? 'Start' : `Need ${g.players.min}+`}
                    </button>
                  </div>
                );
              })}
              {games.length===0 && <div className="muted">No games loaded.</div>}
            </div>
          </div>
        </div>
      )}
    </>
  );
}
window.EngineLauncher = EngineLauncher;

/* ---------- 2 · MAIN — the shared-display phase frame ----------
   Mounted from main-screen.jsx only when engine.active AND no block
   takeover is showing (the accuse-phase vote reuses VoteMainView). */
function EngineMainView(){
  const game = useGame();
  const e = game.engine || {};
  const d = e.def;
  const phase = d && (d.phases||[]).find(p=> p.id===e.phaseId);   // safe when d is null
  const remain = useEngineCountdown(phase, e.phaseStartedAt);      // hook runs every render
  if(!d) return null;
  const view = phase && phase.audience && phase.audience.main && phase.audience.main.view;

  if(e.result){
    const loc = e.vars && e.vars.loc;
    const sid = spyId(e);
    const spy = (game.players||[]).find(p=> p.id===sid);
    const groupWon = e.result.winner==='group';
    return (
      <div className="eng-main eng-reveal">
        <div className={`eng-verdict ${groupWon?'good':'evil'}`}>{e.result.text}</div>
        <div className="eng-reveal-facts">
          {loc && <div className="eng-fact">The location was <b>{loc.name}</b></div>}
          {spy && <div className="eng-fact">The Spy was <b>{(spy.name||'').split(' ')[0]}</b></div>}
        </div>
        <div className="muted eng-reveal-cta">Tap “End game” to play again.</div>
      </div>
    );
  }
  if(view==='briefing'){
    return (
      <div className="eng-main eng-brief">
        <div className="eng-title display">{d.title}</div>
        <div className="eng-brief-cue">Everyone — check your phone for your secret card.</div>
        {remain!=null && <div className="eng-countdown small">{remain}</div>}
      </div>
    );
  }
  if(view==='questions'){
    const locs = (d.setup && d.setup.tables && d.setup.tables.locations) || [];
    return (
      <div className="eng-main eng-questions">
        <div className="eng-q-head">
          <div className="eng-title display">Question Round</div>
          {remain!=null && <div className={`eng-countdown ${remain<=30?'low':''}`}>{fmtSecs(remain)}</div>}
        </div>
        <div className="eng-q-hint">Ask each other questions. Expose the Spy — or, if you’re the Spy, work out where you are.</div>
        <div className="eng-loc-board">
          {locs.map(l=> <span key={l.id} className="eng-loc-chip">{l.name}</span>)}
        </div>
      </div>
    );
  }
  // fallback (no block, no special view)
  return (
    <div className="eng-main">
      <div className="eng-title display">{d.title}</div>
      {phase && <div className="muted">{phase.name}</div>}
    </div>
  );
}
window.EngineMainView = EngineMainView;

/* ---------- 3 · PLAYER — the owning phone's private card + actions ---------- */
function EnginePlayerOverlay({ player }){
  const game = useGame();
  const e = game.engine || {};
  if(!e.active || !player) return null;
  const d = e.def; const phase = enginePhase(e);
  const view = phase && phase.audience && phase.audience.players && phase.audience.players.view;
  const mine = (e.deal||{})[player.id] || {};
  const amSpy = !!mine.spy;

  // reveal
  if(e.result){
    return (
      <div className="eng-pov eng-pov-reveal">
        <div className="eng-pov-inner animate-fade-rise">
          <div className={`eng-pov-verdict ${e.result.winner==='group'?'good':'evil'}`}>{e.result.text}</div>
          <div className="muted">{amSpy ? 'You were the Spy.' : `You were at the ${mine.place||'location'}.`}</div>
        </div>
      </div>
    );
  }
  // during the accuse vote, the existing VotePlayerOverlay handles input
  if(view==='vote') return null;
  if(view!=='role') return null;

  const locs = (d.setup && d.setup.tables && d.setup.tables.locations) || [];
  const isQuestions = phase && phase.id==='questions';
  return (
    <div className="eng-pov">
      <div className="eng-pov-inner animate-fade-rise">
        {amSpy ? (
          <>
            <div className="eng-card spy">
              <div className="eng-card-eyebrow">Your secret</div>
              <div className="eng-card-role display">You are the SPY</div>
              <div className="muted" style={{textTransform:'none'}}>Blend in. Don’t get caught — guess the location to win.</div>
            </div>
            {isQuestions && (
              <div className="eng-guess">
                <div className="eng-guess-label">Guess the location:</div>
                <div className="eng-guess-grid">
                  {locs.map(l=> <button key={l.id} className="eng-guess-btn"
                    onClick={()=>{ if(confirm(`Guess ${l.name}? A wrong guess loses instantly.`)) GameRuntime.setVar('spyGuess', l.id); }}>{l.name}</button>)}
                </div>
              </div>
            )}
          </>
        ) : (
          <div className="eng-card civ">
            <div className="eng-card-eyebrow">Your secret</div>
            <div className="eng-card-loc display">{mine.place||'—'}</div>
            <div className="eng-card-role">You are the <b>{mine.job||'guest'}</b></div>
          </div>
        )}
        {isQuestions && (
          <button className="eng-callvote chip-btn" onClick={()=>GameRuntime.choose('callVote')}>
            ⚖ Call a vote
          </button>
        )}
      </div>
    </div>
  );
}
window.EnginePlayerOverlay = EnginePlayerOverlay;
