// Question Sets module — list + individual quiz runner
// "Novel Quizzes" renamed to "Question Sets" throughout.
// Module number/lesson is the primary label; book title is secondary.

// ── Google Form submission ──────────────────────────────────────
const FORM = {
  url: "https://docs.google.com/forms/d/e/1FAIpQLScSFuVsZ983Vfrd6W_sqI0Y1ikm9ir9KQmAoZdwj-s2ETdc6Q/formResponse",
  fields: {
    name:    "entry.1703369017",
    email:   "entry.1628910836",
    lesson:  "entry.1145222536",
    total:   "entry.14287392",
    q1:      "entry.735810049",
    q2:      "entry.2089759460",
    q3:      "entry.1014706061",
  },
};

function formatAnswer(q, ans) {
  if (ans == null) return "No answer";
  if (q.kind === "mc")          return q.options[ans] ?? "No answer";
  if (q.kind === "twopart")     return `Part A: ${q.partA.options[ans.a] ?? "—"}  |  Part B: ${q.partB.options[ans.b] ?? "—"}`;
  if (q.kind === "match")       return Array.isArray(ans) ? ans.map((v, i) => `${romanize(i+1)}→${letterize(v)}`).join(", ") : "No answer";
  if (q.kind === "multiselect") return Array.isArray(ans) ? ans.map(i => q.options[i]).join("; ") : "No answer";
  return "No answer";
}

async function submitToForm({ studentName, studentEmail, quiz, answers, score }) {
  const body = new FormData();
  body.append(FORM.fields.name,   studentName || studentEmail);
  body.append(FORM.fields.email,  studentEmail);
  body.append(FORM.fields.lesson, `Module 4 · Lesson ${quiz.lesson} — ${quiz.title}`);
  body.append(FORM.fields.total,  `${score}/${quiz.questions.length}`);
  const qFields = [FORM.fields.q1, FORM.fields.q2, FORM.fields.q3];
  quiz.questions.forEach((q, i) => {
    if (qFields[i]) body.append(qFields[i], formatAnswer(q, answers[i]));
  });
  // no-cors: response is opaque but the submission reaches the Sheet
  await fetch(FORM.url, { method: "POST", mode: "no-cors", body });
}

