// App — top-level state machine: intro → select → section

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "skipIntro": false,
  "cardStyle": "chunky",
  "accentColor": "#4f8eff",
  "showStars": true,
  "promptCopy": "watching",
  "soundOn": true,
  "spotlight": false,
  "useHeadshot": false
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [stage, setStage] = React.useState(t.skipIntro ? "select" : "intro");
  const [activeId, setActiveId] = React.useState(null);
  const [cmdOpen, setCmdOpen] = React.useState(false);
  const [theme, setTheme] = React.useState(() => (window.bnsLoadTheme?.() || 'cinema'));

  // Re-render when ThemeToggle swaps themes so the intro picker stays in sync
  React.useEffect(() => {
    const onThemeChange = (e) => setTheme(e.detail || 'cinema');
    window.addEventListener('bns:themechange', onThemeChange);
    return () => window.removeEventListener('bns:themechange', onThemeChange);
  }, []);

  // Apply tweak side effects
  React.useEffect(() => {
    document.documentElement.style.setProperty('--c-about', t.accentColor);
    document.getElementById('stars').style.display = t.showStars ? '' : 'none';
    window.setSpotlight?.(t.spotlight);
  }, [t.accentColor, t.showStars, t.spotlight]);

  // Headshot photo mode — persist + broadcast so Portrait components swap
  React.useEffect(() => {
    try { localStorage.setItem('bns-headshot', t.useHeadshot ? '1' : '0'); } catch {}
    window.dispatchEvent(new CustomEvent('bns:headshotchange', { detail: t.useHeadshot }));
  }, [t.useHeadshot]);

  React.useEffect(() => {
    if (!t.soundOn) {
      window.stopRetroAmbience?.();
      return;
    }

    let unlocked = false;
    const unlock = () => {
      unlocked = true;
      window.startRetroAmbience?.();
    };
    const onPointerDown = (e) => {
      if (e.button && e.button !== 0) return;
      window.playUiClick?.();
      if (!unlocked) unlock();
    };
    const onKeyDown = (e) => {
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      if (['Tab', 'Shift', 'Meta', 'Control', 'Alt'].includes(e.key)) return;
      if (!unlocked) unlock();
    };

    window.addEventListener('pointerdown', onPointerDown, true);
    window.addEventListener('keydown', onKeyDown, true);
    return () => {
      window.removeEventListener('pointerdown', onPointerDown, true);
      window.removeEventListener('keydown', onKeyDown, true);
      window.stopRetroAmbience?.();
    };
  }, [t.soundOn]);

  const active = window.SECTIONS.find(s => s.id === activeId);

  // SPA virtual pageviews for GA4 — fire on the picker and each section (skip intro)
  React.useEffect(() => {
    if (stage === 'select') {
      window.bnsTrackPage?.('/picker', "Who's watching? — Batsal Nath Shrestha");
    } else if (stage === 'section' && active) {
      window.bnsTrackPage?.('/' + active.id, active.name + ' — Batsal Nath Shrestha');
    }
  }, [stage, activeId]);

  // Keyboard: Esc closes section; Cmd+K opens search
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape' && stage === 'section' && !cmdOpen) {
        setStage('select'); setActiveId(null);
      }
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setCmdOpen(o => !o);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [stage, cmdOpen]);

  return (
    <>
      {stage === "intro" && (
        theme === 'manga'
          ? <MangaIntro key="manga" onDone={() => setStage("select")} soundOn={t.soundOn} />
          : <Intro key="cinema" onDone={() => setStage("select")} soundOn={t.soundOn} />
      )}
      {stage === "select" && (
        <ProfileSelect
          cardStyle={t.cardStyle}
          promptCopy={t.promptCopy}
          replayIntro={() => setStage("intro")}
          onPick={(id) => { setActiveId(id); setStage("section"); }}
        />
      )}
      {stage === "section" && active && (
        <SectionView
          section={active}
          onBack={() => { setStage("select"); setActiveId(null); }}
          onPickAnother={() => { setStage("select"); setActiveId(null); }}
        />
      )}

      {/* On the profile-select screen the theme toggle is docked in the header instead */}
      {stage !== 'select' && <ThemeToggle/>}

      <CmdK
        open={cmdOpen}
        onClose={() => setCmdOpen(false)}
        onPick={(id) => {
          window.bnsMarkVisited(id);
          setActiveId(id); setStage('section');
        }}
      />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Stage" />
        <TweakToggle label="Skip intro on load" value={t.skipIntro}
          onChange={(v) => { setTweak('skipIntro', v); if (v) setStage('select'); }} />
        <TweakButton label="Replay intro" onClick={() => setStage('intro')}>Play ▶</TweakButton>

        <TweakSection label="Profile cards" />
        <TweakRadio label="Card style" value={t.cardStyle}
          options={['chunky','flat','poster']}
          onChange={(v) => setTweak('cardStyle', v)} />
        <TweakToggle label="Use real photo (About)" value={t.useHeadshot}
          onChange={(v) => setTweak('useHeadshot', v)} />

        <TweakSection label="Theme" />
        <TweakColor label="Primary accent" value={t.accentColor}
          options={['#4f8eff','#ff4d8d','#ffd93d','#22d3ee','#a3e635','#a78bfa']}
          onChange={(v) => setTweak('accentColor', v)} />
        <TweakSection label="Vibe" />
        <TweakToggle label="Sound effects" value={t.soundOn}
          onChange={(v) => setTweak('soundOn', v)} />
        <TweakToggle label="Spotlight cursor" value={t.spotlight}
          onChange={(v) => setTweak('spotlight', v)} />
        <TweakToggle label="Star field background" value={t.showStars}
          onChange={(v) => setTweak('showStars', v)} />

        <TweakSection label="Memory" />
        <TweakButton label="Clear watch history" onClick={() => {
          try { localStorage.removeItem('bns-portfolio-v1'); } catch {}
          if (stage === 'select') { setStage('intro'); setTimeout(() => setStage('select'), 50); }
        }}>Reset</TweakButton>

        <TweakSection label="Copy" />
        <TweakRadio label="Prompt verb" value={t.promptCopy}
          options={['watching','hiring','briefing']}
          onChange={(v) => setTweak('promptCopy', v)} />
      </TweaksPanel>
    </>
  );
}

// Patch ProfileSelect to read the prompt verb from prop — small inline shim
// (no-op; ProfileSelect accepts promptCopy directly)

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