/* global React, ReactDOM, QUIZ_DATA */
const { useState, useEffect, useRef, useMemo } = React;

/* =========================================================================
   STORAGE
   ========================================================================= */
const STORAGE_KEY = "smaglo_quiz_v1";

function loadState() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return { history: [], unlocked: {} };
    const parsed = JSON.parse(raw);
    return {
      history: parsed.history || [],
      unlocked: parsed.unlocked || {},
    };
  } catch (e) {
    return { history: [], unlocked: {} };
  }
}
function saveState(s) {
  try { localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); } catch(e) {}
}

const PASS_THRESHOLD = 0.7; // 70% to pass a level

function isUnlocked(state, lang, level) {
  const langData = QUIZ_DATA[lang];
  const idx = langData.levels.indexOf(level);
  if (idx === 0) return true;
  const prev = langData.levels[idx - 1];
  const key = `${lang}:${prev}`;
  return !!(state.unlocked[key] && state.unlocked[key].passed);
}
function bestScore(state, lang, level) {
  const matches = state.history.filter(h => h.lang === lang && h.level === level);
  if (matches.length === 0) return null;
  return Math.max(...matches.map(h => h.pct));
}
function levelCongrats(level) {
  const map = {
    A1: ["A1 пройден 🎉", "База уверенно в кармане. Ты уже можешь представиться, заказать кофе и спросить дорогу. Пора к A2."],
    A2: ["A2 пройден 🎉", "Можешь поддержать бытовой разговор и рассказать о себе. Время переходить к B1 — здесь начинается настоящий язык."],
    B1: ["B1 пройден 🎉", "Ты свободнее, чем думаешь. Понимаешь фильмы, ведёшь переписку, путешествуешь один. Впереди B2 — академический уровень."],
    B2: ["B2 пройден 🎉", "Это уровень, с которого говорят «я знаю язык». Доступны экзамены FCE/DELF и серьёзная работа на иностранном."],
    C1: ["C1 пройден 🎉", "Advanced. Ты уверенно работаешь, учишься и ведёшь переговоры. Остаётся C2 — noble level."],
    C2: ["C2 пройден 🎉", "Mastery. Тебя не отличить от носителя. Дальше — только шлифовка и удовольствие от языка."],
    HSK1: ["HSK 1 пройден 🎉", "150 базовых слов и простые фразы. Ты сделал первый шаг — и это сложнее всего. Вперёд к HSK 2."],
    HSK2: ["HSK 2 пройден 🎉", "300 слов, можешь вести простые разговоры. Китайский перестал быть «непонятными иероглифами»."],
    HSK3: ["HSK 3 пройден 🎉", "600 слов. Ты уверенно читаешь, пишешь и понимаешь на слух базовые темы. Middle level unlocked."],
    HSK4: ["HSK 4 пройден 🎉", "1200 слов. Можешь работать и учиться на китайском. Следующий уровень — уже серьёзная академическая планка."],
    HSK5: ["HSK 5 пройден 🎉", "2500 слов. Свободно читаешь газеты, смотришь фильмы, ведёшь переговоры. Впереди — HSK 6, вершина."],
    HSK6: ["HSK 6 пройден 🎉", "5000+ слов. Носитель тебе не ровня, а друг. Mastery level."],
  };
  return map[level] || [`${level} пройден 🎉`, "Отличная работа. Ты продвигаешься."];
}

/* =========================================================================
   UTILS
   ========================================================================= */
