// screens.jsx — core screens (Onboarding, Home, Player, Drill, Complete, Profile, Settings).

// ─── ONBOARDING ─────────────────────────────────────────────
function OnboardingScreen({ theme, mascotOn, nav }) {
  const [page, setPage] = React.useState(0);
  const pages = [
    { head: 'HI! I’M\nCHOPSTICK.',     sub: 'I’ll teach you Mandarin — sounds, words, and your first sentences. No textbooks, just vibes.', mood: 'happy' },
    { head: 'PINYIN IS\nTHE SOUND-KEY.', sub: 'Start with the four tones, then a handful of initials & finals. Characters come later.', mood: 'idle' },
    { head: 'AI TUTOR\nINCLUDED.',     sub: 'Plug in an OpenRouter key and chat with me in real Chinese. Translation grading too.', mood: 'wow' },
    { head: 'STREAKS.\nCOINS. WINS.',  sub: 'Every lesson earns XP. Beat your high score. Don’t break the chain.', mood: 'excited' },
  ];
  const p = pages[page];

  return (
    <Screen theme={theme} scroll={false} style={{ padding: '78px 22px 32px' }}>
      <div style={{ position: 'absolute', top: 80, right: 18,
        ...stampStyle(theme, theme.primary),
        background: theme.surface, color: theme.primary,
        fontSize: 10, transform: 'rotate(8deg)',
      }}>v1.0 BETA</div>

      <button onClick={() => nav('home', { onboarded: true })} style={{
        position: 'absolute', top: 78, left: 22,
        background: 'transparent', border: 0, color: theme.fgMute,
        fontFamily: theme.fontBody, fontSize: 12, letterSpacing: '0.1em',
        textTransform: 'uppercase', cursor: 'pointer', zIndex: 5,
      }}>SKIP →</button>

      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 20, paddingTop: 20, position: 'relative' }}>
        {mascotOn && <Mascot theme={theme} mood={p.mood} size={130} />}
        <H theme={theme} size={40} align="center" style={{ whiteSpace: 'pre-line', lineHeight: 1 }}>{p.head}</H>
        <div style={{ fontFamily: theme.fontBody, fontSize: 14, lineHeight: 1.45, color: theme.fgMute, textAlign: 'center', maxWidth: 280 }}>
          {p.sub}
        </div>
        <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
          {pages.map((_, i) => (
            <div key={i} style={{
              width: i === page ? 20 : 8, height: 8,
              background: i === page ? theme.primary : theme.fgDim,
              border: `1.5px solid ${theme.fg}`,
              borderRadius: 999, transition: 'width .2s',
            }} />
          ))}
        </div>
      </div>

      <div style={{ display: 'flex', gap: 10, position: 'relative' }}>
        {page > 0 && (
          <RetroBtn theme={theme} variant="ghost" onClick={() => setPage(page - 1)} style={{ flex: 1 }}>BACK</RetroBtn>
        )}
        {page < pages.length - 1 ? (
          <RetroBtn theme={theme} variant="primary" onClick={() => setPage(page + 1)} style={{ flex: page === 0 ? 1 : 1.5 }}>NEXT →</RetroBtn>
        ) : (
          <RetroBtn theme={theme} variant="primary" onClick={() => nav('home', { onboarded: true })} style={{ flex: 1.5 }}>LET’S GO →</RetroBtn>
        )}
      </div>
    </Screen>
  );
}

