// app.jsx — main controller for SYLLABUS://OVERRIDE

const { useState: useStApp, useEffect: useEfApp } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "difficulty": "operative",
  "syncFx": false,
  "scanlines": true,
  "a11yDyslexia": true,
  "a11yLargeText": true,
  "a11yHighContrast": true,
  "a11yExtendedTime": true
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [phase, setPhase] = useStApp('signin'); // signin|instructor|briefing|preflight|squad|board|datastream|heist|policy|debrief|resources
  const [student, setStudent] = useStApp(null);
  const [resourcesReturn, setResourcesReturn] = useStApp('briefing');
  const [nextProtocolPhase, setNextProtocolPhase] = useStApp('datastream');
  const [run, setRun] = useStApp(null);
  const [scores, setScores] = useStApp({});
  const [missionTime, setMissionTime] = useStApp(0);
  const savedRef = React.useRef(false);

  // Mission clock starts when we leave the pre-flight, runs through debrief
  const appPaused = window.useSylPaused ? window.useSylPaused() : false;
  useEfApp(() => {
    if (phase === 'signin' || phase === 'instructor' || phase === 'briefing' || phase === 'preflight' || phase === 'debrief' || appPaused) return;
    const t = setInterval(() => setMissionTime((m) => m + 1), 1000);
    return () => clearInterval(t);
  }, [phase, appPaused]);

  function startRun(runData) {
    setRun(runData);
    setScores({});
    setMissionTime(0);
    setNextProtocolPhase('datastream');
    savedRef.current = false;
    setPhase('board');
  }

  function logCompletion(finalScores) {
    if (!student || savedRef.current) return;
    const total = (finalScores.datastream || 0) + (finalScores.heist || 0) + (finalScores.policy || 0);
    const passed = total >= 1500;
    const grade = total >= 2500 ? 'S' : total >= 2000 ? 'A' : total >= 1500 ? 'B' : total >= 1000 ? 'C' : 'F';
    SylRosterStorage.saveCompletion({
      name: student.name,
      email: student.email,
      section: student.section,
      signedInAt: student.signedInAt,
      completedAt: Date.now(),
      difficulty: tweaks.difficulty,
      totalXp: total,
      scores: {
        datastream: finalScores.datastream || 0,
        heist: finalScores.heist || 0,
        policy: finalScores.policy || 0,
        triage: finalScores.triage || 0,
        hexsweep: finalScores.hexsweep || 0,
      },
      grade,
      passed,
      durationSec: missionTime,
      squadName: run ? run.squadName : null,
      role: run ? run.role.id : null,
    });
    savedRef.current = true;
  }

  function nextProtocol(result) {
    const newScores = { ...scores, [result.protocol]: result.score };
    setScores(newScores);
    if (result.protocol === 'datastream') { setNextProtocolPhase('triage'); setPhase('board'); }
    else if (result.protocol === 'triage') { setNextProtocolPhase('heist'); setPhase('board'); }
    else if (result.protocol === 'heist') { setNextProtocolPhase('hexsweep'); setPhase('board'); }
    else if (result.protocol === 'hexsweep') { setNextProtocolPhase('policy'); setPhase('board'); }
    else if (result.protocol === 'policy') {
      logCompletion(newScores);
      setPhase('debrief');
    }
  }

  function restart() {
    setPhase('squad');
    setScores({});
    setMissionTime(0);
    setNextProtocolPhase('datastream');
    savedRef.current = false;
  }

  const phaseLabel = {
    signin: 'NODE/AUTH // CREDENTIALS REQUIRED',
    instructor: 'NODE/INSTRUCTOR // CLEARANCE T1',
    briefing: 'NODE/INFO-I-399 // STANDBY',
    preflight: 'NODE/INFO-I-399 // PRE-FLIGHT BRIEFING',
    squad: 'NODE/INFO-I-399 // SQUAD ASSEMBLY',
    board: 'NODE/INFO-I-399 // MISSION BOARD',
    datastream: 'NODE/INFO-I-399 // PROTOCOL-01 LIVE',
    triage: 'NODE/IU // INTERLUDE · UPLINK_TRIAGE',
    heist: 'NODE/INFO-I-399 // PROTOCOL-02 LIVE',
    hexsweep: 'NODE/IU // INTERLUDE · HEX_SWEEP',
    policy: 'NODE/INFO-I-399 // PROTOCOL-03 LIVE',
    debrief: 'NODE/INFO-I-399 // DEBRIEF',
    resources: 'NODE/IU // SUPPORT_NET',
  }[phase];

  const stageStyle = !tweaks.scanlines ? { '--scan-opacity': 0 } : {};

  // Apply accessibility tweaks to <html> as data attributes / class flags
  useEfApp(() => {
    const root = document.documentElement;
    root.classList.toggle('a11y-dyslexia', !!tweaks.a11yDyslexia);
    root.classList.toggle('a11y-large-text', !!tweaks.a11yLargeText);
    root.classList.toggle('a11y-high-contrast', !!tweaks.a11yHighContrast);
    window.__sylExtendedTime = !!tweaks.a11yExtendedTime;
  }, [tweaks.a11yDyslexia, tweaks.a11yLargeText, tweaks.a11yHighContrast, tweaks.a11yExtendedTime]);

  return (
    <>
      <a href="#main-stage" className="skip-link">Skip to main content</a>
      {window.A11yAnnouncer && React.createElement(window.A11yAnnouncer)}
      <div className={`stage ${tweaks.scanlines ? '' : 'no-scan'}`}>
        <div className="stage-inner">
          <div className="hud" role="banner" aria-label="Mission status header">
            <div className="hud-cluster">
              <div className="hud-cell">
                <div className="hud-dot" />
                <span>{phaseLabel}</span>
              </div>
              <div className="hud-cell">
                <span>SECTOR · 03</span>
              </div>
              <div className="hud-cell">
                <span>CRYO · {Math.floor(missionTime / 60).toString().padStart(2, '0')}:{(missionTime % 60).toString().padStart(2, '0')}</span>
              </div>
            </div>
            <div className="hud-cluster">
              {run && phase !== 'briefing' && phase !== 'squad' && (
                <>
                  <div className="hud-cell"><span>SQUAD</span> <b>{run.squadName}</b></div>
                  <div className="hud-cell"><span>ROLE</span> <b style={{ color: run.role.accent }}>{run.role.name}</b></div>
                </>
              )}
              <div className="hud-cell">
                <span>DIFF</span>
                <b style={{ color: 'var(--neon-yellow)' }}>{tweaks.difficulty.toUpperCase()}</b>
              </div>
              {window.PauseButton && React.createElement(window.PauseButton, { phase })}
            </div>
          </div>

          <main id="main-stage" tabIndex={-1} aria-label={`Current screen: ${phaseLabel}`}
            style={{ display: 'contents' }}>
          {phase === 'signin' && (
            <SignInScreen
              onSignIn={(s) => { setStudent(s); setPhase('briefing'); }}
              onInstructor={() => setPhase('instructor')}
            />
          )}
          {phase === 'instructor' && (
            <InstructorScreen onBack={() => setPhase('signin')} />
          )}
          {phase === 'briefing' && (
            <BriefingScreen onLaunch={() => setPhase('preflight')}
              onResources={() => { setResourcesReturn('briefing'); setPhase('resources'); }} />
          )}
          {phase === 'preflight' && (
            <PreflightScreen onLaunch={() => setPhase('squad')}
              onResources={() => { setResourcesReturn('preflight'); setPhase('resources'); }}
              onBack={() => setPhase('briefing')} />
          )}
          {phase === 'squad' && (
            <SquadScreen onStart={startRun} difficulty={tweaks.difficulty} />
          )}
          {phase === 'board' && run && (
            <BoardScreen run={run} scores={scores} nextPhase={nextProtocolPhase}
              onLaunch={() => setPhase(nextProtocolPhase)} />
          )}
          {phase === 'datastream' && run && (
            <DatastreamScreen run={run} difficulty={tweaks.difficulty} onComplete={nextProtocol} />
          )}
          {phase === 'heist' && run && (
            <DeadlineHeistScreen run={run} difficulty={tweaks.difficulty} onComplete={nextProtocol} />
          )}
          {phase === 'triage' && run && (
            <TriageScreen run={run} difficulty={tweaks.difficulty} onComplete={nextProtocol} />
          )}
          {phase === 'hexsweep' && run && (
            <HexSweepScreen run={run} difficulty={tweaks.difficulty} onComplete={nextProtocol} />
          )}
          {phase === 'policy' && run && (
            <PolicyFirewallScreen run={run} difficulty={tweaks.difficulty} onComplete={nextProtocol} />
          )}
          {phase === 'debrief' && run && (
            <DebriefScreen run={run} scores={scores} onRestart={restart}
              onResources={() => { setResourcesReturn('debrief'); setPhase('resources'); }} />
          )}
          {phase === 'resources' && (
            <ResourcesScreen onBack={() => setPhase(resourcesReturn)} />
          )}
          </main>
        </div>
      </div>

      {window.DropPacketButton && React.createElement(window.DropPacketButton, { phase, run, student })}

      <TweaksPanel title="TWEAKS // RUNTIME">
        <TweakSection label="Difficulty" />
        <TweakRadio
          label="Tier"
          value={tweaks.difficulty}
          options={[
            { value: 'recruit', label: 'Recruit' },
            { value: 'operative', label: 'Op' },
            { value: 'ghost', label: 'Ghost' },
          ]}
          onChange={(v) => setTweak('difficulty', v)}
        />
        <div style={{ fontSize: 10, color: 'rgba(41,38,27,.55)', lineHeight: 1.5, marginTop: 4 }}>
          {tweaks.difficulty === 'recruit' && '5 packets · 12s each · 50s heist. Forgiving.'}
          {tweaks.difficulty === 'operative' && '7 packets · 9s each · 45s heist. Standard.'}
          {tweaks.difficulty === 'ghost' && '9 packets · 6s each · 40s heist. Brutal.'}
        </div>

        <TweakSection label="Visual FX" />
        <TweakToggle label="Scanlines" value={tweaks.scanlines} onChange={(v) => setTweak('scanlines', v)} />
        <TweakToggle label="Sync flash effects" value={tweaks.syncFx} onChange={(v) => setTweak('syncFx', v)} />

        <TweakSection label="Accessibility" />
        <TweakToggle label="Dyslexia-friendly font" value={tweaks.a11yDyslexia}
          onChange={(v) => setTweak('a11yDyslexia', v)} />
        <TweakToggle label="Larger text (+15%)" value={tweaks.a11yLargeText}
          onChange={(v) => setTweak('a11yLargeText', v)} />
        <TweakToggle label="High contrast" value={tweaks.a11yHighContrast}
          onChange={(v) => setTweak('a11yHighContrast', v)} />
        <TweakToggle label="Extended timers (1.5×)" value={tweaks.a11yExtendedTime}
          onChange={(v) => setTweak('a11yExtendedTime', v)} />
        <div style={{ fontSize: 10, color: 'rgba(41,38,27,.55)', lineHeight: 1.5, marginTop: 4 }}>
          Press <b>P</b> any time to pause.
        </div>

        <TweakSection label="Run" />
        <TweakButton label="Restart current run" secondary onClick={() => { setRun(null); setPhase(student ? 'briefing' : 'signin'); setScores({}); savedRef.current = false; }} />
        <TweakButton label="Sign out operative" secondary onClick={() => { setStudent(null); setRun(null); setScores({}); savedRef.current = false; setPhase('signin'); }} />
      </TweaksPanel>
    </>
  );
}

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