// Section 3 専用 App shell — 3×3 ビンゴカード型ダッシュボード
// 各アクティビティの完了状態は localStorage に保存され、ホーム画面のマスにスタンプ表示。
// 1列・1行・対角線が揃うと BINGO 演出が出る。

const S3_STORAGE_KEY = "l1s3_completed_v1";

function loadCompleted() {
  try {
    const raw = localStorage.getItem(S3_STORAGE_KEY);
    return raw ? JSON.parse(raw) : {};
  } catch (e) { return {}; }
}
function saveCompleted(obj) {
  try { localStorage.setItem(S3_STORAGE_KEY, JSON.stringify(obj)); } catch (e) {}
}

// 3×3 配置（中央 index 4 は FREE）
const BINGO_TILES = [
  { key: "reading-mcq",     skill: "Reading",    title: "本文理解",            sub: "選択問題 5問",            cat: "read",    icon: "📖" },
  { key: "scanning",        skill: "Reading",    title: "Scanning",           sub: "語句探し 10問",           cat: "read",    icon: "🔍" },
  { key: "dictation",       skill: "Listening",  title: "Dictation",          sub: "聴取書き取り 4文",        cat: "listen",  icon: "🎧" },
  { key: "listening-cloze", skill: "Listening",  title: "Fill in the Blanks", sub: "空欄埋め 4文",            cat: "listen",  icon: "🎧" },
  { key: "__free",          free: true,          title: "Let's Try!",         sub: "BINGO",                   cat: "free",    icon: "★" },
  { key: "flashcards",      skill: "Vocabulary", title: "Flashcards",         sub: "新出語フラッシュカード", cat: "vocab",   icon: "🗂" },
  { key: "vocab-quiz",      skill: "Vocabulary", title: "Quiz",               sub: "4択クイズ 10問",          cat: "vocab",   icon: "✓" },
  { key: "grammar",         skill: "Grammar",    title: "Key Grammar",        sub: "解説 + 練習 5問",         cat: "grammar", icon: "𝑮" },
  { key: "writing",         skill: "Writing",    title: "Composition",        sub: "作文 3プロンプト",        cat: "write",   icon: "✍️" },
];

// マスのクリア状態（free は常に true 扱い）から BINGO ライン判定
function getBingoLines(completed) {
  // 9 マスを 0..8 で配列化
  const cells = BINGO_TILES.map((t, i) => i === 4 ? true : !!completed[t.key]);
  const lines = [
    [0,1,2],[3,4,5],[6,7,8], // rows
    [0,3,6],[1,4,7],[2,5,8], // cols
    [0,4,8],[2,4,6],         // diagonals
  ];
  const wonLines = lines.filter(L => L.every(i => cells[i]));
  const wonCells = new Set();
  wonLines.forEach(L => L.forEach(i => wonCells.add(i)));
  return { wonLines, wonCells, cells };
}