// ─── HOME ───────────────────────────────────────────────────
function HomeScreen({ theme, mascotOn, progress, nav, onTab }) {
  const units = lessonsByUnit();
  const [scrollRef, onScroll] = useScrollMemory('home');

  // What to suggest playing next.
  const resume = progress.lastPlayed
    ? LESSONS.find((l) => l.id === progress.lastPlayed && !progress.completedLessons.includes(l.id))
    : null;
  const upNext = !resume ? nextLesson(progress) : null;

  return (
    <Screen theme={theme}>
      <div style={{ padding: '54px 16px 12px' }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 12 }}>
          <div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, letterSpacing: '0.15em', color: theme.fgMute, textTransform: 'uppercase' }}>
              NĬ HǍO ↓
            </div>
            <H theme={theme} size={34} style={{ marginTop: 4 }}>CHOPSTICK</H>
            <div style={{
              width: 100, height: 6,
              background: `repeating-linear-gradient(90deg, ${theme.primary} 0 8px, transparent 8px 12px)`,
              marginTop: 4,
            }} />
          </div>
          {mascotOn && (
            <button onClick={() => onTab('tutor')} style={{
              all: 'unset', cursor: 'pointer', transform: 'rotate(-6deg)',
            }}>
              <Mascot theme={theme} mood="happy" size={70} />
            </button>
          )}
        </div>
        <ScoreBar theme={theme} progress={progress} />
      </div>

      <div ref={scrollRef} onScroll={onScroll}
           style={{ flex: 1, overflowY: 'auto', padding: '8px 16px 16px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        {/* Resume / Next-up pill — sits prominently above other CTAs */}
        {(resume || upNext) && (
          <button onClick={() => nav('player', { lessonId: (resume || upNext).id })} style={{
            all: 'unset', cursor: 'pointer',
            background: theme.green, color: theme.mode === 'dark' ? '#0d0d10' : theme.fg,
            border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
            padding: '14px 16px',
            boxShadow: `0 4px 0 0 ${theme.fg}`,
            display: 'flex', alignItems: 'center', gap: 14,
          }}>
            <div style={{ fontSize: 30, lineHeight: 1 }}>{resume ? '▶' : '✨'}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: theme.fontBody, fontSize: 10, letterSpacing: '0.15em', textTransform: 'uppercase', opacity: 0.85 }}>
                {resume ? 'RESUME' : 'UP NEXT'}
              </div>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, lineHeight: 1, marginTop: 2 }}>
                {(resume || upNext).title}
              </div>
              <div style={{ fontFamily: theme.fontBody, fontSize: 11, marginTop: 4, opacity: 0.85, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {(resume || upNext).subtitle}
              </div>
            </div>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 22 }}>→</div>
          </button>
        )}

        {/* AI tutor entry */}
        <button onClick={() => onTab('tutor')} style={{
          all: 'unset', cursor: 'pointer',
          background: theme.primary, color: theme.mode === 'dark' ? '#fff' : theme.fg,
          border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
          padding: '14px 16px',
          boxShadow: `0 4px 0 0 ${theme.yellow}`,
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <Sparkle theme={theme} size={32} color={theme.yellow}/>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, lineHeight: 1 }}>ASK CHOPSTICK</div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, opacity: 0.85, marginTop: 4 }}>
              AI tutor · ask anything in English or Chinese
            </div>
          </div>
          <div style={{ fontFamily: theme.fontDisplay, fontSize: 20 }}>→</div>
        </button>

        {/* Role-play entry */}
        <button onClick={() => nav('roleplay')} style={{
          all: 'unset', cursor: 'pointer',
          background: theme.cyan, color: theme.mode === 'dark' ? '#0d0d10' : theme.fg,
          border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
          padding: '14px 16px',
          boxShadow: `0 4px 0 0 ${theme.primary}`,
          display: 'flex', alignItems: 'center', gap: 14,
        }}>
          <div style={{ fontSize: 32, lineHeight: 1 }}>🎭</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, lineHeight: 1 }}>ROLE-PLAY</div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, opacity: 0.85, marginTop: 4 }}>
              Order food · ride a taxi · meet people — in character, in Chinese
            </div>
          </div>
          <div style={{ fontFamily: theme.fontDisplay, fontSize: 20 }}>→</div>
        </button>

        {units.map((u) => (
          <div key={u.unit}>
            <div style={{
              fontFamily: theme.fontHead, fontSize: 12,
              letterSpacing: '0.18em', color: theme.fgMute,
              textTransform: 'uppercase', margin: '6px 2px 8px',
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <span style={{ color: theme.primary }}>★</span>
              UNIT {u.unit} · {u.name}
              <div style={{ flex: 1, height: 2, borderTop: `2px dashed ${theme.fgDim}` }}/>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {u.lessons.map((l) => (
                <LessonCard key={l.id} theme={theme} lesson={l}
                  stars={progress.lessonStars[l.id] || 0}
                  done={progress.completedLessons.includes(l.id)}
                  recent={progress.lastPlayed === l.id}
                  onPlay={() => nav('player', { lessonId: l.id })}
                />
              ))}
            </div>
          </div>
        ))}
        <div style={{ height: 8 }} />
      </div>

      <TabBar theme={theme} tab="home" onTab={onTab} />
    </Screen>
  );
}

