// v2-quiz.jsx — クイズ画面（A案: 一括＋右レール・例文1列）と結果画面
// Exports: QuizScreen, ResultScreen

// 単語ごとに安定したシャッフル（seed = 文字コード和）
function tgv2Shuffle(arr, seedStr) {
  let seed = 0;
  for (let i = 0; i < seedStr.length; i++) seed = (seed * 31 + seedStr.charCodeAt(i)) % 997;
  const a = arr.slice();
  for (let i = a.length - 1; i > 0; i--) {
    seed = (seed * 137 + 71) % 9973;
    const j = seed % (i + 1);
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

// 英文中の対象語を赤くする（got / getting / took などの活用形も対象）
const TGV2_WORD_FORMS = {
  will: ["won't"],
  would: ["wouldn't"],
  get: ["getting", "gotten", "gets", "got"],
  take: ["taking", "taken", "takes", "took"],
};
function tgv2RenderEn(senseEn, word) {
  const fullEn = senseEn.join('');
  const lower = fullEn.toLowerCase();
  const variants = [word.toLowerCase()]
    .concat(TGV2_WORD_FORMS[word] || [])
    .sort((a, b) => b.length - a.length); // 長い形を優先（getting を get より先に）
  let ix = -1, matched = '';
  for (const v of variants) {
    const i = lower.indexOf(v);
    if (i >= 0 && (ix === -1 || i < ix)) { ix = i; matched = fullEn.substring(i, i + v.length); }
  }
  if (ix < 0) return fullEn;
  return (
    <React.Fragment>
      {fullEn.substring(0, ix)}<em>{matched}</em>{fullEn.substring(ix + matched.length)}
    </React.Fragment>
  );
}

// ── クイズ画面 ─────────────────────────────────────────────
// props: queue(単語idx配列), pos, mode('level'|'review'), levelNo, onWordDone(result), onExit
function QuizScreen({ queue, pos, mode, levelNo, format, onWordDone, onExit }) {
  const wordIdx = queue[pos];
  const W = TAGICO_WORDS[wordIdx];
  const n = W.senses.length;

  const pool = React.useMemo(
    () => tgv2Shuffle(W.senses.map(s => s.answer).concat([W.trap]), W.word),
    [wordIdx]
  );

  const [assign, setAssign] = React.useState(Array(n).fill(null)); // senseIdx -> poolIdx
  const [focus, setFocus] = React.useState(0);                      // いま埋めようとしているマス
  const [phase, setPhase] = React.useState('fill');                // fill | checked | revealed
  React.useEffect(() => {
    setAssign(Array(n).fill(null)); setFocus(0); setPhase('fill');
  }, [wordIdx]);

  const usedPool = assign.filter(v => v !== null);
  const allFilled = usedPool.length === n;
  const results = W.senses.map((s, i) => assign[i] !== null && pool[assign[i]] === s.answer);
  const wrongIdxs = W.senses.map((s, i) => i).filter(i => phase === 'checked' && !results[i]);
  const trapUsed = assign.some(v => v !== null && pool[v] === W.trap);

  // start以降で最初の空マス（なければ先頭から探す、全部埋まっていれば null）
  function firstEmpty(arr, start) {
    for (let k = 0; k < n; k++) {
      const i = (start + k) % n;
      if (arr[i] === null) return i;
    }
    return null;
  }

  // 赤いマス（focus）が画面の下のほうに差しかかったときだけ、少しずつ送る
  // （1〜2問目など、まだ十分見えているうちはスクロールしない）
  const cardRefs = React.useRef([]);
  React.useEffect(() => {
    if (phase !== 'fill' || focus === null) return;
    const el = cardRefs.current[focus];
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const vh = window.innerHeight;
    if (rect.bottom > vh * 0.72) {
      // 下に隠れかけ → カードが画面の4割あたりに来る位置まで送る
      const target = window.scrollY + rect.top - vh * 0.38;
      window.scrollTo({ top: Math.max(target, 0), behavior: 'smooth' });
    } else if (rect.top < 120) {
      // 上に隠れかけ（戻ったときなど） → バーの下まで戻す
      const target = window.scrollY + rect.top - 130;
      window.scrollTo({ top: Math.max(target, 0), behavior: 'smooth' });
    }
  }, [focus, phase]);

  // 答え合わせ／答え表示の瞬間は、1文めの結果から見られるようページ先頭へ
  React.useEffect(() => {
    if (phase !== 'checked' && phase !== 'revealed') return;
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }, [phase]);

  function clickChip(pi) {
    if (phase !== 'fill') return;
    if (usedPool.includes(pi)) return;
    if (focus === null || assign[focus] !== null) return;
    const next = assign.slice(); next[focus] = pi;
    setAssign(next);
    setFocus(firstEmpty(next, focus + 1)); // 次の空マスへ自動で進む
  }
  function clickSlot(si) {
    if (phase !== 'fill') return;
    if (assign[si] !== null) {
      const next = assign.slice(); next[si] = null; setAssign(next);
      setFocus(si); // 外したマスをそのまま埋め直す
    } else {
      setFocus(si);
    }
  }
  function check() {
    const wrong = W.senses.map((s, i) => i).filter(i => pool[assign[i]] !== W.senses[i].answer);
    const score = n - wrong.length;
    tgv2.recordWord(W.word, score, n, wrong, trapUsed, mode);
    setPhase('checked');
  }
  function reveal() {
    const next = W.senses.map(s => pool.indexOf(s.answer));
    setAssign(next);
    setPhase('revealed');
  }
  function reset() { setAssign(Array(n).fill(null)); setFocus(0); setPhase('fill'); }

  const dots = queue.map((q, i) => i < pos ? 'done' : i === pos ? 'current' : 'todo');
  const checked = phase === 'checked' || phase === 'revealed';
  const score = results.filter(Boolean).length;

  return (
    <div className="tg-quiz">
      <div className="tg-quizbar">
        <button className="tg-backbtn" onClick={onExit}>← ホーム</button>
        <span className="tg-quizbar-info">
          {mode === 'review' ? '復習' : `Level ${levelNo}`}
          <span className="faint"> · {pos + 1}/{queue.length}語め</span>
        </span>
        <div className="tg-dots">
          {dots.map((d, i) => <span key={i} className={`tg-dot ${d}`}></span>)}
        </div>
      </div>

      <div className="tg-quizgrid">
        {/* 左: 単語 + 例文 */}
        <div>
          <div className="tg-wordhead">
            <span className="tg-bigword">{W.word}</span>
            <span className="tg-wordtask">{n}つの<b>別々の意味</b>で登場 — {format === 'en' ? '英文だけで意味を見抜こう' : '空欄をうめよう'}</span>
          </div>
          <div className="tg-cards">
            {W.senses.map((s, i) => {
              const st = assign[i] === null ? (focus === i ? 'focus' : 'empty')
                : checked ? (results[i] ? 'correct' : 'wrong') : 'filled';
              return (
                <div key={i} className="tg-card" ref={el => { cardRefs.current[i] = el; }} data-comment-anchor={`sense-${W.word}-${i}`}>
                  <span className="tg-card-idx">{String(i + 1).padStart(2, '0')}</span>
                  <p className="tg-card-en">
                    {tgv2RenderEn(s.en, W.word)}
                  </p>
                  {format === 'en' && !checked ? (
                    <p className="tg-card-jp">
                      <span className="enq">この文での意味は？ →</span>
                      <button className={`tg-slot ${st}`} onClick={() => clickSlot(i)}>
                        {assign[i] !== null ? pool[assign[i]] : '？'}
                      </button>
                    </p>
                  ) : (
                    <p className="tg-card-jp">
                      {s.jpBefore}
                      <button className={`tg-slot ${st}`} onClick={() => clickSlot(i)}>
                        {assign[i] !== null ? pool[assign[i]] : '？'}
                      </button>
                      {s.jpAfter}
                      {checked && !results[i] && <span className="tg-fix"> → 正解：{s.answer}</span>}
                    </p>
                  )}
                  {checked && <p className="tg-card-cue">💡 {s.cue}</p>}
                </div>
              );
            })}
          </div>

          {checked && (
            <div className="tg-postcheck">
              {phase === 'checked' && trapUsed && (
                <div className="tg-trapfb">⚠️ 罠「{W.trap}」を使ってしまった！ 今回の{n}文に「{W.trap}」の出番はありません。</div>
              )}
              {phase === 'checked' && !trapUsed && (
                <div className="tg-trapok">✓ 罠「{W.trap}」を回避！</div>
              )}
              <div className="tg-judging">
                <div className="tg-judging-head">
                  <span className="t">用法まとめ</span>
                </div>
                <h2 className="headline">{W.coreImage.headline}</h2>
                <p className="lead">{W.coreImage.lead}</p>
                {TAGICO_JUDGING[W.word] && (
                  <React.Fragment>
                    <div className="tg-faces">
                      {TAGICO_JUDGING[W.word].faces.map((f, i) => (
                        <div key={i} className="tg-face">
                          <span className="f">{'①②③④⑤⑥⑦⑧⑨⑩'[i] || ''}{f.face}</span>
                          <span className="j">{f.jp}</span>
                          <span className="u">
                            {f.pattern && <code className="pat">{f.pattern}</code>}
                            {(f.note || f.use) && <span className="note">{f.note || f.use}</span>}
                          </span>
                        </div>
                      ))}
                    </div>
                    {(TAGICO_JUDGING[W.word].trivia || []).map((tr, i) => (
                      <p key={i} className="tg-trivia" dangerouslySetInnerHTML={{ __html: '✍️ ' + tr }}></p>
                    ))}
                  </React.Fragment>
                )}
              </div>
            </div>
          )}
        </div>

        {/* 右レール: 訳語プール */}
        <div className="tg-rail">
          {!checked ? (
            <React.Fragment>
              <p className="tg-rail-label">{format === 'en' ? '意味プール — 1つは罠' : '訳語プール — 1つは罠'}</p>
              <div className="tg-pool">
                {pool.map((t, pi) => {
                  const st = usedPool.includes(pi) ? 'used' : 'idle';
                  return <button key={pi} className={`tg-chip ${st}`} onClick={() => clickChip(pi)}>{t}</button>;
                })}
              </div>
              {focus !== null && (
                <p className="tg-rail-hint">クリックした{format === 'en' ? '意味' : '訳語'}が <b>赤い空欄（{String(focus + 1).padStart(2, '0')}）</b> に入ります</p>
              )}
              <button className={`tg-btn primary ${allFilled ? '' : 'disabled'}`} disabled={!allFilled} onClick={check}>
                {allFilled ? '答え合わせ' : `答え合わせ（あと${n - usedPool.length}つ）`}
              </button>
              <div className="tg-rail-links">
                <button className="tg-link" onClick={reset}>やり直す</button>
                <button className="tg-link faint" onClick={reveal}>答えを見る</button>
              </div>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <p className="tg-rail-label">{phase === 'revealed' ? '答えを表示中' : '結果'}</p>
              {phase === 'checked' && (
                <div className={`tg-rail-score ${score === n ? 'perfect' : ''}`}>
                  {score === n && <span className="perfect-badge">🎉 全問正解！</span>}
                  <span className="num">{score}<small>/{n}</small></span>
                  <span className="lbl">{score === n ? 'パーフェクト！' : '正解'}</span>
                </div>
              )}
              {phase === 'revealed' && (
                <p className="tg-rail-hint">採点はされません。もう一度自力で挑戦してみよう。</p>
              )}
              <button className="tg-btn primary" onClick={() => onWordDone({ word: W.word, score: phase === 'revealed' ? null : score, total: n, trapUsed: phase === 'checked' ? trapUsed : null })}>
                {pos + 1 < queue.length
                  ? <span>次の単語へ — <em className="next-w">{TAGICO_WORDS[queue[pos + 1]].word}</em> →</span>
                  : '結果を見る →'}
              </button>
              <div className="tg-rail-links">
                <button className="tg-link" onClick={reset}>この単語をやり直す</button>
              </div>
            </React.Fragment>
          )}
        </div>
      </div>
    </div>
  );
}

// ── 結果画面（レベル/復習 完走時） ─────────────────────────────
// props: session { mode, levelNo, results: [{word, score, total, trapUsed}] }, onHome, onRetry, onNextLevel
function ResultScreen({ session, onHome, onRetry, onNextLevel }) {
  const real = session.results.filter(r => r.score !== null);
  const totalScore = real.reduce((a, r) => a + r.score, 0);
  const totalMax = real.reduce((a, r) => a + r.total, 0);
  const trapsAvoided = real.filter(r => r.trapUsed === false).length;
  const st = tgv2.load();
  const streak = tgv2.streak(st.history);
  const pct = totalMax ? totalScore / totalMax : 0;
  const hasNext = session.mode === 'level' && TAGICO_LEVELS.some(l => l.no === session.levelNo + 1);

  return (
    <div className="tg-result">
      <p className="tg-eyebrow">{session.mode === 'review' ? 'review — clear!' : `Level ${session.levelNo} — clear!`}</p>
      <h2 className="tg-result-title">{session.mode === 'review' ? '復習、完走！' : `${session.results.length}語、完走！`}</h2>

      <div className="tg-result-grid">
        <div className="tg-result-left">
          <div className="tg-ring-wrap">
            <svg width="150" height="150" style={{ transform: 'rotate(-90deg)' }}>
              <circle cx="75" cy="75" r="66" fill="none" stroke="var(--vermilion-soft)" strokeWidth="14"></circle>
              <circle cx="75" cy="75" r="66" fill="none" stroke="var(--vermilion)" strokeWidth="14"
                strokeLinecap="round" strokeDasharray={`${2 * Math.PI * 66 * pct} 999`}></circle>
            </svg>
            <div className="tg-ring-center">
              <span className="num">{totalScore}<small>/{totalMax}</small></span>
              <span className="lbl">正解</span>
            </div>
          </div>
          <div className="tg-result-stats">
            <div><b>{trapsAvoided}/{real.length}</b><span>罠を回避</span></div>
            <div><b>🔥 {streak}</b><span>日連続</span></div>
          </div>
        </div>
        <div className="tg-result-rows">
          {session.results.map((r, i) => (
            <div key={i} className="tg-result-row">
              <em className="w">{r.word}</em>
              {r.score === null
                ? <span className="viewed">答えを見た</span>
                : <span className="bar"><span className="fill" style={{ width: `${r.score / r.total * 100}%`, background: r.score === r.total ? 'var(--green)' : 'var(--vermilion)' }}></span></span>}
              {r.score !== null && <span className="sc">{r.score}/{r.total}</span>}
            </div>
          ))}
        </div>
      </div>

      <div className="tg-result-actions">
        {hasNext && <button className="tg-btn primary lg" onClick={onNextLevel}>Level {session.levelNo + 1} へ進む →</button>}
        <div className="row">
          <button className="tg-btn ghost" onClick={onRetry}>もう一度挑戦</button>
          <button className="tg-btn ghost" onClick={onHome}>ホームへ</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { QuizScreen, ResultScreen });