function QuizzesIndex({ setRoute, studentEmail, studentName, onIdentify, quizProgress }) {
  const quizzes = window.QUIZZES;
  const [filter, setFilter] = useState("all");
  const filtered = filter === "all" ? quizzes : quizzes.filter(q => q.book === filter);
  const w = useWindowWidth();
  const isMobile = w < BP.md;
  const isSmall  = w < BP.sm;

  // If no student email yet, show email entry before quiz list
  if (!studentEmail) {
    return (
      <div style={{ maxWidth: 1240, margin: "0 auto", padding: "36px 28px 80px" }}>
        <button onClick={() => setRoute("home")}
          style={{ color: "var(--green-800)", fontWeight: 600, fontSize: 14, padding: "6px 10px", borderRadius: 8, marginBottom: 20 }}>
          ← Back to hub
        </button>
        <div style={{
          background: "var(--green-700)",
          borderRadius: isSmall ? 18 : 28, padding: isSmall ? "28px 24px" : "48px 52px",
          border: "3px solid var(--green-900)",
          boxShadow: "0 8px 0 var(--green-900)",
          color: "var(--gold-200)",
          position: "relative", overflow: "hidden",
        }}>
          <div aria-hidden style={{
            position: "absolute", inset: 0,
            backgroundImage: "radial-gradient(var(--gold-500) 1px, transparent 1.4px)",
            backgroundSize: "16px 16px", opacity: 0.12, pointerEvents: "none",
          }} />
          <div style={{ position: "relative", maxWidth: 540 }}>
            <Chip tone="gold" style={{ marginBottom: 18 }}>Question Sets</Chip>
            <h2 className="serif" style={{ fontSize: 48, fontWeight: 900, color: "var(--gold-300)", margin: "0 0 12px", lineHeight: 1 }}>
              Ready to start?
            </h2>
            <EmailEntryForm onSubmit={onIdentify} />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div style={{ maxWidth: 1240, margin: "0 auto", padding: isSmall ? "20px 14px 60px" : "36px 28px 80px" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 16 }}>
        <button onClick={() => setRoute("home")}
          style={{ color: "var(--green-800)", fontWeight: 600, fontSize: 14, padding: "6px 10px", borderRadius: 8 }}>
          ← Back to hub
        </button>
      </div>

      {/* Title banner */}
      <div style={{
        background: "var(--gold-200)",
        borderRadius: 24,
        padding: isSmall ? "24px 20px" : "36px 40px",
        border: "2px solid var(--green-800)",
        boxShadow: "0 6px 0 var(--green-900)",
        display: "grid", gridTemplateColumns: isMobile ? "1fr" : "1fr auto", gap: 20, alignItems: "center",
        marginBottom: 28,
      }}>
        <div>
          <Chip tone="green">Wit & Wisdom · Grade 6 · Module 4</Chip>
          <h1 className="serif" style={{
            fontSize: 52, margin: "14px 0 8px", color: "var(--green-800)",
            fontWeight: 900, lineHeight: 1, letterSpacing: "-0.02em",
          }}>
            Question Sets
          </h1>
          <p style={{ fontSize: 16, lineHeight: 1.55, color: "var(--ink-2)", maxWidth: 620, margin: 0 }}>
            Ten question sets across two books — check what you understood, see instant feedback, and retake anything to reinforce your learning.
          </p>
        </div>
        {!isMobile && <SoarStamp />}
      </div>

      {/* Filter chips */}
      <div style={{ display: "flex", gap: 8, marginBottom: 20 }}>
        {[
          { key: "all",       label: "All sets",  count: quizzes.length },
          { key: "shipwreck", label: "Shipwreck", count: quizzes.filter(q => q.book === "shipwreck").length },
          { key: "malala",    label: "I Am Malala", count: quizzes.filter(q => q.book === "malala").length },
        ].map(f => (
          <button key={f.key} onClick={() => setFilter(f.key)}
            style={{
              padding: "10px 16px", borderRadius: 999,
              background: filter === f.key ? "var(--green-700)" : "var(--paper)",
              color: filter === f.key ? "var(--gold-300)" : "var(--green-800)",
              fontWeight: 600, fontSize: 14,
              border: "1.5px solid " + (filter === f.key ? "var(--green-700)" : "rgba(24,71,44,0.2)"),
            }}
          >
            {f.label} <span style={{ opacity: 0.7, fontSize: 12, marginLeft: 4 }}>{f.count}</span>
          </button>
        ))}
      </div>

      {/* Quiz grid */}
      <div style={{ display: "grid", gridTemplateColumns: isSmall ? "1fr" : isMobile ? "repeat(2, 1fr)" : "repeat(3, 1fr)", gap: 16 }}>
        {filtered.map((q) => (
          <QuizCard key={q.id} quiz={q} progress={quizProgress[q.id]} onClick={() => setRoute("quiz:" + q.id)} />
        ))}
      </div>
    </div>
  );
}

// QuizCard — module/lesson number is the hero; book title is de-emphasized
function QuizCard({ quiz, progress, onClick }) {
  const [hover, setHover] = useState(false);
  const done = progress?.completed;
  const pct  = done ? Math.round((progress.score / progress.total) * 100) : null;
  const strong = done && pct >= 67;

  const bookMeta = {
    shipwreck: { color: "var(--accent-sky)",  bgColor: "#e8f0f5", label: "Shipwreck at the Bottom of the World" },
    malala:    { color: "var(--accent-coral)", bgColor: "#fbe8de", label: "I Am Malala" },
  }[quiz.book];

  // Completed cards get a green-tinted header regardless of book
  const headerBg = done ? (strong ? "#d4edd9" : "#fbe8de") : bookMeta.bgColor;
  const borderColor = done
    ? (strong ? "var(--ok)" : "var(--accent-coral)")
    : "rgba(24,71,44,0.15)";

  return (
    <div
      onClick={done ? undefined : onClick}
      onMouseEnter={() => !done && setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        background: "var(--paper)",
        borderRadius: 18,
        border: `2px solid ${borderColor}`,
        boxShadow: done
          ? `0 4px 0 ${strong ? "rgba(47,122,76,0.3)" : "rgba(232,123,78,0.3)"}`
          : hover
            ? "0 12px 24px -8px rgba(12,42,25,0.25), 0 2px 0 rgba(24,71,44,0.1)"
            : "0 4px 0 rgba(24,71,44,0.08)",
        transform: !done && hover ? "translateY(-3px)" : "translateY(0)",
        transition: "transform 200ms, box-shadow 200ms",
        cursor: done ? "default" : "pointer",
        overflow: "hidden",
        display: "flex", flexDirection: "column",
      }}
    >
      {/* Card header */}
      <div style={{
        padding: "18px 20px",
        background: headerBg,
        borderBottom: `1.5px dashed ${done ? (strong ? "rgba(47,122,76,0.3)" : "rgba(232,123,78,0.3)") : "rgba(24,71,44,0.2)"}`,
        position: "relative",
      }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 10 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div className="mono" style={{
              fontSize: 11, letterSpacing: "0.15em",
              color: done ? (strong ? "var(--ok)" : "var(--accent-coral)") : "var(--green-700)",
              fontWeight: 700,
            }}>
              MODULE 4 · LESSON {quiz.lesson}
            </div>
            <h3 className="serif" style={{
              fontSize: 22, fontWeight: 800, color: "var(--green-800)",
              margin: "6px 0 4px", lineHeight: 1.1,
            }}>
              {quiz.title}
            </h3>
            <div style={{ fontSize: 12, color: bookMeta.color, fontWeight: 600, fontStyle: "italic" }}>
              {bookMeta.label}
            </div>
          </div>

          {/* Completed badge — checkmark + score */}
          {done && (
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4, flexShrink: 0 }}>
              <div style={{
                width: 44, height: 44, borderRadius: 999,
                background: strong ? "var(--ok)" : "var(--accent-coral)",
                color: "#fff", display: "grid", placeItems: "center",
                boxShadow: `0 3px 0 ${strong ? "rgba(0,0,0,0.18)" : "rgba(0,0,0,0.18)"}`,
                fontSize: 22, fontWeight: 900,
              }}>✓</div>
              <div style={{
                fontSize: 12, fontWeight: 800,
                color: strong ? "var(--ok)" : "var(--accent-coral)",
              }}>{pct}%</div>
            </div>
          )}
        </div>
      </div>

      {/* Blurb */}
      <div style={{ padding: "16px 20px", flex: 1 }}>
        <p style={{ fontSize: 14, lineHeight: 1.5, color: "var(--ink-2)", margin: 0 }}>{quiz.blurb}</p>
      </div>

      {/* Footer */}
      <div style={{
        padding: "12px 20px",
        borderTop: `1px solid ${done ? (strong ? "rgba(47,122,76,0.2)" : "rgba(232,123,78,0.2)") : "rgba(24,71,44,0.12)"}`,
        display: "flex", justifyContent: "space-between", alignItems: "center",
        background: done ? (strong ? "rgba(229,242,234,0.6)" : "rgba(251,232,222,0.6)") : "var(--gold-100)",
      }}>
        <span className="mono" style={{ fontSize: 11, color: "var(--ink-3)", letterSpacing: "0.1em" }}>
          {quiz.questions.length} QUESTIONS
        </span>
        <span style={{
          color: done ? (strong ? "var(--ok)" : "var(--accent-coral)") : "var(--green-700)",
          fontWeight: 700, fontSize: 13,
        }}>
          {done ? "Completed ✓" : "Start →"}
        </span>
      </div>
    </div>
  );
}

