// Root app — game state machine
const { useState: useStateA, useEffect: useEffectA, useRef: useRefA, useMemo: useMemoA } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#D7263D",
  "grain": 0.18,
  "ambient": 0.35,
  "showLineMarkers": true
}/*EDITMODE-END*/;

function App() {
  const cases = window.CASES || [window.CASE_DATA];
  const [caseId, setCaseId] = useStateA(cases[0].id);
  const caseData = cases.find(c => c.id === caseId) || cases[0];
  // Stamp _caseId on each suspect so the audio engine can locate the right folder.
  const suspects = useMemoA(() => caseData.suspects.map(s => Object.assign(s, { _caseId: caseData.id })), [caseData.id]);
  // Keep window.CASE_DATA in sync as a default-pointer for any code reading it.
  useEffectA(() => { window.CASE_DATA = caseData; }, [caseData.id]);

  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  const [screen, setScreen] = useStateA("briefing"); // briefing | room | accusing | verdict
  const [activeId, setActiveId] = useStateA(suspects[0].id);
  const [listened, setListened] = useStateA(() => new Set());
  const [flagged, setFlagged] = useStateA(() => new Map()); // key suspectId:lineId -> line
  const [jumpToken, setJumpToken] = useStateA(null);
  const [verdictPayload, setVerdictPayload] = useStateA(null);

  // Apply accent to CSS var
  useEffectA(() => {
    document.documentElement.style.setProperty("--accent", tweaks.accent);
    document.documentElement.style.setProperty("--grain", tweaks.grain);
  }, [tweaks.accent, tweaks.grain]);

  // Mark suspect as listened after 60% of clip heard
  useEffectA(() => {
    if (screen !== "room") return;
    const id = setInterval(() => {
      const cur = window.LIE_AUDIO.currentSuspectId();
      if (!cur) return;
      const s = suspects.find(x => x.id === cur);
      const t = window.LIE_AUDIO.getTime();
      if (s && t / s.duration > 0.6 && !listened.has(s.id)) {
        setListened(prev => new Set(prev).add(s.id));
      }
    }, 500);
    return () => clearInterval(id);
  }, [screen, listened, suspects]);

  function flag(suspect, line) {
    setFlagged(prev => {
      const next = new Map(prev);
      next.set(suspect.id + ":" + line.id, line);
      return next;
    });
  }
  function unflag(suspect, line) {
    setFlagged(prev => {
      const next = new Map(prev);
      next.delete(suspect.id + ":" + line.id);
      return next;
    });
  }
  function jump(suspect, line) {
    setActiveId(suspect.id);
    setJumpToken({ suspectId: suspect.id, time: line.start, token: Date.now() });
  }

  function deliver(suspect, line) {
    window.LIE_AUDIO.stop();
    setVerdictPayload({ suspect, line });
    setScreen("verdict");
  }
  function playAgain() {
    setScreen("briefing");
    setListened(new Set());
    setFlagged(new Map());
    setVerdictPayload(null);
    setActiveId(suspects[0].id);
  }

  function pickCase(newId) {
    if (newId === caseId) return;
    window.LIE_AUDIO.stop();
    setCaseId(newId);
    const next = cases.find(c => c.id === newId);
    setActiveId(next.suspects[0].id);
    setListened(new Set());
    setFlagged(new Map());
    setVerdictPayload(null);
    setScreen("briefing");
  }

  const activeSuspect = suspects.find(s => s.id === activeId);
  const canAccuse = listened.size === suspects.length;

  return (
    <div className="app" style={{ "--grain": tweaks.grain }}>
      <div className="grain-layer" />
      <div className="vignette-layer" />

      <header className="topbar">
        <div className="topbar-l">
          <span className="logo-block" />
          <span className="logo-text">FORENSIC AUDIO · UNIT 7</span>
        </div>
        <div className="topbar-c">
          {screen === "room" && (
            <>
              <span>CASE {caseData.id}</span>
              <span className="dot-sep">·</span>
              <span>{caseData.title}</span>
              <span className="dot-sep">·</span>
              <span className="rec-live"><span className="rec-dot" /> EVIDENCE LOCKED</span>
            </>
          )}
        </div>
        <div className="topbar-r">
          <span>{nowStamp()}</span>
        </div>
      </header>

      {screen === "briefing" && (
        <Briefing
          caseData={caseData}
          cases={cases}
          onPickCase={pickCase}
          onBegin={() => setScreen("room")}
        />
      )}

      {screen === "room" && (
        <main className="room">
          <Roster
            suspects={suspects}
            activeId={activeId}
            listened={listened}
            onPick={setActiveId}
          />
          <Player
            suspect={activeSuspect}
            flagged={flagged}
            onFlag={flag}
            onUnflag={unflag}
            jumpToken={jumpToken}
          />
          <Notebook
            suspects={suspects}
            flagged={flagged}
            listened={listened}
            onJump={jump}
            onUnflag={unflag}
            onAccuse={() => setScreen("accusing")}
            canAccuse={canAccuse}
          />
        </main>
      )}

      {screen === "accusing" && (
        <Accusation
          suspects={suspects}
          flagged={flagged}
          onClose={() => setScreen("room")}
          onDeliver={deliver}
        />
      )}

      {screen === "verdict" && verdictPayload && (
        <Verdict
          caseData={caseData}
          suspects={suspects}
          accused={verdictPayload.suspect}
          accusedLine={verdictPayload.line}
          onPlayAgain={playAgain}
        />
      )}

      <window.TweaksPanel title="Tweaks">
        <window.TweakSection title="Accent">
          <window.TweakColor
            label="Flag color"
            value={tweaks.accent}
            onChange={v => setTweak("accent", v)}
          />
        </window.TweakSection>
        <window.TweakSection title="Atmosphere">
          <window.TweakSlider
            label="Film grain"
            value={tweaks.grain}
            min={0} max={0.6} step={0.02}
            onChange={v => setTweak("grain", v)}
          />
          <window.TweakSlider
            label="Ambient bed"
            value={tweaks.ambient}
            min={0} max={1} step={0.05}
            onChange={v => setTweak("ambient", v)}
          />
        </window.TweakSection>
        <window.TweakSection title="Layout">
          <window.TweakToggle
            label="Show line markers"
            value={tweaks.showLineMarkers}
            onChange={v => setTweak("showLineMarkers", v)}
          />
        </window.TweakSection>
        <window.TweakSection title="Jump to">
          <window.TweakButton onClick={() => playAgain()}>↺ Restart case</window.TweakButton>
          <window.TweakButton onClick={() => { window.LIE_AUDIO.stop(); setScreen("room"); }}>→ Interrogation</window.TweakButton>
          <window.TweakButton onClick={() => {
            // mark all heard for testing the accuse flow
            setListened(new Set(suspects.map(s => s.id)));
            setScreen("accusing");
          }}>→ Accusation</window.TweakButton>
        </window.TweakSection>
      </window.TweaksPanel>
    </div>
  );
}

function nowStamp() {
  const d = new Date();
  return d.toISOString().replace("T", " ").slice(0, 19) + " UTC";
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
