/* ===== 豆豆的数学 · 主应用 ===== */
const { useState, useEffect, useRef, Fragment } = React;

/* 顶部声音开关 */
function SoundToggle() {
  const [on, setOn] = useState(true);
  return (
    <button className="pill" onClick={() => {
      const v = !on; setOn(v); Sound.voiceOn = v; Sound.enabled = v;
      if (v) { Sound.init(); Sound.pop(); }
    }} style={{ padding:'10px 16px' }}>
      <span style={{ fontSize:22 }}>{on ? '🔔' : '🔕'}</span>
      <span style={{ fontSize:18 }}>{on ? '声音' : '静音'}</span>
    </button>
  );
}

/* ====================== 首页 ====================== */
function Home({ go }) {
  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column' }}>
      <div style={{ display:'flex', justifyContent:'flex-end', padding:'18px 22px' }}><SoundToggle /></div>

      <div style={{ textAlign:'center', marginTop:4 }}>
        <div className="bob" style={{ fontSize:'clamp(56px,11vw,96px)' }}>🦄</div>
        <h1 className="num" style={{ fontFamily:'var(--font-zh)', fontWeight:400, margin:'2px 0 0',
          fontSize:'clamp(40px,8vw,68px)', color:'var(--ink)',
          textShadow:'3px 3px 0 #fff, 6px 6px 0 rgba(255,201,60,.5)' }}>
          豆豆的数学
        </h1>
        <div style={{ fontSize:'clamp(18px,3.4vw,24px)', color:'var(--ink-soft)', marginTop:8 }}>
          <span style={{ margin:'0 6px' }}>🌈</span>一起来玩数学游戏吧<span style={{ margin:'0 6px' }}>⭐</span>
        </div>
      </div>

      <div style={{ flex:1, display:'flex', alignItems:'center', justifyContent:'center', padding:'22px' }}>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:'clamp(16px,3vw,30px)',
          width:'min(760px, 92vw)' }}>
          {ORDER.map((k, i) => {
            const M = MODULES[k];
            return (
              <button key={k} className="card float" onClick={() => { Sound.click(); go({ screen:'picker', module:k }); }}
                style={{ animationDelay: i * 0.4 + 's', cursor:'pointer', border:'5px solid #fff',
                  background:'var(--cream)', padding:'26px 22px', textAlign:'left',
                  display:'flex', alignItems:'center', gap:18 }}>
                <div className="num" style={{ width:84, height:84, flexShrink:0, borderRadius:24,
                  background: M.color, color:'#fff', display:'flex', alignItems:'center', justifyContent:'center',
                  fontSize:54, boxShadow:'inset -5px -6px 0 rgba(0,0,0,.12), inset 5px 5px 0 rgba(255,255,255,.35)' }}>
                  {M.op}
                </div>
                <div>
                  <div className="num" style={{ fontFamily:'var(--font-zh)', fontWeight:400, fontSize:34, color:'var(--ink)' }}>{M.name}</div>
                  <div style={{ fontSize:18, color:'var(--ink-soft)', marginTop:4 }}>{M.tip}</div>
                </div>
              </button>
            );
          })}
        </div>
      </div>
    </div>
  );
}