function LessonCard({ theme, lesson, stars, done, recent, onPlay }) {
  const accentMap = { primary: theme.primary, cyan: theme.cyan, yellow: theme.yellow, red: theme.red };
  const accent = accentMap[lesson.color] || theme.primary;
  const locked = lesson.locked;

  return (
    <button onClick={locked ? undefined : onPlay} disabled={locked} style={{
      all: 'unset', cursor: locked ? 'not-allowed' : 'pointer',
      background: theme.surface, color: theme.fg,
      border: `2px solid ${theme.fg}`,
      borderRadius: theme.radius,
      padding: 12,
      boxShadow: `0 3px 0 0 ${accent}`,
      display: 'flex', alignItems: 'center', gap: 12,
      opacity: locked ? 0.5 : 1,
      position: 'relative',
    }}>
      <div style={{
        width: 54, height: 54, background: accent,
        border: `2px solid ${theme.fg}`, borderRadius: theme.radius * 0.6,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        flexShrink: 0, color: theme.mode === 'dark' ? '#0d0d10' : theme.fg,
      }}>
        {lesson.icon === 'tone' && (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 2 }}>
            {[0,1,2,3].map(t => <ToneCurve key={t} tone={t} theme={theme} size={18} color={theme.fg}/>)}
          </div>
        )}
        {lesson.icon === 'initial' && <Pinyin theme={theme} size={26} color={theme.fg} style={{ fontWeight: 900 }}>bp</Pinyin>}
        {lesson.icon === 'final'   && <Pinyin theme={theme} size={26} color={theme.fg} style={{ fontWeight: 900 }}>āo</Pinyin>}
        {lesson.icon === 'chat'    && <span style={{ fontSize: 26, lineHeight: 1 }}>💬</span>}
        {lesson.icon === 'num'     && <span style={{ fontFamily: theme.fontDisplay, fontSize: 22 }}>123</span>}
        {lesson.icon === 'people'  && <span style={{ fontSize: 28, lineHeight: 1 }}>👨‍👩‍👧</span>}
        {lesson.icon === 'food'    && <span style={{ fontSize: 28, lineHeight: 1 }}>🍜</span>}
        {lesson.icon === 'color'   && (
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 2 }}>
            <div style={{ width: 10, height: 10, background: '#e8553c', border: `1.5px solid ${theme.fg}` }}/>
            <div style={{ width: 10, height: 10, background: '#f5b82e', border: `1.5px solid ${theme.fg}` }}/>
            <div style={{ width: 10, height: 10, background: '#2a52be', border: `1.5px solid ${theme.fg}` }}/>
            <div style={{ width: 10, height: 10, background: '#3a7d44', border: `1.5px solid ${theme.fg}` }}/>
          </div>
        )}
        {lesson.icon === 'verb'    && <span style={{ fontFamily: theme.fontCN, fontSize: 26 }}>动</span>}
        {lesson.icon === 'qm'      && <span style={{ fontFamily: theme.fontCN, fontSize: 26 }}>吗</span>}
        {lesson.icon === 'star'    && <Star theme={theme} size={28}/>}
      </div>

      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
          <div style={{ fontFamily: theme.fontDisplay, fontSize: 18, lineHeight: 1 }}>{lesson.title}</div>
          {recent && (
            <span style={{
              fontFamily: theme.fontBody, fontSize: 9, fontWeight: 700,
              color: theme.bg, background: theme.green,
              border: `1.5px solid ${theme.fg}`, padding: '1px 5px',
              borderRadius: 999, letterSpacing: '0.08em', textTransform: 'uppercase',
            }}>RESUME</span>
          )}
        </div>
        <div style={{
          fontFamily: theme.fontBody, fontSize: 11,
          color: theme.fgMute, marginTop: 4, lineHeight: 1.35,
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
        }}>{lesson.subtitle}</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 6 }}>
          <StarRow theme={theme} count={done ? (stars || 3) : 0} size={14} />
          <span style={{ fontFamily: theme.fontBody, fontSize: 10, color: theme.fgMute }}>
            +{lesson.xp}XP · +{lesson.coins} <Coin theme={theme} size={10}/>
          </span>
        </div>
      </div>

      {locked ? (
        <svg width="22" height="22" viewBox="0 0 24 24" style={{ flexShrink: 0 }}>
          <rect x="5" y="11" width="14" height="10" rx="2" stroke={theme.fg} strokeWidth="2" fill={theme.bgAlt}/>
          <path d="M8 11 L8 7 Q 8 3 12 3 Q 16 3 16 7 L 16 11" stroke={theme.fg} strokeWidth="2" fill="none"/>
        </svg>
      ) : (
        <div style={{
          width: 32, height: 32, background: theme.fg, color: theme.surface,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          borderRadius: 999, flexShrink: 0, fontFamily: theme.fontDisplay,
        }}>▶</div>
      )}
    </button>
  );
}

// ─── LESSON PLAYER ──────────────────────────────────────────
function LessonPlayerScreen({ theme, mascotOn, progress, nav, params, onLessonComplete }) {
  const lesson = LESSONS.find((l) => l.id === params.lessonId) || LESSONS[0];
  const [exIdx, setExIdx] = React.useState(0);
  const [picked, setPicked] = React.useState(null);
  const [feedback, setFeedback] = React.useState(null);     // 'right'|'wrong'|null
  const [hearts, setHearts] = React.useState(3);
  const [score, setScore] = React.useState(0);
  const [info, setInfo] = React.useState(null);
  const [grading, setGrading] = React.useState(false);
  const [external, setExternal] = React.useState({});       // free-form state per exercise

  const ex = lesson.exercises[exIdx];

  // Reset per-exercise state when stepping forward.
  React.useEffect(() => {
    setPicked(null); setFeedback(null); setInfo(null); setExternal({});
  }, [exIdx]);

  const advance = (right) => {
    if (right) setScore((s) => s + 100);
    if (exIdx + 1 >= lesson.exercises.length) {
      const finalScore = score + (right ? 100 : 0);
      onLessonComplete?.({ lesson, score: finalScore, hearts });
      nav('complete', { lessonId: lesson.id, score: finalScore, perfect: hearts === 3 });
    } else {
      setExIdx(exIdx + 1);
    }
  };

  const check = async () => {
    if (picked == null && !isDisplayOnly(ex.kind)) return;
    setGrading(true);
    try {
      const { right, info } = await gradeExercise(ex, picked, external, setExternal);
      setFeedback(right ? 'right' : 'wrong');
      setInfo(info || null);
      if (!right) setHearts((h) => Math.max(0, h - 1));
      blip(right ? 'right' : 'wrong');
      haptic(right ? 'right' : 'wrong');
    } finally {
      setGrading(false);
    }
  };

  return (
    <Screen theme={theme} scroll={false} style={{ padding: '54px 16px 0' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
        <button onClick={() => nav('home')} style={{
          width: 32, height: 32, background: theme.surface, color: theme.fg,
          border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
          fontSize: 18, lineHeight: 0, cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: theme.fontDisplay,
        }}>×</button>
        <div style={{ flex: 1 }}>
          <Bar theme={theme} value={exIdx + (feedback ? 1 : 0)} max={lesson.exercises.length} />
        </div>
        <div style={{ display: 'flex', gap: 2 }}>
          {[0,1,2].map((i) => (
            <span key={i} style={{ opacity: i < hearts ? 1 : 0.25, filter: i < hearts ? 'none' : 'grayscale(1)' }}>
              <Flame theme={theme} size={18}/>
            </span>
          ))}
        </div>
      </div>

      <div style={{
        fontFamily: theme.fontBody, fontSize: 11, letterSpacing: '0.12em',
        color: theme.fgMute, textTransform: 'uppercase',
      }}>{lesson.title} · {exIdx + 1}/{lesson.exercises.length}</div>

      <div style={{ flex: 1, overflowY: 'auto', marginTop: 8, paddingBottom: 14 }}>
        <ExerciseBody theme={theme} mascotOn={mascotOn} ex={ex}
          picked={picked} setPicked={setPicked} feedback={feedback}
          externalState={external} setExternal={setExternal}
        />
      </div>

      <div style={{
        margin: '0 -16px',
        padding: '14px 16px 32px',
        background: feedback === 'right' ? theme.green : feedback === 'wrong' ? theme.red : 'transparent',
        borderTop: feedback ? `2px solid ${theme.fg}` : 'none',
        transition: 'background .2s',
      }}>
        {feedback ? (
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ flex: 1, color: theme.mode === 'dark' && feedback === 'wrong' ? '#fff' : theme.fg }}>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 18 }}>
                {feedback === 'right' ? 'YESSS!' : 'NOT QUITE'}
              </div>
              <div style={{ fontFamily: theme.fontBody, fontSize: 12, opacity: 0.9 }}>
                {info || (feedback === 'right' ? '+100 score' : (ex.options && Array.isArray(ex.options) ? `Answer: ${(ex.options[ex.answer]?.cn || ex.options[ex.answer]) ?? '—'}` : 'Try again next round.'))}
              </div>
            </div>
            <RetroBtn theme={theme} variant={feedback === 'right' ? 'success' : 'danger'} onClick={() => advance(feedback === 'right')}>
              CONTINUE →
            </RetroBtn>
          </div>
        ) : isDisplayOnly(ex.kind) ? (
          <RetroBtn theme={theme} variant="primary" onClick={() => advance(true)} style={{ width: '100%' }}>
            CONTINUE →
          </RetroBtn>
        ) : (
          <RetroBtn theme={theme} variant="primary" onClick={check}
            disabled={
              ex.kind !== 'speak' && (
                grading ||
                picked == null ||
                picked === '' ||
                // Arrange-incomplete: chips not all placed yet
                (ex.kind === 'arrange' && Array.isArray(picked) && picked.length < (ex.words?.length || 0))
              )
            }
            style={{ width: '100%' }}>
            {grading ? <><Spinner theme={theme}/> CHECKING…</> : 'CHECK'}
          </RetroBtn>
        )}
      </div>
    </Screen>
  );
}

