/* ============================================================
   results.jsx — scored results + answer review
   Exports window.ResultsScreen
   ============================================================ */
(function () {
  const { useState, useMemo } = React;
  const S = window.TestStore;

  function scaleSection(correct, total) {
    if (!total) return 5;
    return Math.min(495, Math.max(5, Math.round((correct / total * 495) / 5) * 5));
  }
  function band(total) {
    if (total >= 860) return { label: "International Proficiency",   note: "Communicates effectively in nearly any professional or social situation.", color: "var(--correct)" };
    if (total >= 730) return { label: "Working Proficiency Plus",    note: "Satisfies most workplace demands with confident, accurate language use.", color: "#2A7AB0" };
    if (total >= 470) return { label: "Limited Working Proficiency", note: "Handles routine work and social situations with developing accuracy.", color: "var(--primary)" };
    if (total >= 220) return { label: "Elementary Proficiency",      note: "Meets immediate, everyday communication needs.", color: "var(--warn)" };
    return                   { label: "Basic Proficiency",           note: "Building foundational language ability.", color: "var(--ink-soft)" };
  }

  function ScoreDial({ score, max, label, color }) {
    const pct = score / max;
    const R = 52, C = 2 * Math.PI * R;
    return (
      <div className="col center" style={{ gap: 8 }}>
        <div style={{ position: "relative", width: 128, height: 128 }}>
          <svg width="128" height="128" style={{ transform: "rotate(-90deg)" }}>
            <circle cx="64" cy="64" r={R} fill="none" stroke="var(--surface-3)" strokeWidth="11" />
            <circle cx="64" cy="64" r={R} fill="none" stroke={color} strokeWidth="11" strokeLinecap="round"
              strokeDasharray={C} strokeDashoffset={C * (1 - pct)}
              style={{ transition: "stroke-dashoffset 1s cubic-bezier(.2,.7,.2,1)" }} />
          </svg>
          <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
            <span className="serif" style={{ fontSize: 30, fontWeight: 600, lineHeight: 1 }}>{score}</span>
            <span className="faint" style={{ fontSize: 11.5 }}>/ {max}</span>
          </div>
        </div>
        <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--ink-soft)" }}>{label}</span>
      </div>
    );
  }

  function SpeakingDial({ attempted, total }) {
    const pct = total > 0 ? attempted / total : 0;
    const R = 52, C = 2 * Math.PI * R;
    return (
      <div className="col center" style={{ gap: 8 }}>
        <div style={{ position: "relative", width: 128, height: 128 }}>
          <svg width="128" height="128" style={{ transform: "rotate(-90deg)" }}>
            <circle cx="64" cy="64" r={R} fill="none" stroke="var(--surface-3)" strokeWidth="11" />
            <circle cx="64" cy="64" r={R} fill="none" stroke="var(--incorrect)" strokeWidth="11" strokeLinecap="round"
              strokeDasharray={C} strokeDashoffset={C * (1 - pct)}
              style={{ transition: "stroke-dashoffset 1s cubic-bezier(.2,.7,.2,1)" }} />
          </svg>
          <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
            <span className="serif" style={{ fontSize: 30, fontWeight: 600, lineHeight: 1, color: "var(--incorrect)" }}>{attempted}</span>
            <span className="faint" style={{ fontSize: 11.5 }}>/ {total}</span>
          </div>
        </div>
        <span style={{ fontSize: 13.5, fontWeight: 600, color: "var(--ink-soft)" }}>Speaking</span>
      </div>
    );
  }

  function ReviewQuestion({ entry, n, answers }) {
    const q       = entry.q;
    const sel     = answers[q.id];
    const correct = q.correct;
    const isRight = sel === correct;
    const meta    = S.PARTS[entry.part];
    return (
      <div className="panel" style={{ padding: 16, borderColor: isRight ? "var(--correct-line)" : "var(--incorrect-line)", background: isRight ? "var(--correct-soft)" : "var(--incorrect-soft)" }}>
        <div className="row gap-3" style={{ alignItems: "flex-start" }}>
          <span style={{ width: 24, height: 24, borderRadius: "50%", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center", background: isRight ? "var(--correct)" : "var(--incorrect)", color: "#fff" }}>
            <Icon name={isRight ? "check" : "x"} size={14} stroke={3} />
          </span>
          <div className="grow col gap-3" style={{ minWidth: 0 }}>
            <div className="row spread" style={{ alignItems: "baseline", gap: 10 }}>
              <span style={{ fontSize: 15, fontWeight: 500, lineHeight: 1.45 }}>
                <span className="mono" style={{ color: "var(--ink-soft)", fontSize: 13, marginRight: 6 }}>Q{n}</span>
                {q.text || <span className="faint">Photograph / spoken prompt</span>}
              </span>
              <span className="badge" style={{ background: "rgba(255,255,255,0.7)", flexShrink: 0 }}>P{entry.part}</span>
            </div>
            <div className="col gap-2" style={{ background: "rgba(255,255,255,0.55)", borderRadius: 8, padding: "10px 12px" }}>
              {q.options.slice(0, meta.options).map((opt, i) => {
                const right = i === correct, chosen = i === sel;
                let state = "idle";
                if (right) state = "correct"; else if (chosen) state = "incorrect";
                return (
                  <div key={i} className="row gap-3" style={{ alignItems: "center", opacity: right || chosen ? 1 : 0.6 }}>
                    <OptionLetter index={i} state={state} />
                    <span style={{ fontSize: 14, fontWeight: right ? 600 : 400 }}>{opt || `(spoken option ${["A","B","C","D"][i]})`}</span>
                    {right && <span className="badge badge-correct" style={{ marginLeft: "auto" }}>Correct</span>}
                    {chosen && !right && <span className="badge badge-incorrect" style={{ marginLeft: "auto" }}>Your answer</span>}
                  </div>
                );
              })}
            </div>
            {sel == null && <span className="hint" style={{ color: "var(--incorrect)" }}>Not answered</span>}
            {q.explanation && (
              <div className="row gap-2" style={{ alignItems: "flex-start", fontSize: 13.5, color: "var(--ink-soft)" }}>
                <Icon name="book" size={14} style={{ marginTop: 2, flexShrink: 0, color: "var(--ink-faint)" }} />
                <span><strong style={{ color: "var(--ink)" }}>Explanation. </strong>{q.explanation}</span>
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }

  function SpeakingReview({ speakingResults }) {
    const items = S.allSpeakingItems();
    if (!items.length) return null;
    return (
      <div className="col gap-3">
        {items.map((it, i) => {
          const res = speakingResults.find((r) => r.id === it.id) || {};
          const att = !!res.attempted;
          return (
            <div key={it.id} className="panel" style={{ padding: 16, borderColor: att ? "var(--correct-line)" : "var(--line)", background: att ? "var(--correct-soft)" : "var(--surface-2)" }}>
              <div className="row gap-3" style={{ alignItems: "flex-start" }}>
                <span style={{ width: 24, height: 24, borderRadius: "50%", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center", background: att ? "var(--correct)" : "var(--line-strong)", color: att ? "#fff" : "var(--ink-faint)" }}>
                  <Icon name={att ? "mic" : "micOff"} size={13} />
                </span>
                <div className="grow col gap-1" style={{ minWidth: 0 }}>
                  <div className="row spread" style={{ gap: 10, alignItems: "flex-start" }}>
                    <span style={{ fontSize: 14.5, fontWeight: 500, lineHeight: 1.45 }}>
                      <span className="mono" style={{ color: "var(--ink-soft)", fontSize: 13, marginRight: 6 }}>Q{i + 1}</span>
                      {it.prompt}
                    </span>
                    {it.topic && <span className="badge" style={{ background: "rgba(255,255,255,0.7)", flexShrink: 0 }}>{it.topic}</span>}
                  </div>
                  {att
                    ? <span className="row gap-2" style={{ fontSize: 13, color: "var(--correct)", marginTop: 4 }}>
                        <Icon name="checkCircle" size={14} /> Response recorded ({res.duration}s)
                      </span>
                    : <span className="hint" style={{ color: "var(--ink-faint)" }}>No response recorded</span>}
                </div>
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  window.ResultsScreen = function ResultsScreen({ settings, answers, speakingResults = [], hasSpeaking = false, onExit, onRetake }) {
    const [filter, setFilter] = useState("all"); // all | incorrect | listening | reading | speaking

    const data = useMemo(() => {
      const compute = (key) => {
        const flat    = S.buildExam(key);
        const correct = flat.filter((e) => answers[e.q.id] === e.q.correct).length;
        return { flat, correct, total: flat.length, scaled: scaleSection(correct, flat.length) };
      };
      const L = compute("listening"), R = compute("reading");
      const totalScaled  = L.scaled + R.scaled;
      const totalCorrect = L.correct + R.correct;
      const totalQ       = L.total + R.total;
      const spkAttempted = speakingResults.filter((r) => r.attempted).length;
      const spkTotal     = S.allSpeakingItems().length;
      return { L, R, totalScaled, totalCorrect, totalQ, spkAttempted, spkTotal, b: band(totalScaled) };
    }, [answers, speakingResults]);

    const numberMap = useMemo(() => {
      const m = {}; let n = 0;
      ["listening", "reading"].forEach((k) => S.buildExam(k).forEach((e) => { m[e.q.id] = ++n; }));
      return m;
    }, []);

    const reviewEntries = useMemo(() => {
      let entries = [...data.L.flat, ...data.R.flat];
      if (filter === "incorrect")  entries = entries.filter((e) => answers[e.q.id] !== e.q.correct);
      if (filter === "listening")  entries = data.L.flat;
      if (filter === "reading")    entries = data.R.flat;
      if (filter === "speaking")   entries = [];
      return entries;
    }, [filter, data]);

    const filterOptions = [
      { value: "all",       label: "All" },
      { value: "incorrect", label: "Incorrect" },
      { value: "listening", label: "Listening" },
      { value: "reading",   label: "Reading" },
      ...(hasSpeaking ? [{ value: "speaking", label: "Speaking" }] : []),
    ];

    return (
      <div className="view-in" style={{ minHeight: "100vh", paddingBottom: 60 }}>
        {/* hero */}
        <div style={{ background: "var(--surface)", borderBottom: "1px solid var(--line)" }}>
          <div style={{ maxWidth: 920, margin: "0 auto", padding: "40px 24px 34px", textAlign: "center" }}>
            <span className="eyebrow">Score Report</span>
            <h1 className="display" style={{ fontSize: 30, margin: "10px 0 26px" }}>{settings.testTitle}</h1>

            <div className="col center" style={{ gap: 4, marginBottom: 18 }}>
              <span className="eyebrow" style={{ color: "var(--accent)" }}>Total Score</span>
              <span className="serif" style={{ fontSize: 64, fontWeight: 600, lineHeight: 1, color: "var(--ink)" }}>{data.totalScaled}</span>
              <span className="faint" style={{ fontSize: 13 }}>out of 990</span>
            </div>
            <div className="row center gap-6 wrap" style={{ marginBottom: 26 }}>
              <ScoreDial score={data.L.scaled} max={495} label="Listening" color="#2A7AB0" />
              <ScoreDial score={data.R.scaled} max={495} label="Reading" color="var(--warn)" />
              {hasSpeaking && <SpeakingDial attempted={data.spkAttempted} total={data.spkTotal} />}
            </div>

            <div className="row center" style={{ marginBottom: 6 }}>
              <div className="row gap-3" style={{ alignItems: "center", padding: "10px 20px", borderRadius: 999, background: "var(--surface-2)", border: `1.5px solid ${data.b.color}` }}>
                <Icon name="award" size={20} style={{ color: data.b.color }} />
                <div className="col" style={{ textAlign: "left", lineHeight: 1.3 }}>
                  <span style={{ fontWeight: 600, fontSize: 15, color: data.b.color }}>{data.b.label}</span>
                  <span className="faint" style={{ fontSize: 12.5 }}>
                    {data.totalCorrect} of {data.totalQ} written questions correct
                    {hasSpeaking ? ` · ${data.spkAttempted}/${data.spkTotal} speaking attempted` : ""}
                  </span>
                </div>
              </div>
            </div>
            <p className="muted" style={{ fontSize: 13.5, maxWidth: 480, margin: "16px auto 0" }}>{data.b.note}</p>

            <div className="row center gap-3" style={{ marginTop: 26 }}>
              <button className="btn btn-ghost" onClick={onExit}><Icon name="arrowLeft" size={16} /> Home</button>
              <button className="btn btn-primary" onClick={onRetake}><Icon name="reset" size={16} /> Retake Test</button>
            </div>
          </div>
        </div>

        {/* review */}
        {settings.showReview && (
          <div style={{ maxWidth: 760, margin: "0 auto", padding: "30px 24px 0" }}>
            <div className="row spread wrap gap-3" style={{ alignItems: "center", marginBottom: 18 }}>
              <h2 className="serif" style={{ fontSize: 22 }}>Answer Review</h2>
              <Segmented value={filter} onChange={setFilter} options={filterOptions} />
            </div>
            <div className="col gap-3">
              {filter === "speaking" ? (
                <SpeakingReview speakingResults={speakingResults} />
              ) : (
                <>
                  {reviewEntries.length === 0 && (
                    <div className="panel center" style={{ padding: 40, flexDirection: "column", gap: 10, color: "var(--correct)" }}>
                      <Icon name="checkCircle" size={32} />
                      <span style={{ fontWeight: 600 }}>Nothing here — every answer in this view was correct.</span>
                    </div>
                  )}
                  {reviewEntries.map((e) => (
                    <ReviewQuestion key={e.q.id} entry={e} n={numberMap[e.q.id]} answers={answers} />
                  ))}
                </>
              )}
            </div>
          </div>
        )}
      </div>
    );
  };
})();