/* ====================== 模块菜单 ====================== */
function Picker({ module, go }) {
  const M = MODULES[module];
  return (
    <div>
      <Header title={M.name} color={M.color} onBack={() => go({ screen:'home' })} right={<SoundToggle />} />
      <div style={{ display:'flex', flexDirection:'column', alignItems:'center', gap:26, padding:'10px 22px 50px' }}>
        <div className="num wiggle" style={{ width:120, height:120, borderRadius:32, background:M.color, color:'#fff',
          display:'flex', alignItems:'center', justifyContent:'center', fontSize:78,
          boxShadow:'inset -6px -8px 0 rgba(0,0,0,.12), inset 6px 6px 0 rgba(255,255,255,.35)' }}>{M.op}</div>

        <div style={{ display:'flex', gap:22, flexWrap:'wrap', justifyContent:'center', width:'100%', maxWidth:920 }}>
          <ModeCard emoji="🧩" title="学习模式" desc="动手摆一摆,看着答案长出来"
            color="var(--pink)" onClick={() => { Sound.click(); go({ screen:'learn', module }); }} />
          <ModeCard emoji="🎨" title="练习模式" desc="边看图边学,慢慢来,不计分"
            color="var(--mint)" onClick={() => { Sound.click(); go({ screen:'practice', module }); }} />
          <ModeCard emoji="🏆" title="测试模式" desc="选好题量,看看能得几颗星！"
            color="var(--orange)" footer={
              <div style={{ display:'flex', gap:10, marginTop:14 }}>
                <button className="btn num" onClick={(e) => { e.stopPropagation(); Sound.click(); go({ screen:'test', module, count:10 }); }}
                  style={{ background:'var(--orange)', fontSize:22, padding:'12px 20px', borderRadius:18 }}>10 题</button>
                <button className="btn num" onClick={(e) => { e.stopPropagation(); Sound.click(); go({ screen:'test', module, count:20 }); }}
                  style={{ background:'var(--coral)', fontSize:22, padding:'12px 20px', borderRadius:18 }}>20 题</button>
              </div>
            } />
          {module === 'mul' && (
            <ModeCard emoji="📖" title="九九乘法表" desc="点一点,认识每一句口诀"
              color="var(--purple)" onClick={() => { Sound.click(); go({ screen:'table', module }); }} />
          )}
        </div>
      </div>
    </div>
  );
}
function ModeCard({ emoji, title, desc, color, onClick, footer }) {
  return (
    <div className="card" onClick={onClick} style={{ cursor: onClick ? 'pointer':'default', padding:'26px 26px 24px',
      width:'min(330px, 92vw)', borderTop:`8px solid ${color}` }}>
      <div style={{ fontSize:52 }}>{emoji}</div>
      <div className="num" style={{ fontFamily:'var(--font-zh)', fontWeight:400, fontSize:32, color:'var(--ink)', marginTop:6 }}>{title}</div>
      <div style={{ fontSize:18, color:'var(--ink-soft)', marginTop:6, lineHeight:1.4 }}>{desc}</div>
      {footer}
    </div>
  );
}

/* ====================== 题目可视化 ====================== */
function ProblemViz({ p }) {
  if (p.m === 'add') return <AddViz a={p.a} b={p.b} />;
  if (p.m === 'sub') return <SubViz a={p.a} b={p.b} />;
  if (p.m === 'mul') return (
    <div style={{ textAlign:'center' }}>
      <DotArray rows={p.a} cols={p.b} />
      <div className="num" style={{ marginTop:12, fontSize:24, color:'var(--purple)' }}>
        {p.a} 行 × {p.b} 列　·　口诀:{koujue(p.a, p.b)}
      </div>
    </div>
  );
  return (
    <div style={{ textAlign:'center' }}>
      <Grouping total={p.a} groups={p.b} />
      <div className="num" style={{ marginTop:12, fontSize:24, color:'var(--mint)' }}>
        {p.a} 个平均分成 {p.b} 份,每份几个?
      </div>
    </div>
  );
}

/* AI 童趣讲解/鼓励:异步获取后用 TTS 念出,失败则静默(已有静态语音兜底) */
function aiSay({ m, a, b, ans, childAnswer, correct }) {
  if (!window.AIExplain) return;
  AIExplain.get({ a, b, op: m, answer: ans, childAnswer, correct }).then((text) => {
    if (text) Sound.speak(text);
  }).catch(() => {});
}

/* ====================== 练习模式 ====================== */
function Practice({ module, go }) {
  const M = MODULES[module];
  const [p, setP] = useState(() => genProblem(module));
  const [opts, setOpts] = useState(() => makeOptions(p.ans, module));
  const [chosen, setChosen] = useState(null);
  const [tried, setTried] = useState([]);
  const [solvedCount, setSolvedCount] = useState(0);
  const [streak, setStreak] = useState(0);

  useEffect(() => { const t = setTimeout(() => Sound.speak(qSpeech(p), 0.95), 350); return () => clearTimeout(t); }, [p.id]);

  function next() {
    const np = genProblem(module);
    setP(np); setOpts(makeOptions(np.ans, module)); setChosen(null); setTried([]);
  }
  function pick(o) {
    if (chosen === p.ans) return;
    if (window.Mastery) Mastery.record(p, o === p.ans);
    if (o === p.ans) {
      setChosen(o);
      const ns = streak + 1; setStreak(ns); setSolvedCount(c => c + 1);
      Sound.correct(); Sound.praise();
      if (ns % 5 === 0) Celebrate.big(); else { Celebrate.stars(); if (ns % 3 === 0) Celebrate.balloons(6); }
      // 每 3 题用 AI 夸奖一次(控制额度),其余用静态语音
      if (ns % 3 === 0) aiSay({ ...p, childAnswer: o, correct: true });
      setTimeout(next, 1900);
    } else {
      setChosen(o); setStreak(0);
      Sound.wrong(); Sound.encourage();
      // 答错优先用 AI 讲解为什么(更有价值)
      aiSay({ ...p, childAnswer: o, correct: false });
      setTimeout(() => { setTried(t => [...t, o]); setChosen(null); }, 650);
    }
  }

  const solved = chosen === p.ans;
  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column' }}>
      <Header title={`${M.name} · 练习`} color={M.color}
        onBack={() => go({ screen:'picker', module })}
        right={<div style={{ display:'flex', gap:8 }}>
          <div className="pill num" style={{ color:M.color }}>⭐ {solvedCount}</div>
        </div>} />

      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center',
        gap:'clamp(18px,3vh,34px)', padding:'10px 22px 40px' }}>
        <div style={{ display:'flex', alignItems:'center', gap:14 }}>
          <Equation p={p} answer={solved ? p.ans : null} state={solved ? 'right' : ''} />
          <SpeakBtn text={qSpeech(p)} color={M.color} />
          <MicBtn color={M.color} disabled={solved} onResult={(n) => pick(n)} />
        </div>

        <div key={p.id} className="pop-in"><ProblemViz p={p} /></div>

        <Bubbles options={opts} correct={p.ans} chosen={chosen} triedWrong={tried} onPick={pick} />

        {solved && <div className="num pop-in" style={{ fontSize:26, color:'var(--green)' }}>🎉 答对啦,真棒!</div>}
      </div>
    </div>
  );
}