// ─── DRILL ──────────────────────────────────────────────────
function DrillScreen({ theme, mascotOn, progress, nav, onTab }) {
  const [active, setActive] = React.useState(null);
  const [combo, setCombo] = React.useState(0);

  const tones = [
    { mark: 'ā', tone: 0, label: 'TONE 1', desc: 'FLAT' },
    { mark: 'á', tone: 1, label: 'TONE 2', desc: 'RISE' },
    { mark: 'ǎ', tone: 2, label: 'TONE 3', desc: 'DIP' },
    { mark: 'à', tone: 3, label: 'TONE 4', desc: 'FALL' },
  ];

  const onTone = (i) => {
    setActive(i); setCombo((c) => c + 1);
    primeSpeech(); speakZh(tones[i].mark);
    setTimeout(() => setActive(null), 250);
  };

  return (
    <Screen theme={theme}>
      <div style={{ padding: '54px 16px 4px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 8 }}>
          <div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, letterSpacing: '0.15em', color: theme.fgMute, textTransform: 'uppercase' }}>
              DRILL MODE
            </div>
            <H theme={theme} size={32}>TONE GYM</H>
          </div>
          <div style={{
            ...stampStyle(theme, theme.primary),
            color: theme.primary, background: theme.surface,
            transform: 'rotate(-4deg)', fontSize: 11,
          }}>COMBO × {combo}</div>
        </div>
        <div style={{ fontFamily: theme.fontBody, fontSize: 12, color: theme.fgMute, lineHeight: 1.45, marginTop: 4 }}>
          Tap each tone to hear it. Build your ear before the quiz.
        </div>
      </div>

      <div style={{ flex: 1, padding: '12px 16px', display: 'flex', flexDirection: 'column', gap: 10 }}>
        {tones.map((t, i) => (
          <button key={i} onClick={() => onTone(i)} style={{
            all: 'unset', cursor: 'pointer',
            background: active === i ? theme.primary : theme.surface,
            color: theme.fg,
            border: `2.5px solid ${theme.fg}`, borderRadius: theme.radius,
            padding: '16px 18px',
            display: 'flex', alignItems: 'center', gap: 16,
            boxShadow: active === i ? '' : `0 5px 0 0 ${[theme.primary, theme.cyan, theme.yellow, theme.green][i]}`,
            transform: active === i ? 'translateY(3px)' : '',
            transition: 'all .12s',
          }}>
            <Pinyin theme={theme} size={56} color={active === i && theme.mode === 'dark' ? '#fff' : theme.primary}>{t.mark}</Pinyin>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 18 }}>{t.label}</div>
              <div style={{ fontFamily: theme.fontBody, fontSize: 11, color: active === i ? 'inherit' : theme.fgMute, letterSpacing: '0.14em', marginTop: 2 }}>
                {t.desc}
              </div>
            </div>
            <ToneCurve tone={i} theme={theme} size={42} color={active === i && theme.mode === 'dark' ? '#fff' : theme.cyan} />
            <Speaker theme={theme} size={22} color={active === i ? 'inherit' : theme.fgMute}/>
          </button>
        ))}

        <div style={{ marginTop: 4, display: 'flex', gap: 10 }}>
          <RetroBtn theme={theme} variant="yellow" onClick={() => nav('player', { lessonId: 'tones-101' })} style={{ flex: 1 }}>
            QUIZ ME →
          </RetroBtn>
        </div>
      </div>

      <TabBar theme={theme} tab="drill" onTab={onTab}/>
    </Screen>
  );
}

