/* ==================================================================
   AI Test Review — admin / HoD moderation surface
   ------------------------------------------------------------------
   learn-kinetiX mints practice tests in real time on student request.
   "Approve before student takes" was rejected (latency). Instead the
   student takes immediately; teachers and admins sign off afterwards.

   This screen is the admin counterpart to teacher-mobile's
   AiReviewListPage / AiReviewDetailPage. Admins see ALL practice tests
   in the school (the visibility model treats role!=='teacher' as
   privileged) and get two extra controls teachers don't have:
     • Reopen — flip a reviewed test back to 'pending' for fresh review.
     • Delete — wipe a hallucination beyond recovery.
   ================================================================== */

const { Icon: AiIcon } = window.KXUI;

const AI_STATUS_LABEL = { pending: "Pending", reviewed: "Reviewed", needs_revision: "Needs work" };
const AI_STATUS_CLS   = { pending: "amber",   reviewed: "green",   needs_revision: "madder"     };

const relTimeAi = (iso) => {
  if (!iso) return "";
  const ms = Date.now() - new Date(iso).getTime();
  const s = Math.floor(ms / 1000);
  if (s < 60)   return `${s}s ago`;
  if (s < 3600) return `${Math.floor(s/60)}m ago`;
  if (s < 86400) return `${Math.floor(s/3600)}h ago`;
  return `${Math.floor(s/86400)}d ago`;
};