/* ====================== 测试模式 ====================== */
function Test({ module, count, go }) {
  const M = MODULES[module];
  const [probs] = useState(() => Array.from({ length: count }, () => genProblem(module)));
  const [idx, setIdx] = useState(0);
  const [opts, setOpts] = useState(() => makeOptions(probs[0].ans, module));
  const [chosen, setChosen] = useState(null);
  const [results, setResults] = useState([]);
  const [done, setDone] = useState(false);

  const p = probs[idx];
  useEffect(() => { setOpts(makeOptions(p.ans, module)); }, [idx]);

  function pick(o) {
    if (chosen != null) return;
    setChosen(o);
    const ok = o === p.ans;
    if (window.Mastery) Mastery.record(p, ok);
    if (ok) { Sound.correct(); Celebrate.stars(14); } else { Sound.wrong(); aiSay({ ...p, childAnswer: o, correct: false }); }
    const nr = [...results, ok]; setResults(nr);
    setTimeout(() => {
      if (idx + 1 >= count) { setDone(true); }
      else { setIdx(idx + 1); setChosen(null); }
    }, ok ? 850 : 1250);
  }

  if (done) {
    const score = results.filter(Boolean).length;
    return <Result module={module} score={score} total={count} go={go} />;
  }

  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column' }}>
      <Header title={`${M.name} · 测试`} color={M.color}
        onBack={() => go({ screen:'picker', module })}
        right={<div className="pill num" style={{ color:M.color }}>{idx + 1}/{count}</div>} />

      <div style={{ padding:'4px 22px 0' }}><Progress idx={idx} total={count} results={results} /></div>

      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center',
        gap:'clamp(28px,5vh,56px)', padding:'10px 22px 50px' }}>
        <div style={{ display:'flex', alignItems:'center', gap:14 }}>
          <Equation p={p} answer={chosen != null ? (chosen === p.ans ? p.ans : chosen) : null}
            state={chosen == null ? '' : (chosen === p.ans ? 'right' : 'wrong')} />
          <SpeakBtn text={qSpeech(p)} color={M.color} />
          <MicBtn color={M.color} disabled={chosen != null} onResult={(n) => pick(n)} />
        </div>
        <Bubbles options={opts} correct={p.ans} chosen={chosen} revealed={chosen != null} onPick={pick} />
      </div>
    </div>
  );
}

