const KEY = 'gg-app-state-v2';
const SCREENS = [['welcome', 'Welcome'], ['signup', 'Sign up'], ['code', 'Verify'], ['priorities', 'Priorities'], ['basics', 'Basics'], ['mood', 'Mood'], ['home', 'Home'], ['ride', 'Space Mission', { world: 'space' }], ['ride', 'City Challenge', { world: 'city' }], ['ride', 'Expedition', { world: 'expedition' }], ['ride', 'Speed Race', { world: 'track' }], ['tutorial', 'Practice Demo'], ['session', 'Drill'], ['complete', 'Drill done'], ['profile', 'Profile']];
const fresh = () => ({ screen: 'welcome', ret: null, firstName: '', email: '', isPro: false, voice: true, selectedPriorities: [], selectedMoods: [], calibration: { ageBand: '', gender: '', duration: '' }, completedDrills: [], rideDone: false, world: 'space', largeText: false, highContrast: false, eyesFree: false, haptics: true, skipRobot: false, speech: 'slow', drillId: 'focus_finder', result: { hits: 0, total: 0, best: 0 } });

function LoginSheet({ open, close, s, set, go }) {
  const { Sheet, Button, TextField, Icon } = window.GG;
  const { tone, haptic } = window.GGData;
  const [mode, setMode] = React.useState('face');
  const [scan, setScan] = React.useState(null);
  const [email, setEmail] = React.useState(s.email);
  const name = s.firstName.trim() || 'Feargal';
  const c = scan === 'ok' ? 'var(--gg-domain-composure)' : 'var(--gg-cyan)';
  const faceId = () => { setScan('scan'); tone(600, 'sine', 0.1); setTimeout(() => { setScan('ok'); haptic('correct'); tone(880, 'sine', 0.2); }, 1300); setTimeout(() => { set({ firstName: name }); go('home'); }, 2200); };
  return (
    <Sheet open={open} onClose={close} title="Welcome back">
      {mode === 'face' ? <>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14, padding: '8px 0' }}>
          <span style={{ width: 104, height: 104, borderRadius: 30, display: 'flex', alignItems: 'center', justifyContent: 'center', color: c, border: '3px solid ' + c, boxShadow: '0 0 28px color-mix(in srgb, ' + c + ' 40%, transparent)', animation: scan === 'scan' ? 'gg-pulse 0.8s ease-in-out infinite' : 'none' }}><Icon name={scan === 'ok' ? 'check' : 'face'} size={60} weight={scan === 'ok' ? 700 : 300} /></span>
          <div style={{ fontSize: 19, fontWeight: 800, textAlign: 'center' }}>{scan === 'ok' ? 'Welcome back, ' + name : scan === 'scan' ? 'Looking for you…' : 'No codes. You stay signed in on this phone.'}</div>
        </div>
        <Button icon="face" disabled={!!scan} onClick={faceId}>Sign in with Face ID</Button>
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: -8 }}><QuietLink onClick={() => setMode('email')}>Use an email code instead</QuietLink></div>
      </> : <>
        <p style={{ margin: 0, fontSize: 15, lineHeight: 1.5, color: 'var(--text-muted)' }}>We'll email you a one-time sign-in code.</p>
        <TextField id="login" label="Email address" type="email" value={email} onChange={setEmail} placeholder="you@example.com" />
        <Button onClick={() => { tone(560); set({ email }); go('code'); }}>Send One-Time Code</Button>
        <div style={{ display: 'flex', justifyContent: 'center', marginTop: -8 }}><QuietLink onClick={() => setMode('face')}>Use Face ID instead</QuietLink></div>
      </>}
    </Sheet>
  );
}