function shuffle(arr) {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}
function pickQuestions(lang, level, n = 10) {
  const pool = QUIZ_DATA[lang].questions[level] || [];
  return shuffle(pool).slice(0, Math.min(n, pool.length)).map((q, i) => ({ ...q, _i: i }));
}
function formatDate(ts) {
  const d = new Date(ts);
  const dd = String(d.getDate()).padStart(2, "0");
  const mm = String(d.getMonth() + 1).padStart(2, "0");
  return `${dd}.${mm} · ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
}

/* =========================================================================
   CONFETTI
   ========================================================================= */
function fireConfetti() {
  const layer = document.getElementById("confettiLayer");
  if (!layer) return;
  const colors = ["#FF2E88", "#00E5FF", "#B794FF", "#FFE66B"];
  const count = 80;
  for (let i = 0; i < count; i++) {
    const p = document.createElement("span");
    p.className = "confetti-piece";
    const x = 50 + (Math.random() - 0.5) * 30; // near center horizontally
    const dx = (Math.random() - 0.5) * 800;
    const r = 360 + Math.random() * 720;
    p.style.left = x + "vw";
    p.style.top = "40vh";
    p.style.background = colors[i % colors.length];
    p.style.borderRadius = Math.random() > 0.5 ? "50%" : "2px";
    p.style.setProperty("--dx", dx + "px");
    p.style.setProperty("--r", r + "deg");
    p.style.animationDelay = (Math.random() * 0.15) + "s";
    layer.appendChild(p);
    setTimeout(() => p.remove(), 2000);
  }
}

/* =========================================================================
   SUBTLE CURSOR TRAIL (copied from main site)
   ========================================================================= */
function useCursorTrail() {
  useEffect(() => {
    const layer = document.getElementById("cursorTrail");
    let lastX = 0, lastY = 0, lastT = 0;
    const onMove = (e) => {
      const now = performance.now();
      const dx = e.clientX - lastX, dy = e.clientY - lastY;
      const dist = Math.hypot(dx, dy);
      if (now - lastT < 28 || dist < 14) return;
      lastX = e.clientX; lastY = e.clientY; lastT = now;
      if (!layer) return;
      const p = document.createElement("span");
      p.className = "trail-dot";
      p.style.left = e.clientX + "px";
      p.style.top = e.clientY + "px";
      layer.appendChild(p);
      setTimeout(() => p.remove(), 900);
    };
    window.addEventListener("mousemove", onMove);
    return () => window.removeEventListener("mousemove", onMove);
  }, []);
}

/* =========================================================================
   SCREENS
   ========================================================================= */
const LANG_GREETINGS = {
  en: { word: "Hello", label: "English", meta: "CEFR · A1 → C2" },
  fr: { word: "Bonjour", label: "Français", meta: "CEFR · A1 → C2" },
  zh: { word: "你好", label: "中文", meta: "HSK 1 → HSK 6" },
  mix: { word: "Hello · Bonjour · 你好", label: "Все языки", meta: "Микс · A1 → C2" },
};

function Home({ state, onPick }) {
  const totalAttempts = state.history.length;
  const langs = ["en", "fr", "zh", "mix"];
  return (
    <>
      <div className="qhero">
        <div className="qhero__eyebrow">
          <span>Q · 01</span>
          <span className="line"></span>
          <span><b>quiz.system</b> / v1.0</span>
          <span className="line"></span>
          <span>SMAGLO · 2026</span>
        </div>
        <h1 className="qhero__title">
          Проверь свой <span className="grad">уровень</span> <br />
          за <span className="outline">10</span> вопросов.
        </h1>
        <p className="qhero__lead">
          Выбери язык — и начни с самого простого. Прошёл уровень на 70%+ — откроется следующий. Прогресс сохраняется локально в браузере.
        </p>

        <div className="lang-grid">
          {langs.map((lang, i) => {
            const g = LANG_GREETINGS[lang];
            return (
              <button
                key={lang}
                className={`lang-card ${lang === "mix" ? "lang-card--mix" : ""}`}
                onClick={() => onPick(lang)}
              >
                <div className="lang-card__id">
                  <span><b>{String(i+1).padStart(2,"0")}</b> / {String(langs.length).padStart(2,"0")}</span>
                  <span>{lang.toUpperCase()}</span>
                </div>
                <div>
                  <div className="lang-card__word">{g.word}</div>
                  <div className="lang-card__label">{g.label}</div>
                  <div className="lang-card__meta">{g.meta}</div>
                </div>
              </button>
            );
          })}
        </div>
      </div>

      {totalAttempts > 0 && <History state={state} onWipe={() => {
        if (confirm("Удалить всю историю попыток?")) {
          saveState({ history: [], unlocked: {} });
          window.location.reload();
        }
      }} />}
    </>
  );
}

function LevelPicker({ lang, state, onBack, onStart }) {
  const data = QUIZ_DATA[lang];
  const g = LANG_GREETINGS[lang];
  return (
    <div className="qhero">
      <div className="qhero__eyebrow">
        <span>Q · 02</span>
        <span className="line"></span>
        <span><b>select.level</b> / {data.system}</span>
        <span className="line"></span>
        <button className="qgame__back" onClick={onBack}>← назад</button>
      </div>
      <h1 className="qhero__title">
        {g.word === "你好" ? <span className="grad">你好</span> : g.word === "Bonjour" ? <span className="grad">Bonjour</span> : g.word === "Hello" ? <span className="grad">Hello</span> : <span className="grad">Mix</span>}
      </h1>
      <p className="qhero__lead">
        Выбери уровень. Начни с самого простого — следующие откроются, когда ты пройдёшь предыдущий на 70%+.
      </p>

      <div className="levels">
        {data.levels.map((level, idx) => {
          const unlocked = isUnlocked(state, lang, level);
          const key = `${lang}:${level}`;
          const passed = state.unlocked[key] && state.unlocked[key].passed;
          const best = bestScore(state, lang, level);
          return (
            <button
              key={level}
              className={`level-card ${unlocked ? "" : "locked"}`}
              onClick={() => unlocked && onStart(lang, level)}
              disabled={!unlocked}
            >
              <div className="level-card__top">
                <span>{String(idx+1).padStart(2,"0")} / {String(data.levels.length).padStart(2,"0")}</span>
                {passed ? (
                  <span className="level-card__badge level-card__badge--passed">пройден</span>
                ) : unlocked ? (
                  <span className="level-card__badge level-card__badge--current">доступен</span>
                ) : (
                  <span className="level-card__badge level-card__badge--locked">🔒 заблокирован</span>
                )}
              </div>
              <div className="level-card__code">{level}</div>
              <div className="level-card__name">{levelName(level)}</div>
              {best !== null && (
                <div className="level-card__best">
                  <span>best</span>
                  <span><b>{Math.round(best * 100)}%</b></span>
                </div>
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}

function levelName(level) {
  const map = {
    A1: "Начальный",
    A2: "Элементарный",
    B1: "Средний",
    B2: "Средне-продвинутый",
    C1: "Продвинутый",
    C2: "Мастер",
    HSK1: "150 слов, база",
    HSK2: "300 слов, быт",
    HSK3: "600 слов, разговор",
    HSK4: "1200 слов, работа",
    HSK5: "2500 слов, свобода",
    HSK6: "5000+ слов, мастерство",
  };
  return map[level] || "";
}

function Game({ lang, level, state, onBack, onFinish }) {
  const [questions] = useState(() => pickQuestions(lang, level, 10));
  const [idx, setIdx] = useState(0);
  const [selected, setSelected] = useState(null);
  const [answers, setAnswers] = useState([]); // { correct: bool, type }
  const [streak, setStreak] = useState(0);

  const q = questions[idx];
  const total = questions.length;
  const progress = (idx + (selected !== null ? 1 : 0)) / total;

  if (!q) return null;

  const pick = (optIdx) => {
    if (selected !== null) return;
    setSelected(optIdx);
    const isRight = optIdx === q.correct;
    setAnswers(a => [...a, { correct: isRight, type: q.type }]);
    if (isRight) {
      setStreak(s => s + 1);
    } else {
      setStreak(0);
    }
    // auto-advance
    const delay = isRight ? 900 : 1800;
    setTimeout(() => {
      setAnswers(curr => {
        // use latest answers at fire time
        if (idx + 1 >= total) {
          const correct = curr.filter(a => a.correct).length;
          const pct = correct / total;
          onFinish({
            lang, level, pct,
            correct, total,
            answers: [...curr],
            ts: Date.now(),
          });
        } else {
          setIdx(i => i + 1);
          setSelected(null);
        }
        return curr;
      });
    }, delay);
  };

  const typeLabel = {
    translate: "перевод",
    image: "картинка",
    fill: "пропуск",
    idiom: "идиома",
    grammar: "грамматика",
  }[q.type] || q.type;

  const isImageOptions = q.type === "image";

  return (
    <div className="qgame">
      <div className="qgame__topbar">
        <button className="qgame__back" onClick={onBack}>← выйти</button>
        <div className="qgame__meta">
          <span className="qgame__chip"><b>{QUIZ_DATA[lang].label}</b> · {level}</span>
          <span className="qgame__chip">{idx + 1} / {total}</span>
        </div>
        <div className="qgame__progress" style={{ "--p": progress }}></div>
        {streak >= 2 && (
          <div className="qgame__streak">streak <b>× {streak}</b></div>
        )}
      </div>

      <div className="qbox" key={idx}>
        <div className="qbox__type">
          ◆ {typeLabel}
          {q._lang && <span className="tlang">{q._lang}</span>}
        </div>
        <div className="qbox__prompt-label">
          {q.type === "translate" ? "переведи" :
           q.type === "image" ? "выбери картинку" :
           q.type === "fill" ? "заполни пропуск" :
           q.type === "idiom" ? "что значит" :
           q.type === "grammar" ? "выбери правильную форму" : ""}
        </div>
        <div className="qbox__prompt">
          {q.type === "fill" || q.type === "grammar"
            ? <span dangerouslySetInnerHTML={{ __html: q.prompt.replace(/___/g, '<em>___</em>') }} />
            : q.prompt}
        </div>

        <div className={`qbox__options ${isImageOptions ? "qbox__options--image" : ""}`}>
          {q.options.map((opt, i) => {
            const isSelected = selected === i;
            const isCorrect = selected !== null && i === q.correct;
            const isWrong = isSelected && i !== q.correct;
            const dim = selected !== null && !isCorrect && !isWrong;
            return (
              <button
                key={i}
                className={`qopt ${isCorrect ? "correct" : ""} ${isWrong ? "wrong" : ""} ${dim ? "dim" : ""}`}
                disabled={selected !== null}
                onClick={() => pick(i)}
              >
                <span className="qopt__key">{"ABCD"[i]}</span>
                <span className="qopt__text">{opt}</span>
              </button>
            );
          })}
        </div>

        {selected !== null && (
          <div className={`qreveal ${selected === q.correct ? "good" : "bad"}`}>
            <div className="qreveal__icon">{selected === q.correct ? "✓" : "✕"}</div>
            <div className="qreveal__text">
              {selected === q.correct
                ? <><b>Верно.</b> {q.note || ""}</>
                : <><b>Правильный ответ:</b> {q.options[q.correct]}{q.note ? ` — ${q.note}` : ""}</>
              }
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function Result({ run, state, onRetry, onLevels, onHome }) {
  const { lang, level, pct, correct, total } = run;
  const passed = pct >= PASS_THRESHOLD;
  const data = QUIZ_DATA[lang];
  const lvlIdx = data.levels.indexOf(level);
  const nextLevel = data.levels[lvlIdx + 1];
  const [title, text] = levelCongrats(level);

  // Breakdown by type
  const byType = {};
  run.answers.forEach(a => {
    if (!byType[a.type]) byType[a.type] = { c: 0, t: 0 };
    byType[a.type].t++;
    if (a.correct) byType[a.type].c++;
  });

  useEffect(() => {
    if (passed) setTimeout(fireConfetti, 300);
  }, [passed]);  return (
    <div className="qresult">
      <div className="qresult__eyebrow">
        результат · {data.label} · {level}
      </div>
      <h1 className="qresult__headline">
        {passed ? (
          <><em>{title.split(" ")[0]} {title.split(" ")[1]}</em><br />{title.split(" ").slice(2).join(" ")}</>
        ) : (
          <>Ещё <em>чуть-чуть.</em></>
        )}
      </h1>
      <p className="qresult__lead">
        {passed
          ? text
          : `Ты ответил верно на ${correct} из ${total} (${Math.round(pct*100)}%). Чтобы разблокировать следующий уровень, нужно 70%+. Давай ещё разок.`}
      </p>

      {passed && nextLevel && (
        <div className="qresult__unlock">
          <div className="qresult__unlock-icon">↗</div>
          <div className="qresult__unlock-text">
            <b>Открыт уровень {nextLevel}.</b> Ты можешь перейти к нему прямо сейчас или потренироваться ещё на текущем.
          </div>
        </div>
      )}

      <div className="qresult__stats">
        <div className="qresult__stat">
          <div className="v">{Math.round(pct*100)}%</div>
          <div className="l">точность</div>
        </div>
        <div className="qresult__stat">
          <div className="v">{correct}<span style={{color: "var(--text-mute)", fontSize: "24px"}}>/{total}</span></div>
          <div className="l">верных ответов</div>
        </div>
        <div className="qresult__stat">
          <div className="v">{passed ? "PASS" : "—"}</div>
          <div className="l">статус</div>
        </div>
      </div>

      {Object.keys(byType).length > 1 && (
        <div style={{ marginBottom: "36px", fontFamily: "var(--mono)", fontSize: "12px", color: "var(--text-soft)" }}>
          <div style={{ fontSize: "10px", letterSpacing: "0.14em", textTransform: "uppercase", color: "var(--text-mute)", marginBottom: "12px" }}>
            разбор по типам
          </div>
          {Object.entries(byType).map(([type, v]) => {
            const tl = { translate: "перевод", image: "картинки", fill: "пропуски", idiom: "идиомы", grammar: "грамматика" }[type] || type;
            return (
              <div key={type} style={{ display: "flex", justifyContent: "space-between", padding: "8px 0", borderBottom: "1px solid var(--line)" }}>
                <span>{tl}</span>
                <span><b style={{color: "var(--text)"}}>{v.c}/{v.t}</b></span>
              </div>
            );
          })}
        </div>
      )}

      <div className="qresult__cta">
        {passed && nextLevel && (
          <button className="btn btn--primary" onClick={() => onRetry(lang, nextLevel)}>
            уровень {nextLevel} →
          </button>
        )}
        <button className="btn btn--ghost" onClick={() => onRetry(lang, level)}>
          ещё раз
        </button>
        <button className="btn btn--ghost" onClick={onLevels}>
          другой уровень
        </button>
        <button className="btn btn--ghost" onClick={onHome}>
          другой язык
        </button>
      </div>
    </div>
  );
}

function History({ state, onWipe }) {
  const sorted = [...state.history].sort((a,b) => b.ts - a.ts).slice(0, 10);
  return (
    <div className="history">
      <div className="history__head">
        <h2 className="history__title">История попыток</h2>
        <button className="history__wipe" onClick={onWipe}>очистить</button>
      </div>
      <div className="history__list">
        {sorted.map((h, i) => (
          <div key={i} className="history__row">
            <div>
              <div style={{fontFamily: "var(--display)", fontSize: "15px", color: "var(--text)"}}>
                {QUIZ_DATA[h.lang]?.label || h.lang}
              </div>
              <div className="date">{formatDate(h.ts)}</div>
            </div>
            <div className="lvl">{h.level}</div>
            <div className="score"><b>{Math.round(h.pct*100)}%</b></div>
            <div>
              <span style={{color: "var(--text-mute)"}}>{h.correct}/{h.total}</span>
            </div>
            <div className={`status ${h.pct >= PASS_THRESHOLD ? "pass" : "fail"}`}>
              {h.pct >= PASS_THRESHOLD ? "✓ passed" : "× retry"}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* =========================================================================
   MAIN APP
   ========================================================================= */
function App() {
  useCursorTrail();

  const [state, setState] = useState(() => loadState());
  const [screen, setScreen] = useState("home"); // home | levels | game | result
  const [sel, setSel] = useState({ lang: null, level: null });
  const [run, setRun] = useState(null);

  useEffect(() => { saveState(state); }, [state]);

  const onPickLang = (lang) => {
    setSel({ lang, level: null });
    setScreen("levels");
  };
  const onStart = (lang, level) => {
    setSel({ lang, level });
    setScreen("game");
  };
  const onFinish = (result) => {
    setRun(result);
    setState(s => {
      const nextHistory = [...s.history, result];
      const key = `${result.lang}:${result.level}`;
      const passed = result.pct >= PASS_THRESHOLD;
      const nextUnlocked = { ...s.unlocked };
      if (passed) {
        nextUnlocked[key] = { passed: true, ts: result.ts };
      } else if (!nextUnlocked[key]) {
        nextUnlocked[key] = { passed: false, ts: result.ts };
      }
      return { history: nextHistory, unlocked: nextUnlocked };
    });
    setScreen("result");
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  return (
    <>
      <div className="cursor-trail" id="cursorTrail"></div>
      <div className="confetti-layer" id="confettiLayer"></div>
      <div className="bg-mesh"></div>
      <div className="bg-grid"></div>
      <div className="bg-scan"></div>

      <nav className="qnav">
        <div className="wrap qnav__inner">
          <a className="qnav__back-home" href="index.html">
            <span style={{fontSize: "14px"}}>←</span>
            <span>SMAGLO <span style={{color: "var(--text-mute)"}}>/ на главную</span></span>
          </a>
          <div style={{fontFamily: "var(--mono)", fontSize: "11px", color: "var(--text-mute)", letterSpacing: "0.12em", textTransform: "uppercase"}}>
            quiz · v1
          </div>
        </div>
      </nav>

      <main className="wrap quiz-page">
        {screen === "home" && <Home state={state} onPick={onPickLang} />}
        {screen === "levels" && sel.lang && (
          <LevelPicker
            lang={sel.lang}
            state={state}
            onBack={() => setScreen("home")}
            onStart={onStart}
          />
        )}
        {screen === "game" && sel.lang && sel.level && (
          <Game
            key={`${sel.lang}:${sel.level}:${Date.now()}`}
            lang={sel.lang}
            level={sel.level}
            state={state}
            onBack={() => setScreen("levels")}
            onFinish={onFinish}
          />
        )}
        {screen === "result" && run && (
          <Result
            run={run}
            state={state}
            onRetry={(lang, level) => { setSel({ lang, level }); setScreen("game"); }}
            onLevels={() => setScreen("levels")}
            onHome={() => setScreen("home")}
          />
        )}
      </main>
    </>
  );
}

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