/* ====================== 成绩页 ====================== */
function Result({ module, score, total, go }) {
  const M = MODULES[module];
  const pct = score / total;
  const stars = pct >= 0.9 ? 3 : pct >= 0.7 ? 2 : pct >= 0.5 ? 1 : 0;
  const msg = stars === 3 ? '太完美啦,你是数学小天才！' :
              stars === 2 ? '很棒哦,再加把劲就满分啦！' :
              stars === 1 ? '不错呀,多练习会更厉害！' : '没关系,我们再试一次吧！';
  useEffect(() => {
    const t = setTimeout(() => {
      if (stars >= 1) { Celebrate.big(); Sound.fanfare(); Sound.speak(`你答对了${score}题,${msg}`); }
      else { Sound.speak(msg); }
    }, 300);
    return () => clearTimeout(t);
  }, []);

  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:22, padding:30 }}>
      <div className="bob" style={{ fontSize:90 }}>{stars >= 1 ? '🦄' : '🦄'}</div>
      <div className="card pop-in" style={{ padding:'34px 46px', textAlign:'center', maxWidth:'92vw' }}>
        <div className="num" style={{ fontFamily:'var(--font-zh)', fontWeight:400, fontSize:38, color:M.color }}>{M.name}测试结果</div>
        <div style={{ display:'flex', gap:10, justifyContent:'center', margin:'16px 0', fontSize:58 }}>
          {[0,1,2].map(i => (
            <span key={i} className={i < stars ? 'pop-in' : ''} style={{ animationDelay: i*0.25+'s',
              filter: i < stars ? 'none' : 'grayscale(1)', opacity: i < stars ? 1 : 0.35 }}>⭐</span>
          ))}
        </div>
        <div className="num" style={{ fontSize:52, color:'var(--ink)' }}>
          <span style={{ color:'var(--green)' }}>{score}</span>
          <span style={{ color:'var(--ink-soft)', fontSize:34 }}> / {total}</span>
        </div>
        <div style={{ fontSize:22, color:'var(--ink-soft)', marginTop:10, maxWidth:340 }}>{msg}</div>
        <div style={{ display:'flex', gap:14, justifyContent:'center', marginTop:24, flexWrap:'wrap' }}>
          <button className="btn num" onClick={() => { Sound.click(); go({ screen:'test', module, count:total }); }}
            style={{ background:M.color, fontSize:24, padding:'14px 26px' }}>再来一次</button>
          <button className="btn num" onClick={() => { Sound.click(); go({ screen:'home' }); }}
            style={{ background:'var(--blue)', fontSize:24, padding:'14px 26px' }}>回首页</button>
        </div>
      </div>
    </div>
  );
}

/* ====================== 学习模式(操作台) ====================== */
function LearnScreen({ module, go }) {
  const M = MODULES[module];
  let Pad;
  if (module === 'add') Pad = AddLearn;
  else if (module === 'sub') Pad = SubLearn;
  else if (module === 'mul') Pad = MulLearn;
  else Pad = DivLearn;
  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column' }}>
      <Header title={`${M.name} · 学习`} color={M.color}
        onBack={() => go({ screen:'picker', module })} right={<SoundToggle />} />
      <div style={{ flex:1 }}><Pad /></div>
    </div>
  );
}

/* ====================== 乘法表探索 ====================== */
function TableScreen({ module, go }) {
  return (
    <div style={{ minHeight:'100vh', display:'flex', flexDirection:'column' }}>
      <Header title="九九乘法表" color="var(--purple)"
        onBack={() => go({ screen:'picker', module })} right={<SoundToggle />} />
      <div style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:18, padding:'6px 18px 40px' }}>
        <div style={{ fontSize:20, color:'var(--ink-soft)', textAlign:'center', whiteSpace:'nowrap' }}>👆 点一点任意格子,听一听口诀</div>
        <div className="card" style={{ padding:'clamp(14px,2.5vw,26px)' }}>
          <MultTable />
        </div>
      </div>
    </div>
  );
}

/* ====================== 根组件 ====================== */
function App() {
  const [nav, setNav] = useState(() => {
    try { const s = JSON.parse(localStorage.getItem('doudou_nav') || 'null'); return s || { screen:'home' }; }
    catch (e) { return { screen:'home' }; }
  });
  const go = (n) => { setNav(n); };
  useEffect(() => { window.__go = go; }, []);
  useEffect(() => {
    try { localStorage.setItem('doudou_nav', JSON.stringify(['home','picker','learn'].includes(nav.screen) ? nav : { screen:'home' })); } catch (e) {}
    window.scrollTo(0, 0);
  }, [nav]);

  let view;
  if (nav.screen === 'home') view = <Home go={go} />;
  else if (nav.screen === 'picker') view = <Picker module={nav.module} go={go} />;
  else if (nav.screen === 'practice') view = <Practice key={'pr'+nav.module} module={nav.module} go={go} />;
  else if (nav.screen === 'test') view = <Test key={'te'+nav.module+nav.count+Math.random()} module={nav.module} count={nav.count} go={go} />;
  else if (nav.screen === 'learn') view = <LearnScreen key={'le'+nav.module} module={nav.module} go={go} />;
  else if (nav.screen === 'table') view = <TableScreen module={nav.module} go={go} />;
  else view = <Home go={go} />;

  return <div key={nav.screen + (nav.module||'')} style={{ minHeight:'100vh' }}>{view}</div>;
}

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