/* =========================================================================
   TAXR — Module test (quiz) with Pip hints + results
   ========================================================================= */
function Quiz({ nav, params, account, progress, onTestComplete, hints, spendHint, buyHints, recordReview }) {
  const D = window.TAXR;
  const moduleId = params.moduleId || "m1";
  const mod = D.modules[moduleId] || D.modules.m1;
  const moduleNum = (D.moduleMeta[moduleId] || {}).n || 1;
  const questions = mod.quiz;
  const hintRepo = mod.hints;
  const PASS = 70;

  const HINT_FN = "https://us-central1-waddl3-ecosystem.cloudfunctions.net/taxrHint";

  const [stage, setStage] = useState("intro"); // intro | run | done
  const [i, setI] = useState(0);
  const [picked, setPicked] = useState(null);
  const [answers, setAnswers] = useState([]); // {pick, correct}
  const [revealHint, setRevealHint] = useState(0); // 0 none, 1 title, 2 body
  const [aiHint, setAiHint] = useState(null);   // null | "loading" | "string"
  const owned = account.paid;

  if (!owned) {
    return <div className="wrap col center" style={{ padding: "80px 32px", minHeight: "70vh" }}>{window.UnlockCard({ nav, moduleId, account })}</div>;
  }

  const q = questions[i];
  const hint = hintRepo[i % hintRepo.length];
  const submitted = picked !== null && answers[i] !== undefined;

  function choose(idx) { if (!submitted) setPicked(idx); }
  function submit() {
    if (picked === null) return;
    const correct = picked === q.correct;
    const a = answers.slice(); a[i] = { pick: picked, correct }; setAnswers(a);
    // feed the spaced-repetition system: missed questions get enrolled for review
    if (recordReview) recordReview({
      id: moduleId + "-q" + i, type: "q", correct,
      payload: { q: q.q, a: q.a, correct: q.correct, why: q.why, wrong: q.wrong, diff: q.diff, moduleId, moduleNum },
    });
  }
  function nextQ() {
    if (i === questions.length - 1) {
      const score = Math.round((answers.filter((x) => x && x.correct).length / questions.length) * 100);
      onTestComplete(moduleId, score);
      setStage("done");
    } else {
      setI(i + 1); setPicked(null); setRevealHint(0); setAiHint(null);
    }
  }
  async function useHint() {
    if (revealHint > 0) { setRevealHint(2); return; }
    if (hints <= 0) { buyHints(); return; }
    spendHint();
    setRevealHint(1);
    // Try AI hint if user is signed in with Waddl3 ID
    if (window.taxrAuth && !account.guest) {
      setAiHint("loading");
      try {
        const token = await window.taxrAuth.currentUser?.getIdToken();
        const res = await fetch(HINT_FN, {
          method: "POST",
          headers: { "Content-Type": "application/json", Authorization: "Bearer " + token },
          body: JSON.stringify({
            questionText: q.q,
            choices: q.a,
            correctIndex: q.correct,
            userAnswer: picked,
            moduleId,
          }),
        });
        if (res.ok) {
          const data = await res.json();
          setAiHint(data.hint || null);
        } else {
          setAiHint(null); // fall back to static hint
        }
      } catch {
        setAiHint(null); // offline or function not deployed — fall back silently
      }
    }
  }
  function retake() { setStage("intro"); setI(0); setPicked(null); setAnswers([]); setRevealHint(0); setAiHint(null); }
  const tests = progress.tests || {};

  /* ---------------- intro ---------------- */
  if (stage === "intro") {
    return (
      <div className="wrap col center" style={{ padding: "60px 32px", minHeight: "78vh" }}>
        <div className="card grid-lines" style={{ maxWidth: 560, width: "100%", padding: 40, textAlign: "center" }}>
          <span style={{ width: 60, height: 60, borderRadius: 16, display: "grid", placeItems: "center", margin: "0 auto 22px", background: "var(--blue-soft)", color: "var(--blue-bright)" }}><Icon name="flag" size={28} /></span>
          <Eyebrow style={{ justifyContent: "center", marginBottom: 14 }}>Module {moduleNum} · Final test</Eyebrow>
          <h1 className="display" style={{ fontSize: 36 }}>Prove it <span className="it">stuck.</span></h1>
          <p className="fs-16 t-muted lh-rel" style={{ margin: "16px auto 28px", maxWidth: 400 }}>
            {questions.length} questions covering all {numberWord(mod.lessons.length)} lessons. Score {PASS}% or higher to pass and unlock the next module. Wrong answers come with a full explanation.
          </p>
          <div className="row" style={{ justifyContent: "center", gap: 0, marginBottom: 30 }}>
            {[[questions.length, "Questions"], [PASS + "%", "To pass"], ["24h", "Retake cooldown"]].map((s, k) => (
              <React.Fragment key={k}>
                {k > 0 && <div className="vr" style={{ margin: "4px 22px" }} />}
                <div className="stat col"><span className="num" style={{ fontSize: 30 }}>{s[0]}</span><span className="lab">{s[1]}</span></div>
              </React.Fragment>
            ))}
          </div>
          <div className="row center gap-12" style={{ marginBottom: 22 }}>
            <Pip tone="cheer" compact style={{ textAlign: "left" }}>Take your time. Stuck on one? Spend a hint and I'll talk you through it. You've got <strong className="t-amber">{hints} hints</strong> left.</Pip>
          </div>
          <Button block size="lg" arrow onClick={() => setStage("run")}>{tests[moduleId] ? "Retake the test" : "Start the test"}</Button>
        </div>
      </div>
    );
  }

  /* ---------------- results ---------------- */
  if (stage === "done") {
    const score = Math.round((answers.filter((x) => x && x.correct).length / questions.length) * 100);
    const passed = score >= PASS;
    return (
      <div className="wrap" style={{ padding: "50px 32px 80px", maxWidth: 760, margin: "0 auto" }}>
        <div className="card grid-lines" style={{ padding: 40, textAlign: "center", marginBottom: 24 }}>
          <span style={{ fontSize: 52 }}>{passed ? "🎉" : "🐧"}</span>
          <h1 className="display" style={{ fontSize: 40, marginTop: 10 }}>{passed ? <>You <span className="it">passed!</span></> : <>So close.</>}</h1>
          <div className="row center gap-12" style={{ margin: "20px 0" }}>
            <span className="serif" style={{ fontSize: 64, color: passed ? "var(--green)" : "var(--amber)" }}>{score}%</span>
            <div className="col" style={{ alignItems: "flex-start" }}>
              <span className="fs-15 t-muted">{answers.filter((x) => x && x.correct).length} of {questions.length} correct</span>
              <Badge kind={passed ? "solid-green" : "amber"} style={{ marginTop: 4 }}>{passed ? "Module " + moduleNum + " complete" : "Need " + PASS + "% to pass"}</Badge>
            </div>
          </div>
          <p className="fs-16 t-muted" style={{ maxWidth: 420, margin: "0 auto 26px" }}>
            {passed ? "That module's locked in. Anything you missed has been added to your review deck so it comes back before you forget it." : "Review the explanations below, give it another shot, and you'll have it."}
          </p>
          <div className="row center gap-12">
            <Button variant="ghost" onClick={retake}>Retake test</Button>
            <Button arrow onClick={() => nav("dashboard")}>{passed ? "Back to track" : "Review & retry later"}</Button>
          </div>
        </div>

        <span className="mono fs-13 t-dim upper" style={{ display: "block", marginBottom: 14 }}>Review</span>
        <div className="col gap-12">
          {questions.map((qq, k) => {
            const a = answers[k];
            const ok = a && a.correct;
            return (
              <div key={k} className="card card-pad" style={{ borderColor: ok ? "rgba(70,214,164,0.25)" : "rgba(240,132,106,0.25)" }}>
                <div className="row gap-12" style={{ alignItems: "flex-start", marginBottom: 8 }}>
                  <span style={{ color: ok ? "var(--green)" : "var(--wrong)", flex: "none", marginTop: 2 }}><Icon name={ok ? "check" : "x"} size={18} /></span>
                  <span className="fs-16" style={{ fontWeight: 600 }}>{qq.q}</span>
                </div>
                <div style={{ paddingLeft: 30 }}>
                  <p className="fs-14 t-green" style={{ marginBottom: 4 }}>Correct: {qq.a[qq.correct]}</p>
                  {!ok && a && <p className="fs-14 t-wrong" style={{ marginBottom: 8 }}>You chose: {qq.a[a.pick]}</p>}
                  <p className="fs-14 t-muted lh-rel">{qq.why}</p>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  /* ---------------- run ---------------- */
  return (
    <div className="wrap" style={{ padding: "26px 32px 70px", maxWidth: 760, margin: "0 auto" }}>
      {/* top bar */}
      <div className="row spread" style={{ marginBottom: 10 }}>
        <button className="row gap-8 fs-14 t-dim" onClick={() => nav("dashboard")}><Icon name="x" size={16} /> Exit test</button>
        <Fish count={hints} onClick={buyHints} compact />
      </div>
      <div className="row gap-16" style={{ marginBottom: 28, alignItems: "center" }}>
        <Progress value={((i + (submitted ? 1 : 0)) / questions.length) * 100} />
        <span className="mono fs-13 t-dim" style={{ flex: "none" }}>{i + 1} / {questions.length}</span>
      </div>

      <div className="row gap-12" style={{ marginBottom: 18 }}>
        <Badge kind={q.diff === "Easy" ? "solid-green" : q.diff === "Hard" ? "amber" : "blue"}>{q.diff}</Badge>
        <span className="mono fs-13 t-dim">Question {i + 1}</span>
      </div>
      <h1 className="serif" style={{ fontSize: 28, lineHeight: 1.25, marginBottom: 26 }}>{q.q}</h1>

      <div className="col gap-12">
        {q.a.map((opt, idx) => {
          const isPick = picked === idx;
          const isCorrect = idx === q.correct;
          let bd = "var(--line)", bg = "var(--surface)", ic = null, tc = "var(--text)";
          if (submitted) {
            if (isCorrect) { bd = "rgba(70,214,164,0.5)"; bg = "var(--green-soft)"; ic = <Icon name="check" size={18} style={{ color: "var(--green)" }} />; }
            else if (isPick) { bd = "rgba(240,132,106,0.5)"; bg = "var(--wrong-soft)"; ic = <Icon name="x" size={18} style={{ color: "var(--wrong)" }} />; }
            else tc = "var(--muted)";
          } else if (isPick) { bd = "var(--blue)"; bg = "var(--blue-soft)"; }
          return (
            <button key={idx} onClick={() => choose(idx)} disabled={submitted}
              className="row gap-16" style={{ textAlign: "left", padding: "16px 18px", borderRadius: 13, border: "1px solid " + bd, background: bg, alignItems: "center", transition: "all .15s", cursor: submitted ? "default" : "pointer" }}>
              <span style={{ width: 26, height: 26, borderRadius: 8, flex: "none", display: "grid", placeItems: "center",
                border: "1px solid " + (isPick && !submitted ? "var(--blue)" : "var(--line-2)"),
                fontFamily: "var(--mono)", fontSize: 13, color: isPick && !submitted ? "var(--blue-bright)" : "var(--dim)" }}>
                {String.fromCharCode(65 + idx)}
              </span>
              <span className="fs-16" style={{ flex: 1, color: tc }}>{opt}</span>
              {ic}
            </button>
          );
        })}
      </div>

      {/* explanation after submit */}
      {submitted && (
        <div className="pop" style={{ marginTop: 20, padding: "18px 20px", borderRadius: 14,
          background: answers[i].correct ? "var(--green-soft)" : "var(--wrong-soft)",
          border: "1px solid " + (answers[i].correct ? "rgba(70,214,164,0.3)" : "rgba(240,132,106,0.3)") }}>
          <span className="mono fs-13 upper" style={{ color: answers[i].correct ? "var(--green)" : "var(--wrong)" }}>
            {answers[i].correct ? "Correct" : "Not quite"}
          </span>
          <p className="fs-15 lh-rel" style={{ color: "var(--ink)", marginTop: 6 }}>{q.why}</p>
          {!answers[i].correct && q.wrong[answers[i].pick] && <p className="fs-14 t-muted lh-rel" style={{ marginTop: 8 }}>Why your pick is wrong: {q.wrong[answers[i].pick]}</p>}
        </div>
      )}

      {/* hint — AI-powered when signed in, static fallback otherwise */}
      {!submitted && revealHint > 0 && (
        <div className="pop" style={{ marginTop: 20 }}>
          {aiHint === "loading" ? (
            <Pip tone="tip" title="Pip is thinking…">
              <span className="t-dim fs-14">Generating a hint for this question…</span>
            </Pip>
          ) : aiHint ? (
            <Pip tone="tip" title="Pip's hint">
              {revealHint === 2
                ? <p className="lh-rel" style={{ marginTop: 4 }}>{aiHint}</p>
                : <button className="t-peri fs-14" style={{ fontWeight: 600, marginTop: 8, display: "block" }} onClick={() => setRevealHint(2)}>Show me the hint →</button>}
            </Pip>
          ) : (
            <Pip tone="tip" title={"Hint · " + hint.id}>
              <strong>{hint.title}</strong>
              {revealHint === 2
                ? <p className="lh-rel" style={{ marginTop: 8 }}>{hint.body}</p>
                : <button className="t-peri fs-14" style={{ fontWeight: 600, marginTop: 8, display: "block" }} onClick={() => setRevealHint(2)}>Show me the hint →</button>}
            </Pip>
          )}
        </div>
      )}

      {/* controls */}
      <div className="row spread" style={{ marginTop: 26 }}>
        {!submitted
          ? <Button variant="ghost" onClick={useHint}>
              {revealHint > 0 ? "Hint shown" : hints > 0 ? <><Icon name="bulb" size={16} style={{ color: "var(--amber)" }} /> Use a hint · –1 🐟</> : <><Icon name="fish" size={16} /> Get hints</>}
            </Button>
          : <span />}
        {!submitted
          ? <Button arrow disabled={picked === null} onClick={submit}>Submit answer</Button>
          : <Button arrow onClick={nextQ}>{i === questions.length - 1 ? "See results" : "Next question"}</Button>}
      </div>
    </div>
  );
}

Object.assign(window, { Quiz });

function numberWord(n) {
  return ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"][n] || String(n);
}