// ── Individual quiz runner ──────────────────────────────────────

function QuizRunner({ quizId, setRoute, studentEmail, studentName, onComplete }) {
  const w = useWindowWidth();
  const isSmall = w < BP.sm;
  const quiz = window.QUIZZES.find(q => q.id === quizId);
  const [idx, setIdx] = useState(0);
  const [answers, setAnswers] = useState({});
  const [showResults, setShowResults] = useState(false);
  const total = quiz.questions.length;

  function setAnswer(a) { setAnswers({ ...answers, [idx]: a }); }

  function next() {
    if (idx < total - 1) {
      setIdx(idx + 1);
    } else {
      setShowResults(true);
    }
  }

  function isCorrect(q, ans) {
    if (ans == null) return false;
    if (q.kind === "mc")          return ans === q.answer;
    if (q.kind === "twopart")     return ans && ans.a === q.partA.answer && ans.b === q.partB.answer;
    if (q.kind === "match")       return Array.isArray(ans) && ans.every((v, i) => v === q.answer[i]);
    if (q.kind === "multiselect") {
      if (!Array.isArray(ans)) return false;
      if (ans.length !== q.answer.length) return false;
      const s = new Set(ans);
      return q.answer.every(a => s.has(a));
    }
    return false;
  }

  if (showResults) {
    return (
      <QuizResults
        quiz={quiz}
        answers={answers}
        setRoute={setRoute}
        studentName={studentName}
        studentEmail={studentEmail}
        onComplete={onComplete}
        onRetake={() => { setIdx(0); setAnswers({}); setShowResults(false); }}
      />
    );
  }

  const q = quiz.questions[idx];
  const bookMeta = quiz.book === "shipwreck"
    ? { color: "var(--accent-sky)",   label: "Shipwreck at the Bottom of the World" }
    : { color: "var(--accent-coral)", label: "I Am Malala" };

  return (
    <div style={{ maxWidth: 980, margin: "0 auto", padding: isSmall ? "16px 14px 40px" : "28px 28px 60px" }}>
      {/* Top bar — module first, book title secondary */}
      <div style={{ display: "flex", alignItems: "center", flexWrap: "wrap", gap: isSmall ? 6 : 12, marginBottom: 14 }}>
        <button onClick={() => setRoute("quizzes")}
          style={{ color: "var(--green-800)", fontWeight: 600, fontSize: 14, padding: "6px 10px", borderRadius: 8 }}>
          ← Exit
        </button>
        <div style={{ flex: 1 }} />
        <span className="mono" style={{ fontSize: 11, color: "var(--ink-3)", letterSpacing: "0.1em" }}>
          MODULE 4 · LESSON {quiz.lesson}
        </span>
        {!isSmall && (
          <span className="mono" style={{ fontSize: 11, color: bookMeta.color, letterSpacing: "0.08em" }}>
            {bookMeta.label.toUpperCase()}
          </span>
        )}
      </div>

      {/* Progress bar */}
      <div style={{ marginBottom: 18 }}>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
          <div className="serif" style={{ fontSize: 22, fontWeight: 800, color: "var(--green-800)" }}>
            {quiz.title}
          </div>
          <div className="mono" style={{ fontSize: 12, color: "var(--green-700)", fontWeight: 700 }}>
            Q {idx + 1} / {total}
          </div>
        </div>
        <div style={{
          height: 10, borderRadius: 999, background: "var(--gold-200)",
          overflow: "hidden", border: "1.5px solid rgba(24,71,44,0.15)",
        }}>
          <div style={{
            height: "100%", width: `${(idx / total) * 100}%`,
            background: `linear-gradient(90deg, var(--green-700), ${bookMeta.color})`,
            transition: "width 300ms",
          }} />
        </div>
      </div>

      {/* Passage */}
      <Card style={{ padding: 22, marginBottom: 18 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 20 }}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: bookMeta.color, fontWeight: 700 }}>
              PASSAGE
            </div>
            <h3 className="serif" style={{
              fontSize: 18, margin: "4px 0 10px", color: "var(--green-800)", fontWeight: 700, fontStyle: "italic",
            }}>
              from {bookMeta.label}
            </h3>
          </div>
          {quiz.glossary && quiz.glossary.length > 0 && (
            <div style={{ display: "flex", gap: 8 }}>
              <GlossaryPopover items={quiz.glossary} />
            </div>
          )}
        </div>
        <p style={{
          fontSize: 15, lineHeight: 1.65, color: "var(--ink)",
          fontFamily: "Fraunces", fontWeight: 400,
          maxHeight: 260, overflowY: "auto", paddingRight: 8, margin: 0,
        }}>{quiz.passage}</p>
        {quiz.citation && (
          <div style={{
            marginTop: 12,
            paddingTop: 10,
            borderTop: "1px dashed rgba(24,71,44,0.15)",
            fontSize: 12, color: "var(--ink-3)",
            fontStyle: "italic",
          }}>
            {quiz.citation}
          </div>
        )}
      </Card>

      {/* Question */}
      <Card style={{ padding: 28 }}>
        <QuestionView
          q={q} idx={idx}
          answer={answers[idx]} setAnswer={setAnswer}
          revealed={false}
        />
        <div style={{
          marginTop: 24, paddingTop: 20,
          borderTop: "1px dashed rgba(24,71,44,0.2)",
          display: "flex", justifyContent: "space-between", alignItems: "center",
        }}>
          <button
            onClick={() => setIdx(Math.max(0, idx - 1))}
            disabled={idx === 0}
            style={{
              padding: "10px 16px", borderRadius: 10,
              color: "var(--green-800)", fontWeight: 600,
              opacity: idx === 0 ? 0.3 : 1,
            }}
          >← Previous</button>
          <Button variant="coral" onClick={next} disabled={answers[idx] == null}>
            {idx === total - 1 ? "Submit quiz 🏆" : "Next question →"}
          </Button>
        </div>
      </Card>
    </div>
  );
}