function Dashboard({ onPick, meta, completed, onReset }) {
  const { wonLines, wonCells } = getBingoLines(completed);
  const cleared = BINGO_TILES.filter(t => !t.free && completed[t.key]).length;
  const hasBingo = wonLines.length > 0;

  return (
    <div className="dash">
      <div className="dash-hero">
        <div className="hero-eyebrow">ENGLISH COMMUNICATION Ⅱ · SELF-STUDY</div>
        <h1 className="hero-title">{meta.lesson} · {meta.title}</h1>
        <div className="hero-section">{meta.section} — {meta.subtitle}</div>
        <p className="hero-lede">
          ビンゴカード形式。9マス中の好きなアクティビティから取り組もう。中央の <b>Let's Try!</b> はフリースペース。
          1列・1行・対角線を全部クリアして <b>BINGO</b> を狙ってみよう。
        </p>
        <div className="progress-row">
          <div className="progress-stat">
            <span className="ps-num">{cleared}</span><span className="ps-den">/ 8</span>
            <span className="ps-label">クリア</span>
          </div>
          <div className="progress-stat">
            <span className="ps-num">{wonLines.length}</span>
            <span className="ps-label">BINGO ライン</span>
          </div>
          {cleared > 0 && (
            <button className="reset-btn" onClick={onReset} title="進捗をリセット">↻ リセット</button>
          )}
        </div>
      </div>

      <div className={"bingo-grid" + (hasBingo ? " has-bingo" : "")}>
        {BINGO_TILES.map((t, i) => {
          const isWon = wonCells.has(i);
          if (t.free) {
            return (
              <div key={t.key} className={"tile tile-free" + (isWon ? " is-won" : "")} aria-label="Free space">
                <div className="free-stamp">FREE</div>
                <div className="free-title">{t.title}</div>
                <div className="free-sub">{t.sub}</div>
                <div className="free-deco">★</div>
              </div>
            );
          }
          const done = !!completed[t.key];
          return (
            <button
              key={t.key}
              className={"tile tile-" + t.cat + (done ? " is-done" : "") + (isWon ? " is-won" : "")}
              onClick={() => onPick(t.key)}
            >
              <div className="tile-top">
                <span className="tile-skill">{t.skill}</span>
                <span className="tile-icon">{t.icon}</span>
              </div>
              <div className="tile-title">{t.title}</div>
              <div className="tile-sub">{t.sub}</div>
              <div className="tile-go">{done ? "もう一度 ↻" : "Start →"}</div>
              {done && <div className="done-stamp" aria-label="Cleared">CLEAR</div>}
            </button>
          );
        })}
      </div>

      {hasBingo && (
        <div className="bingo-banner">
          <div className="bingo-banner-title">🎉 BINGO!</div>
          <div className="bingo-banner-sub">{wonLines.length} ライン達成 — Great work!</div>
        </div>
      )}

      <div className="dash-footer">
        英コミュニケーションⅡ · {meta.lesson} · {meta.section} · Self-Study Hub
      </div>
    </div>
  );
}

function App() {
  const [route, setRoute] = useState("dashboard");
  const [completed, setCompleted] = useState(loadCompleted);
  const [confirmReset, setConfirmReset] = useState(false);
  const data = window.L1_DATA;
  const meta = data.meta;

  // activities.jsx から呼び出されるグローバルフック
  React.useEffect(() => {
    window.__markActivityComplete = (key) => {
      setCompleted(prev => {
        if (prev[key]) return prev;
        const next = { ...prev, [key]: Date.now() };
        saveCompleted(next);
        return next;
      });
    };
    return () => { delete window.__markActivityComplete; };
  }, []);

  const exit = () => setRoute("dashboard");
  const reset = () => setConfirmReset(true);
  const doReset = () => {
    saveCompleted({});
    setCompleted({});
    setConfirmReset(false);
  };

  let view;
  if (route === "dashboard") view = <Dashboard onPick={setRoute} meta={meta} completed={completed} onReset={reset} />;
  else if (route === "reading-mcq") view = <ReadingMCQ data={data} onExit={exit} />;
  else if (route === "scanning") view = <Scanning data={data} onExit={exit} />;
  else if (route === "dictation") view = <Dictation data={data} onExit={exit} />;
  else if (route === "listening-cloze") view = <ListeningCloze data={data} onExit={exit} />;
  else if (route === "flashcards") view = <Flashcards data={data} onExit={exit} />;
  else if (route === "vocab-quiz") view = <VocabQuiz data={data} onExit={exit} />;
  else if (route === "grammar") view = <Grammar data={data} onExit={exit} />;
  else if (route === "writing") view = <Writing data={data} onExit={exit} />;

  return (
    <div className="app">
      {route !== "dashboard" && (
        <div className="topbar">
          <button className="back-btn" onClick={exit}>← ダッシュボード</button>
          <div className="topbar-meta">{meta.lesson} · {meta.section}</div>
        </div>
      )}
      {view}
      {confirmReset && (
        <div className="reset-modal-bg" onClick={() => setConfirmReset(false)}>
          <div className="reset-modal" onClick={e => e.stopPropagation()}>
            <div className="reset-modal-title">進捗をリセットしますか？</div>
            <div className="reset-modal-msg">ビンゴカードのクリア状況がすべて消えます。</div>
            <div className="reset-modal-btns">
              <button className="reset-modal-cancel" onClick={() => setConfirmReset(false)}>キャンセル</button>
              <button className="reset-modal-ok" onClick={doReset}>リセットする</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