const AiReviewScreen = () => {
  const [tab, setTab] = React.useState("pending");
  const [rows, setRows] = React.useState([]);
  const [counts, setCounts] = React.useState({ pending: 0, reviewed: 0, needs_revision: 0 });
  const [search, setSearch] = React.useState("");
  const [subjectFilter, setSubjectFilter] = React.useState("");
  const [selectedId, setSelectedId] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState(null);

  const subjects = window.KX?.SUBJECTS || [];

  const refresh = React.useCallback(async () => {
    setLoading(true); setErr(null);
    try {
      const [list, c] = await Promise.all([
        window.KXApi.get(`/teacher/ai-tests?status=${tab}`),
        window.KXApi.get("/teacher/ai-tests/counts"),
      ]);
      setRows(list || []);
      setCounts(c || { pending: 0, reviewed: 0, needs_revision: 0 });
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setLoading(false); }
  }, [tab]);

  React.useEffect(() => { refresh(); }, [refresh]);

  const filtered = rows.filter((r) => {
    if (subjectFilter && r.subjectCode !== subjectFilter && r.subjectName !== subjectFilter) return false;
    if (!search) return true;
    const q = search.toLowerCase();
    return (
      (r.title || "").toLowerCase().includes(q) ||
      (r.displayId || "").toLowerCase().includes(q) ||
      (r.studentName || "").toLowerCase().includes(q) ||
      (r.studentRoll || "").toLowerCase().includes(q) ||
      (r.subjectName || "").toLowerCase().includes(q)
    );
  });

  const selected = rows.find((r) => r.id === selectedId) || null;

  return (
    <div style={{ display: "grid", gridTemplateColumns: "minmax(380px, 520px) 1fr", height: "100%", overflow: "hidden" }}>
      {/* ─── Left: list ─── */}
      <div style={{ overflow: "auto", padding: "24px 20px", borderRight: "1px solid var(--line)" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 4 }}>
          <span style={{ color: "var(--accent)" }}><AiIcon name="sparkle" size={18}/></span>
          <div className="muted" style={{ fontSize: 11, letterSpacing: ".08em", textTransform: "uppercase" }}>AI test review</div>
        </div>
        <h1 style={{ margin: "4px 0 6px", color: "var(--ink-0)", fontFamily: "'Instrument Serif', serif", fontWeight: 400, fontSize: 28, letterSpacing: "-0.01em" }}>
          Practice queue
        </h1>
        <p className="muted" style={{ margin: 0, fontSize: 13, maxWidth: 480 }}>
          Tests minted by learn-kinetiX for individual students. Edit any question, sign off when satisfied. Admin / HoD can also reopen or delete a test.
        </p>

        {/* Tabs */}
        <div style={{ marginTop: 18, display: "flex", gap: 4, borderBottom: "1px solid var(--line)" }}>
          {["pending", "reviewed", "needs_revision"].map((t) => {
            const active = tab === t;
            return (
              <button key={t} onClick={() => { setTab(t); setSelectedId(null); }}
                style={{
                  background: "transparent", border: "none", padding: "8px 14px",
                  color: active ? "var(--ink-0)" : "var(--ink-3)",
                  borderBottom: active ? "2px solid var(--accent)" : "2px solid transparent",
                  cursor: "pointer", fontSize: 12.5, fontWeight: active ? 600 : 400,
                  letterSpacing: ".02em",
                }}>
                {AI_STATUS_LABEL[t]}
                <span className={`pill ${AI_STATUS_CLS[t]}`} style={{ marginLeft: 8, fontSize: 9 }}>
                  {counts[t] || 0}
                </span>
              </button>
            );
          })}
        </div>

        {/* Filter bar */}
        <div style={{ display: "flex", gap: 8, marginTop: 12 }}>
          <div style={{ position: "relative", flex: 1 }}>
            <span style={{ position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--ink-3)" }}>
              <AiIcon name="search" size={12}/>
            </span>
            <input type="text" value={search} onChange={(e) => setSearch(e.target.value)}
              placeholder="Search test, student, ID…"
              style={{
                width: "100%", padding: "8px 10px 8px 30px", fontSize: 12.5,
                background: "var(--bg-2)", border: "1px solid var(--line)",
                borderRadius: 6, color: "var(--ink-0)",
              }}/>
          </div>
          <select value={subjectFilter} onChange={(e) => setSubjectFilter(e.target.value)}
            style={{
              padding: "8px 10px", fontSize: 12.5,
              background: "var(--bg-2)", border: "1px solid var(--line)",
              borderRadius: 6, color: "var(--ink-0)", minWidth: 140,
            }}>
            <option value="">All subjects</option>
            {subjects.map((s) => (
              <option key={s.id} value={s.short_code || s.name}>
                {s.name}
              </option>
            ))}
          </select>
        </div>

        {err && <div style={{ marginTop: 14, color: "var(--madder, #b14a4a)", fontSize: 12 }}>{err}</div>}
        {loading && <div className="muted" style={{ marginTop: 16, fontSize: 12 }}>Loading…</div>}

        <div style={{ marginTop: 12, display: "flex", flexDirection: "column", gap: 6 }}>
          {!loading && filtered.length === 0 && (
            <div className="cx-emptycard">
              {tab === "pending"
                ? "Inbox zero — no practice tests waiting."
                : `Nothing ${AI_STATUS_LABEL[tab].toLowerCase()} matches.`}
            </div>
          )}
          {filtered.map((r) => {
            const active = r.id === selectedId;
            return (
              <button key={r.id} onClick={() => setSelectedId(r.id)}
                style={{
                  textAlign: "left", padding: "10px 12px",
                  background: active ? "rgba(255,186,90,0.08)" : "var(--bg-2)",
                  border: `1px solid ${active ? "var(--accent)" : "var(--line)"}`,
                  borderRadius: 8, cursor: "pointer", display: "flex", flexDirection: "column", gap: 4,
                }}>
                <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                  <span className={`pill ${AI_STATUS_CLS[r.reviewStatus]}`} style={{ fontSize: 9 }}>
                    {AI_STATUS_LABEL[r.reviewStatus]}
                  </span>
                  <span style={{ color: "var(--ink-2)", fontSize: 11, fontFamily: "var(--mono, monospace)" }}>
                    {r.displayId}
                  </span>
                  <span style={{ color: "var(--ink-3)", fontSize: 10, marginLeft: "auto" }}>{relTimeAi(r.createdAt)}</span>
                </div>
                <div style={{ color: "var(--ink-0)", fontSize: 12.5, lineHeight: 1.35 }}>
                  {r.title}
                </div>
                <div className="muted" style={{ fontSize: 11 }}>
                  {r.studentName ? <>
                    <b>{r.studentName}</b> <span style={{ opacity: 0.7 }}>({r.studentRoll})</span> · </> : null}
                  {r.subjectCode || r.subjectName} · {r.questionsCount}Q · {r.totalMarks ?? "—"} marks
                  {r.attemptsCount > 0 ? <> · {r.attemptsCount} attempt</> : null}
                </div>
              </button>
            );
          })}
        </div>
      </div>

      {/* ─── Right: detail ─── */}
      {selected ? (
        <AiTestDetail key={selected.id} testId={selected.id} onChanged={refresh} />
      ) : (
        <div style={{ display: "grid", placeItems: "center", color: "var(--ink-3)", fontSize: 13 }}>
          Pick a test from the queue to review.
        </div>
      )}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────────────────
// AiTestDetail — full editing pane for one test. Each question gets an
// inline editor (text + options + correctness + marks). Saving a single
// question fires a PATCH; the wider Approve / Needs work / Delete / Reopen
// actions live in the sticky header.
// ─────────────────────────────────────────────────────────────────────────

const AiTestDetail = ({ testId, onChanged }) => {
  const [detail, setDetail] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState(null);
  const [busy, setBusy] = React.useState(false);

  const reload = React.useCallback(async () => {
    setLoading(true); setErr(null);
    try {
      const d = await window.KXApi.get(`/teacher/ai-tests/${testId}`);
      setDetail(d);
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setLoading(false); }
  }, [testId]);

  React.useEffect(() => { reload(); }, [reload]);

  const decide = async (decision) => {
    setBusy(true);
    try {
      await window.KXApi.post(`/teacher/ai-tests/${testId}/review`, { decision });
      await reload();
      onChanged && onChanged();
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setBusy(false); }
  };

  const reopen = async () => {
    setBusy(true);
    try {
      await window.KXApi.post(`/teacher/ai-tests/${testId}/reopen`, {});
      await reload();
      onChanged && onChanged();
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setBusy(false); }
  };

  const remove = async () => {
    if (!window.confirm("Permanently delete this practice test? Cannot be undone.")) return;
    setBusy(true);
    try {
      await window.KXApi.del(`/teacher/ai-tests/${testId}`);
      onChanged && onChanged();
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setBusy(false); }
  };

  if (loading) {
    return (
      <div style={{ display: "grid", placeItems: "center", color: "var(--ink-3)", fontSize: 13 }}>
        Loading…
      </div>
    );
  }
  if (err) {
    return (
      <div style={{ padding: 24, color: "var(--madder, #b14a4a)", fontSize: 13 }}>
        {err}
      </div>
    );
  }
  if (!detail) return null;

  const t = detail.test;

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }}>
      {/* Sticky header */}
      <div style={{
        padding: "18px 24px", borderBottom: "1px solid var(--line)",
        background: "var(--bg-1)",
      }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
          <div style={{ minWidth: 0 }}>
            <div className="muted" style={{ fontSize: 10.5, letterSpacing: ".08em", textTransform: "uppercase", marginBottom: 4 }}>
              {t.displayId} · {t.subjectCode || t.subjectName}
              {t.classLevel ? <> · Class {t.classLevel}{t.section ? `-${t.section}` : ""}</> : null}
            </div>
            <div style={{ fontSize: 16, color: "var(--ink-0)", fontWeight: 500 }}>{t.title}</div>
            <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
              {t.studentName ? <>For <b>{t.studentName}</b> ({t.studentRoll}) · </> : null}
              {detail.questions.length} questions · {t.totalMarks ?? "—"} marks
              {t.reviewedAt ? <> · reviewed {relTimeAi(t.reviewedAt)}</> : null}
            </div>
          </div>
          <span className={`pill ${AI_STATUS_CLS[t.reviewStatus]}`} style={{ fontSize: 10 }}>
            {AI_STATUS_LABEL[t.reviewStatus]}
          </span>
        </div>

        {/* Action bar */}
        <div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
          <button className="btn sm" onClick={() => decide("needs_revision")} disabled={busy}
            style={{ borderColor: "var(--madder, #b14a4a)", color: "var(--madder, #b14a4a)" }}>
            Needs work
          </button>
          <button className="btn sm primary" onClick={() => decide("reviewed")} disabled={busy}>
            Approve
          </button>
          {t.reviewStatus !== "pending" && (
            <button className="btn sm" onClick={reopen} disabled={busy}>
              Reopen for re-review
            </button>
          )}
          <div style={{ marginLeft: "auto" }}>
            <button className="btn sm" onClick={remove} disabled={busy}
              style={{ borderColor: "var(--madder, #b14a4a)", color: "var(--madder, #b14a4a)" }}>
              Delete test
            </button>
          </div>
        </div>
      </div>

      {/* Question list */}
      <div style={{ flex: 1, overflow: "auto", padding: "20px 24px", display: "flex", flexDirection: "column", gap: 14 }}>
        {detail.questions.map((q, i) => (
          <AiQuestionEditor key={q.id} index={i} testId={testId} question={q} onSaved={reload}/>
        ))}
      </div>
    </div>
  );
};

const AiQuestionEditor = ({ index, testId, question, onSaved }) => {
  const isMcq = question.type === "mcq";
  const [text, setText] = React.useState(question.text);
  const [marks, setMarks] = React.useState(question.marks);
  const [expected, setExpected] = React.useState(question.expectedAnswer ?? "");
  const [options, setOptions] = React.useState(() =>
    (question.options || []).map((o) => ({
      letter: o.letter, text: o.text, is_correct: !!o.is_correct,
    }))
  );
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);

  // Reset local draft when the parent reloads (after a save / decision).
  React.useEffect(() => {
    setText(question.text);
    setMarks(question.marks);
    setExpected(question.expectedAnswer ?? "");
    setOptions((question.options || []).map((o) => ({
      letter: o.letter, text: o.text, is_correct: !!o.is_correct,
    })));
    setErr(null);
  }, [question]);

  const dirty =
    text !== question.text ||
    marks !== question.marks ||
    expected !== (question.expectedAnswer ?? "") ||
    JSON.stringify(options) !== JSON.stringify(
      (question.options || []).map((o) => ({ letter: o.letter, text: o.text, is_correct: !!o.is_correct }))
    );

  const setOpt = (i, patch) => setOptions((xs) => xs.map((o, j) => (j === i ? { ...o, ...patch } : o)));
  const setCorrect = (i) => setOptions((xs) => xs.map((o, j) => ({ ...o, is_correct: j === i })));

  const save = async () => {
    setBusy(true); setErr(null);
    try {
      const optionsChanged = isMcq && JSON.stringify(options) !== JSON.stringify(
        (question.options || []).map((o) => ({ letter: o.letter, text: o.text, is_correct: !!o.is_correct }))
      );
      if (optionsChanged && options.filter((o) => o.is_correct).length !== 1) {
        throw new Error("exactly one option must be marked correct");
      }
      const patch = {};
      if (text !== question.text) patch.text = text;
      if (marks !== question.marks) patch.marks = marks;
      if (expected !== (question.expectedAnswer ?? "")) patch.expected_answer = expected;
      if (optionsChanged) patch.options = options;
      await window.KXApi.patch(`/teacher/ai-tests/${testId}/questions/${question.id}`, patch);
      onSaved && onSaved();
    } catch (e) {
      setErr(String(e.message || e));
    } finally { setBusy(false); }
  };

  return (
    <div style={{
      border: "1px solid var(--line)", borderRadius: 10,
      background: "var(--bg-2)", padding: "14px 16px",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
        <span className="muted" style={{ fontSize: 11, fontFamily: "var(--mono, monospace)" }}>Q{index + 1}</span>
        <span className="pill" style={{ fontSize: 9, textTransform: "uppercase" }}>{question.type}</span>
        {dirty && <span className="pill amber" style={{ fontSize: 9 }}>Unsaved</span>}
      </div>

      <AiField label="Question text">
        <textarea value={text} onChange={(e) => setText(e.target.value)} rows={3}
          style={{
            width: "100%", padding: "8px 10px", fontSize: 13,
            background: "var(--bg-1)", border: "1px solid var(--line)",
            borderRadius: 6, color: "var(--ink-0)", resize: "vertical",
          }}/>
      </AiField>

      {isMcq && (
        <AiField label="Options · pick the correct one">
          <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
            {options.map((opt, i) => (
              <div key={i} style={{
                display: "flex", alignItems: "flex-start", gap: 8,
                padding: "8px 10px", borderRadius: 6,
                border: `1px solid ${opt.is_correct ? "var(--success, #2c8a4a)" : "var(--line)"}`,
                background: opt.is_correct ? "rgba(44, 138, 74, 0.07)" : "var(--bg-1)",
              }}>
                <button type="button" onClick={() => setCorrect(i)}
                  style={{
                    width: 18, height: 18, borderRadius: 99,
                    border: `2px solid ${opt.is_correct ? "var(--success, #2c8a4a)" : "var(--ink-3)"}`,
                    background: "transparent", cursor: "pointer", marginTop: 3,
                    display: "grid", placeItems: "center", padding: 0,
                  }}>
                  {opt.is_correct && <span style={{ width: 8, height: 8, borderRadius: 99, background: "var(--success, #2c8a4a)" }}/>}
                </button>
                <span className="muted" style={{ fontFamily: "var(--mono, monospace)", fontSize: 11, marginTop: 6 }}>
                  {opt.letter}
                </span>
                <textarea value={opt.text} onChange={(e) => setOpt(i, { text: e.target.value })} rows={1}
                  style={{
                    flex: 1, padding: "5px 8px", fontSize: 12.5,
                    background: "var(--bg-1)", border: "1px solid var(--line)",
                    borderRadius: 4, color: "var(--ink-0)", resize: "vertical",
                  }}/>
              </div>
            ))}
          </div>
        </AiField>
      )}

      {!isMcq && (
        <AiField label="Expected answer (with units)">
          <input value={expected} onChange={(e) => setExpected(e.target.value)}
            style={{
              width: "100%", padding: "8px 10px", fontSize: 13,
              background: "var(--bg-1)", border: "1px solid var(--line)",
              borderRadius: 6, color: "var(--ink-0)",
            }}
            placeholder="e.g. 17 g/mol"/>
        </AiField>
      )}

      <AiField label="Marks">
        <input type="number" min={1} max={10} value={marks}
          onChange={(e) => setMarks(Math.max(1, Math.min(10, Math.round(Number(e.target.value) || 1))))}
          style={{
            width: 80, padding: "6px 10px", fontSize: 13,
            background: "var(--bg-1)", border: "1px solid var(--line)",
            borderRadius: 6, color: "var(--ink-0)",
          }}/>
      </AiField>

      {err && <div style={{ marginTop: 6, color: "var(--madder, #b14a4a)", fontSize: 12 }}>{err}</div>}

      <div style={{ display: "flex", gap: 8, marginTop: 10 }}>
        <button className="btn sm primary" onClick={save} disabled={!dirty || busy}>
          Save question
        </button>
      </div>
    </div>
  );
};

const AiField = ({ label, children }) => (
  <label style={{ display: "block", marginBottom: 10 }}>
    <div className="muted" style={{ fontSize: 10.5, letterSpacing: ".08em", textTransform: "uppercase", marginBottom: 4 }}>{label}</div>
    {children}
  </label>
);

window.AiReviewScreen = AiReviewScreen;