function GlossaryPopover({ items }) {
  const [open, setOpen] = useState(false);
  return (
    <div style={{ position: "relative" }}>
      <button onClick={() => setOpen(!open)}
        style={{
          padding: "8px 12px", borderRadius: 999,
          background: "var(--gold-200)", border: "1.5px solid var(--gold-500)",
          color: "var(--green-800)", fontSize: 12, fontWeight: 600,
        }}
      >📖 Glossary</button>
      {open && (
        <div style={{
          position: "absolute", right: 0, top: "calc(100% + 6px)",
          width: 280, padding: 16, zIndex: 20,
          background: "var(--paper)",
          borderRadius: 14, border: "1.5px solid var(--green-800)",
          boxShadow: "0 8px 20px -4px rgba(0,0,0,0.2)",
        }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--green-700)", fontWeight: 700, marginBottom: 8 }}>
            TRICKY WORDS
          </div>
          {items.map(([term, def]) => (
            <div key={term} style={{ marginBottom: 8, fontSize: 13 }}>
              <b style={{ color: "var(--green-800)" }}>{term}</b>
              <span style={{ color: "var(--ink-2)" }}> — {def}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function QuestionView({ q, idx, answer, setAnswer, revealed }) {
  const isSmall = useWindowWidth() < BP.sm;
  if (q.kind === "mc") {
    return (
      <div>
        <QPrompt>{q.prompt}</QPrompt>
        <OptionList options={q.options} selected={answer} correct={q.answer} revealed={revealed}
          onSelect={i => !revealed && setAnswer(i)} />
        {revealed && <FeedbackBanner correct={answer === q.answer} />}
      </div>
    );
  }
  if (q.kind === "twopart") {
    return (
      <div>
        <QPrompt>This item has two parts. Answer Part A, then Part B.</QPrompt>
        <div style={{ marginBottom: 20 }}>
          <div className="mono" style={{ fontSize: 11, color: "var(--accent-coral)", fontWeight: 700, marginBottom: 6, letterSpacing: "0.12em" }}>PART A</div>
          <div style={{ fontSize: 15, color: "var(--ink-2)", marginBottom: 12 }}>{q.partA.prompt}</div>
          <OptionList options={q.partA.options} selected={answer?.a} correct={q.partA.answer} revealed={revealed}
            onSelect={i => !revealed && setAnswer({ ...(answer || {}), a: i })} />
        </div>
        <div>
          <div className="mono" style={{ fontSize: 11, color: "var(--accent-coral)", fontWeight: 700, marginBottom: 6, letterSpacing: "0.12em" }}>PART B</div>
          <div style={{ fontSize: 15, color: "var(--ink-2)", marginBottom: 12 }}>{q.partB.prompt}</div>
          <OptionList options={q.partB.options} selected={answer?.b} correct={q.partB.answer} revealed={revealed}
            onSelect={i => !revealed && setAnswer({ ...(answer || {}), b: i })} />
        </div>
        {revealed && (
          <FeedbackBanner
            correct={answer && answer.a === q.partA.answer && answer.b === q.partB.answer}
            note={
              answer && answer.a === q.partA.answer && answer.b !== q.partB.answer
                ? "Part A is right — Part B isn't yet."
                : answer && answer.a !== q.partA.answer && answer.b === q.partB.answer
                  ? "Part B is right — Part A isn't yet."
                  : null
            }
          />
        )}
      </div>
    );
  }
  if (q.kind === "match") {
    const current = answer || new Array(q.left.length).fill(null);
    return (
      <div>
        <QPrompt>{q.prompt}</QPrompt>
        {q.left.map((l, li) => (
          <div key={li} style={{
            display: "grid", gridTemplateColumns: isSmall ? "1fr" : "1fr auto 1fr", gap: isSmall ? 6 : 14,
            alignItems: "center", padding: "10px 0",
            borderBottom: li < q.left.length - 1 ? "1px dashed rgba(24,71,44,0.15)" : "none",
          }}>
            <div style={{ fontSize: 14, lineHeight: 1.45 }}>
              <span className="mono" style={{ color: "var(--accent-coral)", fontWeight: 700, marginRight: 6 }}>{romanize(li + 1)}.</span>
              {l}
            </div>
            <div style={{ fontSize: 20, color: "var(--ink-3)" }}>→</div>
            <select
              value={current[li] ?? ""}
              disabled={revealed}
              onChange={e => {
                const next = [...current];
                next[li] = e.target.value === "" ? null : parseInt(e.target.value);
                setAnswer(next);
              }}
              style={{
                padding: "10px 12px", borderRadius: 10,
                border: "1.5px solid " + (revealed
                  ? (current[li] === q.answer[li] ? "var(--ok)" : "var(--danger)")
                  : "rgba(24,71,44,0.25)"),
                background: revealed
                  ? (current[li] === q.answer[li] ? "#e5f2ea" : "#fbe5dc")
                  : "var(--paper)",
                fontFamily: "Geist", fontSize: 13, width: "100%",
              }}
            >
              <option value="">Choose evidence...</option>
              {q.right.map((r, ri) => (
                <option key={ri} value={ri}>{letterize(ri)}. {r.length > 70 ? r.slice(0, 70) + "…" : r}</option>
              ))}
            </select>
          </div>
        ))}
        {revealed && (
          <div style={{ marginTop: 14, padding: 12, background: "var(--gold-200)", borderRadius: 10, fontSize: 13 }}>
            <b>Answer key:</b> {q.answer.map((a, i) => `${romanize(i + 1)}→${letterize(a)}`).join(", ")}
          </div>
        )}
        {revealed && <FeedbackBanner correct={current.every((v, i) => v === q.answer[i])} />}
      </div>
    );
  }
  if (q.kind === "multiselect") {
    const current = answer || [];
    const needed = q.answer.length;
    return (
      <div>
        <QPrompt>{q.prompt}</QPrompt>
        <div className="mono" style={{ fontSize: 11, color: "var(--ink-3)", marginBottom: 10, letterSpacing: "0.1em" }}>
          SELECTED: {current.length} / {needed}
        </div>
        {q.options.map((opt, i) => {
          const selected = current.includes(i);
          const isCorr = q.answer.includes(i);
          const bg = revealed
            ? (isCorr ? "#e5f2ea" : (selected ? "#fbe5dc" : "var(--paper)"))
            : (selected ? "var(--gold-200)" : "var(--paper)");
          const border = revealed
            ? (isCorr ? "var(--ok)" : (selected ? "var(--danger)" : "rgba(24,71,44,0.15)"))
            : (selected ? "var(--green-700)" : "rgba(24,71,44,0.15)");
          return (
            <button key={i}
              disabled={revealed}
              onClick={() => {
                if (revealed) return;
                if (selected) setAnswer(current.filter(x => x !== i));
                else if (current.length < needed) setAnswer([...current, i]);
              }}
              style={{
                display: "flex", alignItems: "center", gap: 12,
                width: "100%", textAlign: "left",
                padding: "12px 14px", borderRadius: 10,
                background: bg, border: `1.5px solid ${border}`,
                marginBottom: 8, fontSize: 14, lineHeight: 1.45, color: "var(--ink)",
                cursor: revealed ? "default" : "pointer",
              }}
            >
              <span style={{
                width: 22, height: 22, borderRadius: 6,
                border: `2px solid ${selected || (revealed && isCorr) ? "var(--green-700)" : "rgba(24,71,44,0.3)"}`,
                background: selected ? "var(--green-700)" : "transparent",
                display: "grid", placeItems: "center", flexShrink: 0,
              }}>
                {selected && <span style={{ color: "var(--gold-300)", fontSize: 14, fontWeight: 900 }}>✓</span>}
              </span>
              <span>{opt}</span>
            </button>
          );
        })}
        {revealed && (
          <FeedbackBanner correct={current.length === needed && q.answer.every(a => current.includes(a))} />
        )}
      </div>
    );
  }
  return null;
}

function QPrompt({ children }) {
  return (
    <div style={{
      fontFamily: "Fraunces", fontSize: 19, lineHeight: 1.45,
      color: "var(--green-800)", fontWeight: 600, marginBottom: 18,
    }}>{children}</div>
  );
}

function OptionList({ options, selected, correct, revealed, onSelect }) {
  return (
    <div>
      {options.map((opt, i) => {
        const isSel = selected === i;
        const isCorr = correct === i;
        let bg = "var(--paper)", border = "rgba(24,71,44,0.15)", badge = "var(--gold-200)";
        if (revealed) {
          if (isCorr)       { bg = "#e5f2ea"; border = "var(--ok)";     badge = "var(--ok)"; }
          else if (isSel)   { bg = "#fbe5dc"; border = "var(--danger)"; badge = "var(--danger)"; }
        } else if (isSel)   { bg = "var(--gold-200)"; border = "var(--green-700)"; badge = "var(--green-700)"; }
        return (
          <button key={i}
            disabled={revealed}
            onClick={() => onSelect(i)}
            style={{
              display: "flex", alignItems: "flex-start", gap: 14,
              width: "100%", textAlign: "left",
              padding: "14px 16px", borderRadius: 12,
              background: bg, border: `1.5px solid ${border}`,
              marginBottom: 10, fontSize: 14.5, lineHeight: 1.5, color: "var(--ink)",
              cursor: revealed ? "default" : "pointer",
              transition: "all 150ms",
            }}
          >
            <span style={{
              width: 30, height: 30, borderRadius: 8,
              background: badge,
              color: (isSel || (revealed && isCorr)) ? "#fff" : "var(--green-800)",
              display: "grid", placeItems: "center",
              flexShrink: 0, fontWeight: 700, fontSize: 14, fontFamily: "Geist Mono",
            }}>
              {letterize(i).toUpperCase()}
            </span>
            <span style={{ paddingTop: 4 }}>{opt}</span>
            {revealed && isCorr && <span style={{ marginLeft: "auto", color: "var(--ok)",     fontWeight: 700, fontSize: 18 }}>✓</span>}
            {revealed && isSel && !isCorr && <span style={{ marginLeft: "auto", color: "var(--danger)", fontWeight: 700, fontSize: 18 }}>✗</span>}
          </button>
        );
      })}
    </div>
  );
}

function FeedbackBanner({ correct, note }) {
  return (
    <div style={{
      marginTop: 16, padding: "14px 18px", borderRadius: 12,
      background: correct ? "#e5f2ea" : "#fbe5dc",
      border: `1.5px solid ${correct ? "var(--ok)" : "var(--danger)"}`,
      display: "flex", alignItems: "center", gap: 12,
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 999,
        background: correct ? "var(--ok)" : "var(--danger)",
        color: "#fff", display: "grid", placeItems: "center",
        fontWeight: 900, fontSize: 18,
      }}>{correct ? "✓" : "✗"}</div>
      <div>
        <div style={{ fontWeight: 700, color: "var(--green-800)", fontSize: 15 }}>
          {correct ? "Nice work! Correct." : "Not quite — check the answer key above."}
        </div>
        {note && <div style={{ fontSize: 13, color: "var(--ink-2)", marginTop: 2 }}>{note}</div>}
      </div>
    </div>
  );
}

function QuizResults({ quiz, answers, setRoute, studentName, studentEmail, onComplete, onRetake }) {
  const [submitted, setSubmitted] = useState(false);
  const w = useWindowWidth();
  const isSmall = w < BP.sm;

  function isCorrect(q, ans) {
    if (ans == null) return false;
    if (q.kind === "mc")          return ans === q.answer;
    if (q.kind === "twopart")     return ans && ans.a === q.partA.answer && ans.b === q.partB.answer;
    if (q.kind === "match")       return Array.isArray(ans) && ans.every((v, j) => v === q.answer[j]);
    if (q.kind === "multiselect") {
      const s = new Set(ans || []);
      return s.size === q.answer.length && q.answer.every(a => s.has(a));
    }
    return false;
  }

  const score = quiz.questions.filter((q, i) => isCorrect(q, answers[i])).length;
  const total = quiz.questions.length;
  const pct   = Math.round((score / total) * 100);

  // On first render: persist progress + submit to Google Form
  useEffect(() => {
    if (submitted) return;
    setSubmitted(true);
    onComplete?.(quiz.id, { completed: true, score, total });
    submitToForm({ studentName, studentEmail, quiz, answers, score }).catch(console.error);
  }, []);

  const message = pct === 100 ? "Perfect score! You soared! 🦅"
    : pct >= 67 ? "Great job! Strong work."
    : pct >= 34 ? "Good effort — give it another try."
    : "Let's try that again. Review the passage and retake.";

  return (
    <div style={{ maxWidth: 820, margin: "0 auto", padding: isSmall ? "16px 14px 40px" : "28px 28px 60px" }}>
      <div style={{ marginBottom: 14 }}>
        <button onClick={() => setRoute("quizzes")}
          style={{ color: "var(--green-800)", fontWeight: 600, fontSize: 14, padding: "6px 10px", borderRadius: 8 }}>
          ← All question sets
        </button>
      </div>

      {/* Score banner */}
      <Card style={{
        padding: isSmall ? "28px 24px" : "36px 40px", textAlign: "center",
        background: "var(--green-700)",
        color: "var(--gold-200)",
        border: "3px solid var(--green-900)",
        boxShadow: "0 6px 0 var(--green-900)",
        position: "relative", overflow: "hidden",
      }}>
        <div aria-hidden style={{
          position: "absolute", inset: 0,
          backgroundImage: "radial-gradient(var(--gold-500) 1px, transparent 1.4px)",
          backgroundSize: "18px 18px", opacity: 0.12,
        }} />
        <div style={{ position: "relative" }}>
          <img src="assets/eagle.svg" style={{ width: isSmall ? 80 : 120, filter: "drop-shadow(0 8px 0 rgba(12,42,25,0.35))", marginBottom: 16 }} />
          <div className="mono" style={{ fontSize: 11, letterSpacing: "0.15em", color: "var(--gold-500)" }}>
            MODULE 4 · LESSON {quiz.lesson} RESULTS
          </div>
          <div className="serif" style={{ fontSize: isSmall ? 52 : 72, fontWeight: 900, color: "var(--gold-300)", letterSpacing: "-0.02em", lineHeight: 1 }}>
            {score}/{total}
          </div>
          <div style={{ fontSize: isSmall ? 15 : 18, marginTop: 8, color: "var(--gold-500)", fontWeight: 600 }}>
            {pct}% · {message}
          </div>
        </div>
      </Card>

      <div style={{ display: "flex", gap: 12, marginTop: 28, justifyContent: "center" }}>
        <Button onClick={() => setRoute("quizzes")}>Back to question sets</Button>
      </div>
    </div>
  );
}

function romanize(n)  { return ["I","II","III","IV","V","VI","VII","VIII"][n - 1] || n; }
function letterize(n) { return "abcdefgh"[n] || n; }

Object.assign(window, { QuizzesIndex, QuizRunner });