// ─── COMPLETE ───────────────────────────────────────────────
function CompleteScreen({ theme, mascotOn, progress, nav, params }) {
  const lesson = LESSONS.find((l) => l.id === params.lessonId) || LESSONS[0];
  const score = params.score || 800;
  const stars = score >= Math.max(700, lesson.exercises.length * 80) ? 3 : score >= 400 ? 2 : 1;
  // Next lesson the user hasn't completed (start search AFTER the one just played).
  const upNext = nextLesson(progress, lesson.id);

  return (
    <Screen theme={theme} scroll={false} style={{ padding: '54px 22px 32px' }}>
      <div style={{
        position: 'absolute', inset: 0, opacity: 0.13, pointerEvents: 'none',
        backgroundImage: `repeating-linear-gradient(45deg, ${theme.primary} 0 4px, transparent 4px 24px), repeating-linear-gradient(-45deg, ${theme.cyan} 0 4px, transparent 4px 24px)`,
      }}/>

      <div style={{ position: 'relative', flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-start', gap: 14, paddingTop: 10 }}>
        <div style={{ ...stampStyle(theme, theme.primary), color: theme.primary, fontSize: 11, transform: 'rotate(-6deg)' }}>
          LESSON CLEAR!
        </div>
        <H theme={theme} size={46} align="center" style={{ lineHeight: 0.95 }}>NICE!</H>
        {mascotOn && <Mascot theme={theme} mood="excited" size={130} />}
        <div style={{ fontFamily: theme.fontBody, fontSize: 12, color: theme.fgMute, textTransform: 'uppercase', letterSpacing: '0.14em' }}>
          {lesson.title.toUpperCase()}
        </div>
        <StarRow theme={theme} count={stars} size={32}/>

        <Card theme={theme} padded={false} style={{ width: '100%', padding: 14, marginTop: 4 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `2px dashed ${theme.fgDim}`, paddingBottom: 8, marginBottom: 8 }}>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, color: theme.fgMute, textTransform: 'uppercase', letterSpacing: '0.14em' }}>SCORE</div>
            <div style={{ fontFamily: theme.fontDisplay, fontSize: 30, color: theme.primary, fontVariantNumeric: 'tabular-nums' }}>
              {String(score).padStart(5, '0')}
            </div>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <div style={{ textAlign: 'center', flex: 1 }}>
              <div style={{ fontFamily: theme.fontBody, fontSize: 10, color: theme.fgMute, textTransform: 'uppercase', letterSpacing: '0.14em' }}>XP</div>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 26, color: theme.fg }}>+{lesson.xp}</div>
            </div>
            <div style={{ width: 1, background: theme.fgDim }}/>
            <div style={{ textAlign: 'center', flex: 1 }}>
              <div style={{ fontFamily: theme.fontBody, fontSize: 10, color: theme.fgMute, textTransform: 'uppercase', letterSpacing: '0.14em' }}>COINS</div>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 26, color: theme.fg }}>+{lesson.coins}</div>
            </div>
            <div style={{ width: 1, background: theme.fgDim }}/>
            <div style={{ textAlign: 'center', flex: 1 }}>
              <div style={{ fontFamily: theme.fontBody, fontSize: 10, color: theme.fgMute, textTransform: 'uppercase', letterSpacing: '0.14em' }}>STREAK</div>
              <div style={{ fontFamily: theme.fontDisplay, fontSize: 26, color: theme.red, display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                <Flame theme={theme} size={16}/>+1
              </div>
            </div>
          </div>
        </Card>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10, position: 'relative' }}>
        {upNext && (
          <RetroBtn theme={theme} variant="primary" onClick={() => nav('player', { lessonId: upNext.id })} style={{ width: '100%' }}>
            NEXT: {upNext.title.toUpperCase()} →
          </RetroBtn>
        )}
        <div style={{ display: 'flex', gap: 10 }}>
          <RetroBtn theme={theme} variant="ghost" onClick={() => nav('player', { lessonId: lesson.id })} style={{ flex: 1 }}>REDO</RetroBtn>
          <RetroBtn theme={theme} variant={upNext ? 'surface' : 'primary'} onClick={() => nav('home')} style={{ flex: 1 }}>HOME</RetroBtn>
        </div>
      </div>
    </Screen>
  );
}