function Modals({ modal, close, s, set, go, onToggleMood, onMoodDone }) {
  const { Sheet, Button, TextField, ListRow, Icon, OptionChip } = window.GG;
  const { tone, MOODS } = window.GGData;
  const [email, setEmail] = React.useState(s.email);
  const P = ({ children }) => <p style={{ margin: 0, fontSize: 14, lineHeight: 1.5, color: 'var(--text-muted)' }}>{children}</p>;
  const sarah = <a href="https://www.linkedin.com/in/sarahmcewen/" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--gg-cyan)', fontWeight: 800 }}>Sarah McEwen</a>;
  return <>
    <Sheet open={modal === 'science'} onClose={close} title="Why bike + brain drills?">
      <P><b style={{ color: '#fff' }}>Dual-task neuroplasticity:</b> performing cognitive drills <b style={{ color: '#fff' }}>while your heart rate is elevated</b> on a stationary bike triggers a 3x surge in BDNF (Brain-Derived Neurotrophic Factor) compared to playing stationary.</P>
      <div style={{ borderRadius: 'var(--radius-card)', padding: 16, background: 'linear-gradient(135deg, color-mix(in srgb, var(--gg-cyan) 18%, #0c0e14), #0c0e14)', border: '1px solid color-mix(in srgb, var(--gg-cyan) 35%, transparent)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
        <div><div style={{ fontSize: 15, fontWeight: 800 }}>Flow state acceleration</div><div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 2 }}>Ride time feels 60% faster while engaged</div></div>
        <div style={{ fontSize: 30, fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--gg-cyan)', whiteSpace: 'nowrap' }}>3x <span style={{ fontSize: 14 }}>BDNF</span></div>
      </div>
      <Button icon={null} onClick={close}>Got It</Button>
    </Sheet>
    <Sheet open={modal === 'mood'} onClose={onMoodDone} title="How are you feeling today?">
      <P>Pick up to 2. We'll tune this ride's pace and cue rhythm to match.</P>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        {MOODS.map(m => <OptionChip key={m.id} icon={m.icon} color={m.color} selected={s.selectedMoods.includes(m.id)} onClick={() => onToggleMood(m.id)}>{m.label}</OptionChip>)}
      </div>
      <Button disabled={!s.selectedMoods.length} icon="play_arrow" onClick={onMoodDone}>Start Ride</Button>
      <div style={{ display: 'flex', justifyContent: 'center', marginTop: -8 }}><QuietLink onClick={onMoodDone}>Skip for now</QuietLink></div>
    </Sheet>
    <LoginSheet open={modal === 'login'} close={close} s={s} set={set} go={go} />
    <Sheet open={modal === 'pro'} onClose={close} title="Genius Pro">
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}><span style={{ fontSize: 44, fontWeight: 800, letterSpacing: '-0.03em', fontVariantNumeric: 'tabular-nums' }}>$19.99</span><span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text-muted)' }}>/month or $199/year</span></div>
      <div style={{ fontSize: 17, fontWeight: 800 }}>Elevate your bike brain training</div>
      <div style={{ borderRadius: 'var(--radius-panel)', background: 'var(--surface-card)', border: '1px solid var(--gg-line)', overflow: 'hidden' }}>
        <ListRow icon="all_inclusive" title="Unlimited games" subtitle="Play bike brain drills without daily caps" />
        <div style={{ borderTop: '1px solid var(--gg-line)' }}><ListRow icon="forum" color="var(--gg-domain-composure)" title="WhatsApp community" subtitle="Accountability challenges and live Q&As" /></div>
        <div style={{ borderTop: '1px solid var(--gg-line)', padding: '14px 16px', display: 'flex', gap: 14 }}>
          <span style={{ width: 40, height: 40, flex: 'none', borderRadius: 12, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--gg-domain-memory)', background: 'color-mix(in srgb, var(--gg-domain-memory) 15%, transparent)', border: '1px solid color-mix(in srgb, var(--gg-domain-memory) 30%, transparent)' }}><Icon name="call" size={22} /></span>
          <div><div style={{ fontSize: 15, fontWeight: 700 }}>1-on-1 onboarding call</div><div style={{ fontSize: 12, lineHeight: 1.45, color: 'var(--text-muted)', marginTop: 2 }}>Understand your fitness and cognitive goals with our founder, a Cognitive Psychologist and NSCA-Certified Personal Trainer {sarah}</div></div>
        </div>
      </div>
      <Button onClick={() => { tone(880, 'sine', 0.25); set({ isPro: true, justFinished: false }); window.__ggModal('congrats'); }}>Join Genius Pro</Button>
      <div style={{ textAlign: 'center', fontSize: 12, color: 'var(--text-disabled)', fontWeight: 600 }}>Cancel anytime</div>
    </Sheet>
    <Sheet open={modal === 'congrats'} onClose={close}>
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', gap: 12, paddingTop: 8 }}>
        <span style={{ width: 64, height: 64, borderRadius: '50%', background: 'var(--gg-domain-composure)', color: '#050608', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 28px color-mix(in srgb, var(--gg-domain-composure) 50%, transparent)' }}><Icon name="check" size={34} weight={700} /></span>
        <div style={{ fontSize: 26, fontWeight: 800, letterSpacing: '-0.02em' }}>Welcome to Genius Pro!</div>
        <P>Your membership is now upgraded. You have unlocked unlimited games, VIP WhatsApp community access, and your 1-on-1 introductory onboarding call with founder {sarah}.</P>
      </div>
      <Button icon={null} onClick={close}>Start Riding</Button>
    </Sheet>
  </>;
}

// Screen-state changer: sidebar on desktop, slide-up sheet on mobile.
function ScreenSwitcher({ s, go, reset }) {
  const [open, setOpen] = React.useState(false);
  const jump = (id, extra) => { window.GGData.hush(); go(id, { ret: null, ...(extra || {}) }); setOpen(false); };
  const active = (id, extra) => s.screen === id && (!extra || !extra.world || extra.world === s.world);
  return <>
    <button type="button" className="gg-switch-fab" aria-expanded={open} onClick={() => setOpen(o => !o)}>
      <span className="material-symbols-outlined">{open ? 'close' : 'grid_view'}</span><span>Screens</span>
    </button>
    <div className={'gg-scrim' + (open ? ' is-open' : '')} onClick={() => setOpen(false)}></div>
    <nav className={'gg-switch' + (open ? ' is-open' : '')} aria-label="Jump to screen">
      <div className="gg-switch-head">
        <span className="gg-switch-title">Screens</span>
        <span className="gg-switch-count">{SCREENS.length}</span>
      </div>
      <div className="gg-switch-list">
        {SCREENS.map(([id, label, extra]) => (
          <button key={label} type="button" className={'gg-pill' + (active(id, extra) ? ' is-active' : '')} onClick={() => jump(id, extra)}>{label}</button>
        ))}
      </div>
      <div className="gg-switch-foot">
        <a className="gg-pill gg-pill-link" href="landscape">Landscape gameplay ↗</a>
        <button type="button" className="gg-pill gg-pill-warn" onClick={() => { reset(); setOpen(false); }}>Reset demo</button>
        <button type="button" className="gg-pill gg-pill-quiet" onClick={() => window.__ggLock()}>Lock prototype</button>
      </div>
    </nav>
  </>;
}

function App() {
  const { tone } = window.GGData;
  const [s, setS] = React.useState(() => { try { return { ...fresh(), ...JSON.parse(localStorage.getItem(KEY)) }; } catch (e) { return fresh(); } });
  const [modal, setModal] = React.useState(null);
  const moodAsked = React.useRef(false);
  const pending = React.useRef(null);
  const withMood = fn => { pending.current = fn; setS(x => ({ ...x, selectedMoods: [] })); setModal('mood'); };
  const moodDone = () => { moodAsked.current = true; setModal(null); const fn = pending.current; pending.current = null; fn && fn(); };
  window.__ggModal = setModal;
  React.useEffect(() => { localStorage.setItem(KEY, JSON.stringify(s)); }, [s]);
  const set = p => setS(x => ({ ...x, ...p }));
  window.GGPrefs = { largeText: s.largeText, highContrast: s.highContrast, haptics: s.haptics, skipRobot: s.skipRobot, speech: s.speech, voice: s.voice, ageBand: s.calibration.ageBand, set };
  React.useEffect(() => { const f = e => { if (e.target.closest && e.target.closest('button,[role=button],[role=switch]')) window.GGData.haptic('tap'); }; document.addEventListener('pointerdown', f, true); return () => document.removeEventListener('pointerdown', f, true); }, []);
  const go = (screen, extra = {}) => { setModal(null); setS(x => ({ ...x, screen, ...extra })); };
  const toggleP = id => setS(x => { const c = x.selectedPriorities.slice(); const i = c.indexOf(id); if (i >= 0) c.splice(i, 1); else if (c.length < 3) c.push(id); return { ...x, selectedPriorities: c }; });
  const toggleM = id => { tone(500); setS(x => { const c = x.selectedMoods.slice(); const i = c.indexOf(id); if (i >= 0) c.splice(i, 1); else { if (c.length >= 2) c.shift(); c.push(id); } return { ...x, selectedMoods: c }; }); };
  const tab = t => { tone(450); go(t); };
  const play = id => (!s.isPro && s.completedDrills.length >= 3) ? setModal('pro') : withMood(() => { tone(550); go(s.skipRobot ? 'session' : 'tutorial', { drillId: id, ret: 'home', fromDemo: false }); });
  const ret = s.ret;
  let view;
  switch (s.screen) {
    case 'welcome': view = <Welcome onStart={() => go('signup')} onLogin={() => setModal('login')} onScience={() => setModal('science')} />; break;
    case 'signup': view = <Signup s={s} set={set} onBack={() => go('welcome')} onNext={() => { tone(560); go('code'); }} onLogin={() => setModal('login')} />; break;
    case 'code': view = <VerifyCode email={s.email} onBack={() => go('signup')} onNext={() => go('priorities', { ret: null })} />; break;
    case 'priorities': view = <Priorities selected={s.selectedPriorities} onToggle={toggleP} onReorder={a => set({ selectedPriorities: a })} fromProfile={!!ret} onBack={() => go(ret || 'code', { ret: null })} onContinue={() => go(ret || 'basics', { ret: null })} />; break;
    case 'basics': view = <Basics s={s} set={set} onBack={() => go('priorities')} onNext={() => go('mood')} onSkip={() => go('home')} />; break;
    case 'mood': view = <MoodCheck moods={s.selectedMoods} onToggle={toggleM} onBack={() => go('basics')} onNext={() => { tone(660); go('home'); }} onSkip={() => go('home')} />; break;
    case 'home': view = <Home s={s} onTab={tab} onPlay={play} onRide={() => (s.justFinished && !s.isPro) ? setModal('pro') : withMood(() => { tone(660); go('ride'); })} onEditGoals={() => go('priorities', { ret: 'home' })} onScience={() => setModal('science')} onPro={() => setModal('pro')} />; break;
    case 'ride': view = <BrainRide key={s.world + '-' + (s.rideKey || 0)} worldId={s.world} voice={s.voice} onExit={() => { window.GGData.hush(); setModal(null); setS(x => ({ ...x, screen: 'home', world: x.pendingWorld || x.world, pendingWorld: null })); }} onComplete={stats => setS(x => ({ ...x, rideDone: true, lastRide: stats, justFinished: true, pendingWorld: (id => { const O = window.WORLD_ORDER; return O[(O.indexOf(id) + 1) % O.length]; })(stats.world) }))} onNextWorld={() => { window.GGData.hush(); if (!s.isPro) setModal('pro'); else setS(x => ({ ...x, justFinished: false, world: x.pendingWorld || x.world, pendingWorld: null, rideKey: (x.rideKey || 0) + 1 })); }} />; break;
    case 'tutorial': view = <DrillDemo drillId={s.drillId} onBack={() => go('home')} onPlay={() => { tone(660); go('session', { fromDemo: true }); }} />; break;
    case 'session': view = <Session key={s.drillId} drillId={s.drillId} fromDemo={!!s.fromDemo} voice={s.voice} onEnd={() => go('home')} onFinish={res => setS(x => ({ ...x, screen: 'complete', result: res, completedDrills: x.completedDrills.includes(x.drillId) ? x.completedDrills : [...x.completedDrills, x.drillId] }))} />; break;
    case 'complete': view = <Complete drillId={s.drillId} result={s.result} completed={s.completedDrills} voice={s.voice} onReplay={() => go('session', { fromDemo: false })} onNext={id => go(s.skipRobot ? 'session' : 'tutorial', { drillId: id, fromDemo: false })} onHome={() => { go('home'); if (!s.isPro && s.completedDrills.length >= 3) setTimeout(() => setModal('pro'), 450); }} />; break;
    case 'profile': view = <Profile s={s} set={set} onTab={tab} onTogglePriority={toggleP} onPro={() => setModal('pro')} onLogout={() => { tone(520); setModal(null); setS(fresh()); }} />; break;
    default: view = null;
  }
  return (
    <>
      <div className="gg-stage">
        <div className="gg-device">
          {view}
          <div className="gg-modals" style={{ pointerEvents: modal ? 'auto' : 'none' }}><Modals key={modal || 'none'} modal={modal} close={() => setModal(null)} s={s} set={set} go={go} onToggleMood={toggleM} onMoodDone={moodDone} /></div>
        </div>
      </div>
      <ScreenSwitcher s={s} go={go} reset={() => { setModal(null); setS(fresh()); }} />
    </>
  );
}

window.GGReady.then(() => {
  const root = ReactDOM.createRoot(document.getElementById('root'));
  const boot = () => { root.render(<App />); requestAnimationFrame(() => window.__ggFit && window.__ggFit()); };
  if (window.__ggUnlocked && window.__ggUnlocked()) boot();
  else window.addEventListener('proto:unlocked', boot, { once: true });
});