// ─── PROFILE ────────────────────────────────────────────────
function ProfileScreen({ theme, mascotOn, progress, nav, onTab }) {
  const totalLessons = LESSONS.length;
  const doneCount = progress.completedLessons.length;
  const achievements = [
    { label: 'FIRST BLOOD',  desc: 'Finish your first lesson',    done: doneCount > 0 },
    { label: 'TONE TAMER',   desc: 'Master the 4 tones',          done: progress.lessonStars['tones-101'] >= 3 },
    { label: '3 DAY CHAIN',  desc: 'Hit a 3-day streak',          done: progress.streak >= 3 },
    { label: 'PERFECT',      desc: '3-star a lesson',             done: Object.values(progress.lessonStars).some((s) => s >= 3) },
    { label: 'BILINGUAL',    desc: 'Finish all of Unit 2',        done: ['greetings','numbers-0-10'].every((id) => progress.completedLessons.includes(id)) },
    { label: '100 COINS',    desc: 'Earn 100 coins',              done: progress.coins >= 100 },
  ];

  return (
    <Screen theme={theme}>
      <div style={{
        padding: '54px 16px 16px',
        background: `${halftone(theme.yellow, 1.5, 6)}, linear-gradient(135deg, ${theme.surface} 0%, ${theme.surfaceAlt} 100%)`,
        borderBottom: `2px solid ${theme.fg}`,
        position: 'relative',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          {mascotOn && (
            <div style={{
              background: theme.surface, padding: 4,
              border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
              boxShadow: `0 4px 0 0 ${theme.fg}`,
            }}>
              <Mascot theme={theme} mood="happy" size={68}/>
            </div>
          )}
          <div style={{ flex: 1 }}>
            <div style={{
              fontFamily: theme.fontBody, fontSize: 10, color: theme.fg,
              letterSpacing: '0.18em', textTransform: 'uppercase',
              background: theme.bg, display: 'inline-block', padding: '2px 6px',
              border: `1.5px solid ${theme.fg}`,
            }}>{`LEVEL ${Math.floor(progress.xp / 50) + 1} · ${progress.xp >= 200 ? 'PRACTITIONER' : 'APPRENTICE'}`}</div>
            <H theme={theme} size={26} style={{ marginTop: 4 }}>YOUR PAGE</H>
          </div>
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          <BigStat theme={theme} label="HI SCORE"  value={String(progress.highScore)} accent={theme.primary} icon={<Star theme={theme} size={14}/>}/>
          <BigStat theme={theme} label="STREAK"    value={progress.streak + 'd'}      accent={theme.red}     icon={<Flame theme={theme} size={14}/>}/>
          <BigStat theme={theme} label="TOTAL XP"  value={progress.xp}                accent={theme.cyan}/>
          <BigStat theme={theme} label="COINS"     value={progress.coins}             accent={theme.yellow}  icon={<Coin theme={theme} size={14}/>}/>
        </div>

        <Card theme={theme} padded={false} style={{ padding: 14 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
            <div style={{ fontFamily: theme.fontHead, fontSize: 13, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
              ★ THIS WEEK
            </div>
            <div style={{ fontFamily: theme.fontBody, fontSize: 11, color: theme.fgMute }}>{progress.streak}/7 days</div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7,1fr)', gap: 4 }}>
            {['M','T','W','T','F','S','S'].map((d, i) => {
              const done = i < progress.streak;
              const today = i === progress.streak;
              return (
                <div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
                  <div style={{ fontFamily: theme.fontBody, fontSize: 10, fontWeight: 700, color: theme.fgMute }}>{d}</div>
                  <div style={{
                    width: '100%', aspectRatio: '1', maxWidth: 32,
                    background: done ? theme.primary : today ? theme.yellow : theme.surfaceAlt,
                    border: `2px solid ${theme.fg}`,
                    borderRadius: theme.radius * 0.6,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: theme.fontDisplay, fontSize: 14, color: theme.fg,
                  }}>{done && <Flame theme={theme} size={14}/>}{today && !done && '·'}</div>
                </div>
              );
            })}
          </div>
        </Card>

        <Card theme={theme} padded={false} style={{ padding: 14 }}>
          <div style={{ fontFamily: theme.fontHead, fontSize: 13, letterSpacing: '0.1em', textTransform: 'uppercase', marginBottom: 8 }}>
            ★ LESSON PROGRESS
          </div>
          <div style={{ fontFamily: theme.fontBody, fontSize: 12, color: theme.fgMute, marginBottom: 8 }}>
            {doneCount} / {totalLessons} lessons cleared
          </div>
          <Bar theme={theme} value={doneCount} max={totalLessons} height={10}/>
        </Card>

        <div>
          <div style={{
            fontFamily: theme.fontHead, fontSize: 13, letterSpacing: '0.12em',
            textTransform: 'uppercase', color: theme.fgMute,
            marginBottom: 8, padding: '0 2px',
          }}>★ STICKERS</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            {achievements.map((a, i) => (
              <div key={i} style={{
                background: a.done ? theme.surface : theme.surfaceAlt,
                border: `2px ${a.done ? 'solid' : 'dashed'} ${theme.fg}`,
                borderRadius: theme.radius,
                padding: 10,
                opacity: a.done ? 1 : 0.55,
                boxShadow: a.done ? `0 3px 0 0 ${theme.primary}` : 'none',
                transform: a.done ? `rotate(${[-2,1.5,-1,2,-1.5,1][i]}deg)` : 'none',
              }}>
                <div style={{ fontFamily: theme.fontDisplay, fontSize: 14, color: a.done ? theme.primary : theme.fgDim, lineHeight: 1.1 }}>
                  {a.label}
                </div>
                <div style={{ fontFamily: theme.fontBody, fontSize: 10, color: theme.fgMute, marginTop: 3, lineHeight: 1.3 }}>
                  {a.desc}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <TabBar theme={theme} tab="profile" onTab={onTab}/>
    </Screen>
  );
}

function BigStat({ theme, label, value, accent, icon }) {
  return (
    <div style={{
      background: theme.surface, border: `2px solid ${theme.fg}`,
      borderRadius: theme.radius, padding: 10,
      boxShadow: `0 3px 0 0 ${accent}`,
    }}>
      <div style={{
        fontFamily: theme.fontHead, fontSize: 11, letterSpacing: '0.12em',
        color: theme.fgMute, textTransform: 'uppercase',
        display: 'flex', alignItems: 'center', gap: 4,
      }}>{icon}{label}</div>
      <div style={{
        fontFamily: theme.fontDisplay, fontSize: 28,
        color: accent || theme.fg, lineHeight: 1, marginTop: 4,
        fontVariantNumeric: 'tabular-nums',
      }}>{value}</div>
    </div>
  );
}

// ─── SETTINGS ───────────────────────────────────────────────
function SettingsScreen({ theme, mascotOn, nav, onTab, onReset, settings, setSettings, themeKey, setThemeKey }) {
  const [keyDraft, setKeyDraft] = React.useState(orGetKey());
  const [modelDraft, setModelDraft] = React.useState(orGetModel());
  const [keySaved, setKeySaved] = React.useState(false);
  const [proxyState, setProxyState] = React.useState({ checked: false, available: false, hasKey: false });

  // Probe the server proxy on mount.
  React.useEffect(() => {
    let cancelled = false;
    orProxyAvailable().then((available) => {
      if (cancelled) return;
      setProxyState({ checked: true, available, hasKey: orProxyHasKey() });
    });
    return () => { cancelled = true; };
  }, []);

  const saveKey = () => {
    orSetKey(keyDraft.trim());
    orSetModel(modelDraft);
    setKeySaved(true);
    setTimeout(() => setKeySaved(false), 1500);
  };

  return (
    <Screen theme={theme}>
      <div style={{ padding: '54px 16px 12px' }}>
        <div style={{ fontFamily: theme.fontBody, fontSize: 11, letterSpacing: '0.15em', color: theme.fgMute, textTransform: 'uppercase' }}>
          DIAL IT IN
        </div>
        <H theme={theme} size={32}>SETTINGS</H>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', padding: '6px 16px 16px', display: 'flex', flexDirection: 'column', gap: 14 }}>
        <SettingGroup theme={theme} title="APPEARANCE">
          <SettingRow theme={theme} label="Theme" desc="Pick your palette"
            right={<Seg theme={theme} value={themeKey === 'risoDark' ? 'DARK' : 'LIGHT'} options={['LIGHT','DARK']} onChange={(v) => setThemeKey(v === 'DARK' ? 'risoDark' : 'risoLight')}/>}
            stacked
          />
          <SettingRow theme={theme} label="Mascot" desc="Show Chopstick around the app"
            right={<Switch theme={theme} on={settings.mascot} onChange={(v) => setSettings({ ...settings, mascot: v })}/>}/>
        </SettingGroup>

        <SettingGroup theme={theme} title="AI TUTOR (OpenRouter)">
          <SettingRow theme={theme} label="Connection"
            desc={
              !proxyState.checked ? 'checking…' :
              proxyState.available && proxyState.hasKey ? 'Server proxy active — your key stays server-side. ✓' :
              proxyState.available && !proxyState.hasKey ? 'Server proxy deployed but missing OPENROUTER_API_KEY.' :
              'No server proxy — using direct mode (BYOK). Claude blocked from browser.'
            }
            right={
              <div style={{
                fontFamily: theme.fontHead, fontSize: 11, fontWeight: 700,
                background: proxyState.available && proxyState.hasKey ? theme.green : theme.yellow,
                color: theme.fg, border: `2px solid ${theme.fg}`,
                padding: '4px 8px', borderRadius: 999,
                letterSpacing: '0.08em', textTransform: 'uppercase',
              }}>{proxyState.available && proxyState.hasKey ? 'PROXY' : 'DIRECT'}</div>
            }
          />
          <SettingRow theme={theme} label="API key (direct mode only)"
            desc={proxyState.available && proxyState.hasKey
              ? 'Not needed — the deployed proxy holds the key.'
              : 'Paste your sk-or-… key. Stays in this browser. Skip if using the proxy.'}
            stacked
            right={
              <div style={{ display: 'flex', gap: 6, width: '100%' }}>
                <input type="password" value={keyDraft} onChange={(e) => setKeyDraft(e.target.value)}
                  placeholder="sk-or-…"
                  style={{
                    flex: 1, fontFamily: theme.fontBody, fontSize: 13,
                    padding: '10px 12px', background: theme.surface, color: theme.fg,
                    border: `2px solid ${theme.fg}`, borderRadius: theme.radius * 0.7,
                    outline: 'none',
                  }}/>
                <RetroBtn theme={theme} size="md" variant={keySaved ? 'success' : 'primary'} onClick={saveKey}>
                  {keySaved ? 'SAVED' : 'SAVE'}
                </RetroBtn>
              </div>
            }
          />
          <SettingRow theme={theme} label="Model" desc="Cheap models are usually fine"
            stacked
            right={
              <select value={modelDraft} onChange={(e) => { setModelDraft(e.target.value); orSetModel(e.target.value); }}
                style={{
                  width: '100%', fontFamily: theme.fontBody, fontSize: 13,
                  padding: '10px 12px', background: theme.surface, color: theme.fg,
                  border: `2px solid ${theme.fg}`, borderRadius: theme.radius * 0.7,
                  outline: 'none',
                }}>
                {MODEL_CHOICES.map((m) => <option key={m.id} value={m.id}>{m.label}</option>)}
              </select>
            }
          />
          <SettingRow theme={theme} label="Get a key" desc="openrouter.ai — sign up & top up $5"
            right={
              <a href="https://openrouter.ai/keys" target="_blank" rel="noreferrer"
                 style={{ color: theme.primary, fontFamily: theme.fontHead, fontSize: 13, fontWeight: 700, letterSpacing: '0.06em' }}>
                OPEN ↗
              </a>
            }
          />
        </SettingGroup>

        <SettingGroup theme={theme} title="SOUND & FEEDBACK">
          <SettingRow theme={theme} label="Sound effects" desc="Bleeps & blops on every tap"
            right={<Switch theme={theme} on={settings.sound} onChange={(v) => setSettings({ ...settings, sound: v })}/>}/>
          <SettingRow theme={theme} label="Haptics" desc="Buzz on correct / wrong"
            right={<Switch theme={theme} on={settings.haptics} onChange={(v) => setSettings({ ...settings, haptics: v })}/>}/>
          <SettingRow theme={theme} label="Voice speed" desc="How fast TTS plays back"
            right={<Seg theme={theme} value={settings.speed} options={['SLOW','NORMAL','FAST']} onChange={(v) => setSettings({ ...settings, speed: v })}/>}
            stacked
          />
        </SettingGroup>

        <SettingGroup theme={theme} title="PROGRESS">
          <SettingRow theme={theme} label="Reset progress" desc="Wipe XP, coins, streak"
            danger
            right={<RetroBtn theme={theme} variant="danger" size="md" onClick={onReset}>RESET</RetroBtn>}/>
        </SettingGroup>

        <SettingGroup theme={theme} title="ABOUT">
          <SettingRow theme={theme} label="Version" desc="Chopstick v1.0 BETA"
            right={<span style={{ fontFamily: theme.fontBody, color: theme.fgMute, fontSize: 13 }}>1.0.0</span>}/>
          <SettingRow theme={theme} label="Made with 🥢" desc="Pinyin first. Characters next. AI when needed." right={null}/>
        </SettingGroup>

        <div style={{ height: 4 }} />
      </div>

      <TabBar theme={theme} tab="settings" onTab={onTab}/>
    </Screen>
  );
}

function SettingGroup({ theme, title, children }) {
  const arr = React.Children.toArray(children);
  return (
    <div>
      <div style={{
        fontFamily: theme.fontHead, fontSize: 12, letterSpacing: '0.16em',
        color: theme.fgMute, textTransform: 'uppercase',
        padding: '0 2px 6px',
      }}>{title}</div>
      <Card theme={theme} padded={false} style={{ padding: 0, overflow: 'hidden' }}>
        {arr.map((c, i) => (
          <React.Fragment key={i}>
            {c}
            {i < arr.length - 1 && <div style={{ height: 1, background: theme.fgDim, margin: '0 14px' }}/>}
          </React.Fragment>
        ))}
      </Card>
    </div>
  );
}

function SettingRow({ theme, label, desc, right, danger, stacked }) {
  return (
    <div style={{
      padding: '12px 14px',
      display: 'flex', alignItems: stacked ? 'flex-start' : 'center',
      flexDirection: stacked ? 'column' : 'row',
      gap: stacked ? 10 : 12,
    }}>
      <div style={{ flex: 1, alignSelf: 'stretch' }}>
        <div style={{
          fontFamily: theme.fontHead, fontSize: 14, fontWeight: 700,
          color: danger ? theme.red : theme.fg,
        }}>{label}</div>
        <div style={{ fontFamily: theme.fontBody, fontSize: 11, color: theme.fgMute, marginTop: 2 }}>
          {desc}
        </div>
      </div>
      {right && <div style={{ width: stacked ? '100%' : 'auto' }}>{right}</div>}
    </div>
  );
}

function Switch({ theme, on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} style={{
      all: 'unset', cursor: 'pointer',
      width: 48, height: 28,
      background: on ? theme.green : theme.surfaceAlt,
      border: `2px solid ${theme.fg}`,
      borderRadius: 999, position: 'relative',
      transition: 'background .2s',
    }}>
      <div style={{
        position: 'absolute', top: 2, left: on ? 22 : 2,
        width: 20, height: 20,
        background: theme.fg, borderRadius: '50%',
        transition: 'left .2s',
      }}/>
    </button>
  );
}

function Seg({ theme, value, options, onChange }) {
  return (
    <div style={{
      display: 'flex',
      border: `2px solid ${theme.fg}`, borderRadius: theme.radius,
      background: theme.surfaceAlt, width: '100%', overflow: 'hidden',
    }}>
      {options.map((opt) => (
        <button key={opt} onClick={() => onChange(opt)} style={{
          all: 'unset', cursor: 'pointer',
          flex: 1, textAlign: 'center', padding: '8px 4px',
          fontFamily: theme.fontHead, fontSize: 11, fontWeight: 700,
          letterSpacing: '0.06em',
          background: value === opt ? theme.primary : 'transparent',
          color: value === opt && theme.mode === 'dark' ? '#fff' : theme.fg,
          borderRight: opt === options[options.length-1] ? 'none' : `1.5px solid ${theme.fg}`,
        }}>{opt}</button>
      ))}
    </div>
  );
}

Object.assign(window, {
  OnboardingScreen, HomeScreen, LessonCard, LessonPlayerScreen,
  DrillScreen, CompleteScreen, ProfileScreen, SettingsScreen,
  BigStat, SettingGroup, SettingRow, Switch, Seg,
});
