// Teacher-facing feature panels: quizzes, homework grading, analytics,
// messaging. Split out of the old features-more.jsx.

// Extract an 11-char YouTube id from any common link form (watch, youtu.be,
// embed, shorts, live) or a bare id. Returns "" if none — keeps the embed URL
// well-formed instead of injecting "null".
const ytId = (url) => {
  if (!url) return "";
  const m = String(url).match(/(?:v=|\/embed\/|\/shorts\/|\/live\/|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
  return m ? m[1] : /^[a-zA-Z0-9_-]{11}$/.test(url) ? url : "";
};

// Fetch a stored course file (base64) and open it in a new tab. PDFs / text /
// images render inline; office formats (ppt/doc) will download — browsers can't
// preview those without an external viewer. MIME resolution is shared + case-
// insensitive (fileMimeType in shared.jsx) so png/webp/gif and odd-cased
// extensions preview instead of downloading.
const openCourseFile = async (courseId, fileId) => {
  if (!courseId || !fileId) return;
  const r = await apiFetch(`/course-files/${courseId}/${fileId}/data`);
  if (!r.ok) { alert("Could not open this file."); return; }
  const { file_data, file_type } = await r.json();
  const bin = atob(file_data), bytes = new Uint8Array(bin.length);
  for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
  const url = URL.createObjectURL(new Blob([bytes], { type: fileMimeType(file_type) }));
  window.open(url, "_blank");
  setTimeout(() => URL.revokeObjectURL(url), 60000);
};

// Small icon-button style for inline edit/move/delete/publish controls.
const CTRL_BTN = { background:"none", border:"none", cursor:"pointer", fontSize:13, padding:"2px 5px", borderRadius:6, lineHeight:1 };

// ── Teacher: Quizzes ──────────────────────────────────────────────────────────
const TeacherQuizzes = ({ dark = false, go, session }) => {
  const [quizzes, setQuizzes] = React.useState(null);
  const { data: initQuizzes } = useApi("/quizzes");
  const { data: allBatches } = useApi("/batches");
  const { data: allCourses } = useApi("/courses/list");
  const list = quizzes ?? initQuizzes;

  const [activeQuiz, setActiveQuiz] = React.useState(null);
  const [view, setView] = React.useState("questions"); // "questions" | "results"
  const [questions, setQuestions] = React.useState([]);
  const [quizResults, setQuizResults] = React.useState([]);
  const [reviewStudent, setReviewStudent] = React.useState(null);
  const [showCreate, setShowCreate] = React.useState(false);
  const [form, setForm] = React.useState({ title:"", batch_id:"", course_id:"", questions:"5", time_limit:"20 minutes", opens_at:"", closes_at:"", allow_retakes: false });
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState("");

  // Question builder state
  const [qType, setQType] = React.useState("mcq");
  const [qText, setQText] = React.useState("");
  const [qOpts, setQOpts] = React.useState(["", ""]);
  const [qCorrect, setQCorrect] = React.useState(0);
  const [qVideo, setQVideo] = React.useState("");
  const [qHint, setQHint] = React.useState("");
  const [qExplanation, setQExplanation] = React.useState("");
  const [qAdding, setQAdding] = React.useState(false);
  const [showAddQ, setShowAddQ] = React.useState(false);

  // B8: Dynamic MCQ option handlers
  const addOpt = () => setQOpts(o => o.length < 6 ? [...o, ""] : o);
  const removeOpt = (idx) => setQOpts(o => {
    if (o.length <= 2) return o;
    const next = o.filter((_, i) => i !== idx);
    if (qCorrect >= next.length) setQCorrect(next.length - 1);
    else if (qCorrect > idx) setQCorrect(qCorrect - 1);
    return next;
  });

  // B4: Inline editing state and handlers
  const [editQId, setEditQId] = React.useState(null);
  const [editQForm, setEditQForm] = React.useState(null);
  const [editQSaving, setEditQSaving] = React.useState(false);
  const [editQErr, setEditQErr] = React.useState("");

  const startEditQ = (qq) => {
    setEditQId(qq.id);
    setEditQErr("");
    const opts = Array.isArray(qq.opts) && qq.opts.length >= 2 ? [...qq.opts] : ["", ""];
    setEditQForm({
      question: qq.q || "",
      type: qq.type || "mcq",
      options: opts,
      correct_ans: typeof qq.ans === "number" ? qq.ans : 0,
      video_url: qq.video_url || "",
      hint: qq.hint || "",
      explanation: qq.explanation || "",
    });
  };

  const cancelEditQ = () => {
    setEditQId(null);
    setEditQForm(null);
    setEditQErr("");
  };

  const saveEditQ = async () => {
    if (!editQForm.question.trim()) { setEditQErr("Question required"); return; }
    if (editQForm.type === "mcq") {
      const opts = editQForm.options.map(o => o.trim()).filter(Boolean);
      if (opts.length < 2) { setEditQErr("At least 2 options required"); return; }
    }
    setEditQSaving(true); setEditQErr("");
    const res = await apiFetch(`/quiz-questions/${editQId}`, {
      method: "PATCH",
      body: JSON.stringify({
        question: editQForm.question.trim(),
        type: editQForm.type,
        options: editQForm.type === "mcq" ? editQForm.options : [],
        correct_ans: editQForm.correct_ans,
        video_url: editQForm.type === "video" ? editQForm.video_url.trim() : null,
        hint: editQForm.hint.trim() || null,
        explanation: editQForm.explanation.trim() || null,
      }),
    });
    setEditQSaving(false);
    if (!res.ok) {
      const d = await res.json().catch(() => ({}));
      setEditQErr(d.error || "Could not update question");
      return;
    }
    cancelEditQ();
    await loadQuestions(activeQuiz);
    refresh();
  };

  // Assignment dialog — mirrors the Homework "Create & assign" targeting so a
  // teacher can point an existing quiz at a whole course or a named few students.
  const [assignQuiz, setAssignQuiz] = React.useState(null);
  const [assignForm, setAssignForm] = React.useState({ course_id:"", batch_id:"" });
  const [assignMode, setAssignMode] = React.useState("all");   // all | selected
  const [roster, setRoster] = React.useState([]);
  const [selectedStudents, setSelectedStudents] = React.useState([]);
  const [assignSaving, setAssignSaving] = React.useState(false);
  const [assignMsg, setAssignMsg] = React.useState(null);

  // Quizzes this teacher has hidden from their own view. Hiding writes only to
  // their account — the Content LMS keeps the quiz for everyone else.
  const [showHidden, setShowHidden] = React.useState(false);
  const [hiddenIds, setHiddenIds] = React.useState([]);

  const quiz = activeQuiz ? list.find(q => q.id === activeQuiz) : null;

  const loadQuestions = (id) => apiFetch(`/quizzes/${id}/questions`).then(r => r.json()).then(setQuestions).catch(() => {});
  const loadResults  = (id) => apiFetch(`/quizzes/${id}/results`).then(r => r.json()).then(setQuizResults).catch(() => {});

  React.useEffect(() => {
    if (!activeQuiz) return;
    loadQuestions(activeQuiz);
    loadResults(activeQuiz);
  }, [activeQuiz]);

  React.useEffect(() => {
    if (allBatches.length && !form.batch_id) setForm(f => ({ ...f, batch_id: String(allBatches[0].id), course_id: String(allBatches[0].course_id || "") }));
  }, [allBatches.length]);

  const refresh = () => apiFetch(`/quizzes${showHidden ? "?include_hidden=1" : ""}`).then(r => r.json()).then(setQuizzes).catch(() => {});
  const refreshHidden = () => apiFetch("/hidden-items").then(r => r.ok ? r.json() : [])
    .then(rows => setHiddenIds((Array.isArray(rows)?rows:[]).filter(r => r.item_type === "quiz").map(r => r.item_id)))
    .catch(() => {});
  React.useEffect(() => { refreshHidden(); }, []);
  React.useEffect(() => { refresh(); }, [showHidden]);

  // ── Assign ─────────────────────────────────────────────────────────────────
  const loadRoster = (courseId) => {
    if (!courseId) { setRoster([]); return Promise.resolve(); }
    return apiFetch(`/courses/${courseId}/roster`).then(r => r.ok ? r.json() : [])
      .then(d => setRoster(Array.isArray(d) ? d : [])).catch(() => setRoster([]));
  };
  const openAssign = async (qz) => {
    // B9: Block quiz assignment if questions < 2
    if ((qz.questions || 0) < 2) {
      alert("Cannot assign quiz with fewer than 2 questions. Please add at least 2 questions first.");
      return;
    }
    setAssignQuiz(qz); setAssignMsg(null);
    setAssignForm({ course_id: qz.course_id ? String(qz.course_id) : "", batch_id: qz.batch_id ? String(qz.batch_id) : "" });
    await loadRoster(qz.course_id);
    const current = await apiFetch(`/quizzes/${qz.id}/assignees`).then(r => r.ok ? r.json() : { student_ids: [] }).catch(() => ({ student_ids: [] }));
    const ids = current.student_ids || [];
    setSelectedStudents(ids);
    setAssignMode(ids.length ? "selected" : "all");
  };
  const onAssignCourse = async (cid) => {
    setAssignForm(f => ({ ...f, course_id: cid }));
    setSelectedStudents([]);
    await loadRoster(cid);
  };
  const saveAssign = async () => {
    if (!assignForm.course_id) { setAssignMsg({ type:"err", text:"Pick a course" }); return; }
    if (assignMode === "selected" && !selectedStudents.length) { setAssignMsg({ type:"err", text:"Pick at least one student, or choose 'All students'." }); return; }
    setAssignSaving(true);
    const res = await apiFetch(`/quizzes/${assignQuiz.id}`, { method:"PATCH", body: JSON.stringify({
      course_id: parseInt(assignForm.course_id),
      batch_id: assignForm.batch_id ? parseInt(assignForm.batch_id) : null,
      student_ids: assignMode === "selected" ? selectedStudents : [],
    })});
    setAssignSaving(false);
    if (!res.ok) { const d = await res.json().catch(()=>({})); setAssignMsg({ type:"err", text: d.error || "Could not assign this quiz" }); return; }
    setAssignQuiz(null);
    refresh();
  };

  // ── Remove ─────────────────────────────────────────────────────────────────
  const archiveQuiz = async (qz) => {
    if (!confirm(`Archive "${qz.title}"?\n\nIt will be retired from student dashboards immediately. Past results are preserved in analytics.`)) return;
    const res = await apiFetch(`/quizzes/${qz.id}/archive`, { method:"POST" });
    if (!res.ok) { const d = await res.json().catch(()=>({})); alert(d.error || "Could not archive quiz."); return; }
    refresh();
  };

  const deleteQuiz = async (qz) => {
    if (!confirm(`Delete quiz "${qz.title}"? This permanently removes the quiz, its questions, and any student results.`)) return;
    const res = await apiFetch(`/quizzes/${qz.id}`, { method:"DELETE" });
    if (!res.ok) { const d = await res.json().catch(()=>({})); alert(d.error || "Could not delete quiz."); return; }
    if (activeQuiz === qz.id) setActiveQuiz(null);
    refresh();
  };
  const hideQuiz = async (qz) => {
    if (!confirm(`Hide "${qz.title}" from your Quizzes view?\n\nIt stays in the Content LMS and stays visible to students and other teachers.`)) return;
    const res = await apiFetch("/hidden-items", { method:"POST", body: JSON.stringify({ item_type:"quiz", item_id:qz.id }) });
    if (!res.ok) { alert("Could not hide quiz."); return; }
    if (activeQuiz === qz.id) setActiveQuiz(null);
    await refreshHidden(); refresh();
  };
  const unhideQuiz = async (qz) => {
    await apiFetch(`/hidden-items/quiz/${qz.id}`, { method:"DELETE" });
    await refreshHidden(); refresh();
  };

  const create = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const payload = {
      title: form.title,
      time_limit: form.time_limit,
      timer_enabled: form.timer_enabled !== false,
      instructions: form.instructions ? form.instructions.trim() : null,
      opens_at: form.opens_at ? new Date(form.opens_at).toISOString() : null,
      closes_at: form.closes_at ? new Date(form.closes_at).toISOString() : null,
      allow_retakes: form.allow_retakes,
    };
    const res = await apiFetch("/quizzes", { method:"POST", body: JSON.stringify(payload) });
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh(); setShowCreate(false); setSaving(false);
    setActiveQuiz(data.id);
    loadQuestions(data.id);
    setTab("builder");
    setForm(f => ({ ...f, title:"", questions:"0", time_limit:"20 minutes", timer_enabled: true, instructions:"", opens_at:"", closes_at:"", allow_retakes: false }));
  };

  const addQuestion = async () => {
    if (!qText.trim() || !activeQuiz) return;
    if (qType === "mcq" && qOpts.some(o => !o.trim())) { setError("Fill in all options"); return; }
    if (qType === "video" && !qVideo.trim()) { setError("Add a video URL"); return; }
    setError(""); setQAdding(true);
    const res = await apiFetch(`/quizzes/${activeQuiz}/questions`, {
      method:"POST",
      body: JSON.stringify({
        question: qText.trim(),
        type: qType,
        options: qType==="mcq" ? qOpts : [],
        correct_ans: qCorrect,
        video_url: qType==="video" ? qVideo.trim() : null,
        hint: qHint.trim() || null,
        explanation: qExplanation.trim() || null,
      })
    });
    if (!res.ok) {
      const d = await res.json().catch(() => ({}));
      setError(d.error || "Failed to add question"); setQAdding(false); return;
    }
    await loadQuestions(activeQuiz);
    await refresh();
    setQText(""); setQOpts(["",""]); setQCorrect(0); setQVideo(""); setQHint(""); setQExplanation(""); setQAdding(false); setShowAddQ(false);
  };

  const deleteQuestion = async (qid) => {
    await apiFetch(`/quiz-questions/${qid}`, { method:"DELETE" });
    await loadQuestions(activeQuiz);
    await refresh();
  };

  const TYPE_COLORS = { mcq:"var(--coral)", paragraph:"var(--moss)", video:"var(--sky)" };

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/quizzes" go={go} session={session}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0 }}>
        <div style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)" }}>
          <div>
            <div className="display" style={{ fontSize:22 }}>Quizzes</div>
            <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{list.length} quizzes</div>
          </div>
          <div style={{ flex:1 }}/>
          {hiddenIds.length > 0 && (
            <button className="btn btn-ghost" onClick={() => setShowHidden(v=>!v)} style={{ padding:"6px 14px", fontSize:12 }}
              title="Quizzes you hid from your own list — the Content LMS still has them">
              {showHidden ? "Hide hidden" : `Show hidden (${hiddenIds.length})`}
            </button>
          )}
          <button className="btn btn-primary" onClick={() => setShowCreate(true)} style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} New quiz</button>
        </div>
        <div style={{ flex:1, display:"flex", overflow:"hidden" }}>
          {/* Quiz list */}
          <div style={{ width:320, borderRight:"var(--border-thin)", overflow:"auto", padding:16, display:"flex", flexDirection:"column", gap:10, flexShrink:0 }}>
            {list.length === 0 ? (
              <div style={{ textAlign:"center", padding:40, color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:10 }}>📝</div>
                <div style={{ fontWeight:700 }}>No quizzes yet</div>
                <button onClick={() => setShowCreate(true)} className="btn btn-primary" style={{ marginTop:14 }}>{I.plus({ size:14 })} Create quiz</button>
              </div>
            ) : list.map(q => {
              const hidden = hiddenIds.includes(q.id);
              const who = q.assigned_count ? `${q.assigned_count} student${q.assigned_count===1?"":"s"}` : "Whole course";
              return (
              <div key={q.id} onClick={() => { setActiveQuiz(q.id); setShowAddQ(false); setView("questions"); }}
                className="card-flat" style={{ padding:14, cursor:"pointer", borderLeft: activeQuiz===q.id ? "3px solid var(--coral)" : "3px solid transparent", opacity: hidden ? .55 : 1 }}>
                <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                  <div style={{ width:36, height:36, borderRadius:10, background:"var(--plum)", color:"white", display:"grid", placeItems:"center", flexShrink:0 }}>{I.puzzle({ size:16 })}</div>
                  <div style={{ flex:1, minWidth:0 }}>
                    <div style={{ fontWeight:700, fontSize:13, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{q.title}</div>
                    <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{q.batch || q.course || "—"} · {q.questions} Qs</div>
                  </div>
                  {q.avgScore != null && <span style={{ fontWeight:800, fontSize:13, color:"var(--moss)" }}>{q.avgScore}%</span>}
                </div>
                <div style={{ display:"flex", alignItems:"center", gap:6, marginTop:10, flexWrap:"wrap" }}>
                  <span title={Array.isArray(q.assignees) && q.assignees.length ? q.assignees.join(", ") : ""}
                    style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background: q.assigned_count ? "var(--plum-deep)" : "var(--sky-deep)", color:"white" }}>{who}</span>
                  {hidden && <span style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background:"var(--ink-mute)", color:"white" }}>hidden for you</span>}
                  {!q.mine && !hidden && <span title="Authored in the Content LMS" style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background:"var(--ink-soft)", color:"white" }}>content</span>}
                  <div style={{ flex:1 }}/>
                  <button onClick={e=>{ e.stopPropagation(); openAssign(q); }} className="btn btn-ghost" style={{ padding:"3px 10px", fontSize:11 }}>Assign</button>
                  {hidden ? (
                    <button onClick={e=>{ e.stopPropagation(); unhideQuiz(q); }} className="btn btn-ghost" style={{ padding:"3px 10px", fontSize:11, color:"var(--moss)" }}>Unhide</button>
                  ) : q.mine ? (<>
                    <button
                      title="Archive — hides from students who haven't taken it yet (can be unarchived any time)"
                      onClick={e=>{ e.stopPropagation(); archiveQuiz(q); }}
                      className="btn btn-ghost"
                      style={{ padding:"3px 10px", fontSize:11, color:"var(--sky-deep)" }}>Archive</button>
                    <button
                      title="Delete permanently — removes the quiz, all questions, and every student result. Cannot be undone."
                      onClick={e=>{ e.stopPropagation(); deleteQuiz(q); }}
                      className="btn btn-ghost"
                      style={{ padding:"3px 10px", fontSize:11, color:"var(--coral)" }}>Delete</button>
                  </>) : (
                    <button title="Hide from your view (can be unhidden anytime — stays active for students and content LMS)" onClick={e=>{ e.stopPropagation(); hideQuiz(q); }} className="btn btn-ghost" style={{ padding:"3px 10px", fontSize:11, color:"var(--ink-mute)" }}>Hide</button>
                  )}
                </div>
              </div>
            );})}
          </div>

          {/* Detail panel */}
          {quiz ? (
            <div style={{ flex:1, display:"flex", flexDirection:"column", overflow:"hidden" }}>
              <div style={{ padding:"12px 20px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12 }}>
                <div>
                  <div className="display" style={{ fontSize:18 }}>{quiz.title}</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)" }}>
                    {quiz.batch || "—"} · {quiz.course || "—"} · Assigned {quiz.assigned} · {quiz.assigned_count ? `${quiz.assigned_count} student${quiz.assigned_count===1?"":"s"}` : "whole course"}
                  </div>
                </div>
                <div style={{ flex:1 }}/>
                <button className="btn btn-ghost" onClick={()=>openAssign(quiz)} style={{ padding:"6px 14px", fontSize:12 }}>{I.users({ size:14 })} Assign</button>
                {/* allow_retakes inline toggle */}
                <button
                  title={quiz.allow_retakes ? "Retakes ON — students can redo this quiz" : "Retakes OFF — one attempt only"}
                  onClick={async () => {
                    const res = await apiFetch(`/quizzes/${quiz.id}`, { method:"PATCH", body: JSON.stringify({ allow_retakes: !quiz.allow_retakes }) });
                    if (res.ok) refresh();
                  }}
                  style={{ padding:"6px 12px", fontSize:11, fontWeight:700, borderRadius:8, border:"var(--border-thin)", cursor:"pointer",
                    background: quiz.allow_retakes ? "var(--moss)" : "var(--paper-deep)",
                    color: quiz.allow_retakes ? "white" : "var(--ink-mute)" }}
                >
                  {quiz.allow_retakes ? "♻ Retakes ON" : "⊘ Retakes OFF"}
                </button>
                <Tabs items={["Questions","Results"]} active={view==="questions"?"Questions":"Results"} onChange={v=>setView(v==="Questions"?"questions":"results")}/>
              </div>

              {view === "questions" ? (
                <div style={{ flex:1, overflow:"auto", padding:20, display:"flex", flexDirection:"column", gap:12 }}>
                  {questions.length === 0 && !showAddQ && (
                    <div style={{ textAlign:"center", padding:40, color:"var(--ink-mute)" }}>
                      <div style={{ fontSize:32, marginBottom:10 }}>🧩</div>
                      <div style={{ fontWeight:700 }}>No questions yet</div>
                      <div style={{ fontSize:13, marginTop:4 }}>Add your first question below</div>
                    </div>
                  )}
                  {questions.map((qq, i) => (
                    <div key={qq.id} className="card-flat" style={{ padding:14 }}>
                      {editQId === qq.id ? (
                        <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
                          <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between" }}>
                            <div className="mono" style={{ fontSize:10, fontWeight:700, color:"var(--ink-mute)" }}>EDIT QUESTION {i+1}</div>
                            <div style={{ display:"flex", gap:6 }}>
                              {["mcq","paragraph","video"].map(t => (
                                <button key={t} type="button" onClick={() => setEditQForm(f=>({...f, type:t}))} style={{ padding:"3px 10px", borderRadius:999, border:"var(--border-thin)", fontSize:11, fontWeight:700, cursor:"pointer", background: editQForm.type===t ? TYPE_COLORS[t] : "var(--paper-deep)", color: editQForm.type===t ? "white" : "var(--ink-mute)" }}>{t.toUpperCase()}</button>
                              ))}
                            </div>
                          </div>
                          <FormField label="QUESTION">
                            <input style={inputStyle} value={editQForm.question} onChange={e=>setEditQForm(f=>({...f, question:e.target.value}))} placeholder="Enter your question…"/>
                          </FormField>
                          {editQForm.type === "mcq" && (
                            <>
                              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:4 }}>OPTIONS · click radio to mark correct</div>
                              {editQForm.options.map((o, oi) => (
                                <div key={oi} style={{ display:"flex", alignItems:"center", gap:8, marginBottom:6 }}>
                                  <input type="radio" name={`edit-correct-${qq.id}`} checked={editQForm.correct_ans===oi} onChange={() => setEditQForm(f=>({...f, correct_ans:oi}))} style={{ accentColor:"var(--moss)", width:16, height:16 }}/>
                                  <input style={{ ...inputStyle, flex:1 }} value={o} onChange={e => { const next=[...editQForm.options]; next[oi]=e.target.value; setEditQForm(f=>({...f, options:next})); }} placeholder={`Option ${String.fromCharCode(65+oi)}`}/>
                                  {editQForm.options.length > 2 && (
                                    <button type="button" onClick={() => {
                                      const next = editQForm.options.filter((_, idx) => idx !== oi);
                                      const curAns = editQForm.correct_ans;
                                      const nextAns = curAns >= next.length ? next.length - 1 : curAns > oi ? curAns - 1 : curAns;
                                      setEditQForm(f=>({...f, options:next, correct_ans: nextAns}));
                                    }} style={{ border:"none", background:"transparent", color:"var(--coral)", cursor:"pointer", padding:"2px 6px", fontSize:14 }}>✕</button>
                                  )}
                                </div>
                              ))}
                              {editQForm.options.length < 6 && (
                                <button type="button" onClick={() => setEditQForm(f=>({...f, options:[...f.options, ""]}))} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, alignSelf:"flex-start", marginBottom:6 }}>+ Add option</button>
                              )}
                            </>
                          )}
                          {editQForm.type === "video" && (
                            <FormField label="YOUTUBE URL">
                              <input style={inputStyle} value={editQForm.video_url} onChange={e=>setEditQForm(f=>({...f, video_url:e.target.value}))} placeholder="https://youtube.com/watch?v=…"/>
                            </FormField>
                          )}
                          <FormField label="HINT (OPTIONAL · ACCESSIBLE DURING QUIZ)">
                            <input style={inputStyle} value={editQForm.hint} onChange={e=>setEditQForm(f=>({...f, hint:e.target.value}))} placeholder="e.g. Remember that index starts at 0"/>
                          </FormField>
                          <FormField label="EXPLANATION (OPTIONAL · REVEALED POST-QUIZ)">
                            <textarea style={{ ...inputStyle, minHeight:48, resize:"vertical" }} value={editQForm.explanation} onChange={e=>setEditQForm(f=>({...f, explanation:e.target.value}))} placeholder="Explanation shown to students after submitting…"/>
                          </FormField>
                          {editQErr && <div style={{ color:"var(--coral)", fontSize:12 }}>{editQErr}</div>}
                          <div style={{ display:"flex", gap:8, justifyContent:"flex-end", marginTop:4 }}>
                            <button type="button" onClick={cancelEditQ} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>Cancel</button>
                            <button type="button" onClick={saveEditQ} disabled={editQSaving} className="btn btn-primary" style={{ padding:"6px 16px", fontSize:12 }}>{editQSaving ? "Saving…" : "Save changes"}</button>
                          </div>
                        </div>
                      ) : (
                        <div style={{ display:"flex", alignItems:"flex-start", gap:10 }}>
                          <div style={{ width:24, height:24, borderRadius:"50%", background:"var(--paper-deep)", border:"var(--border-thin)", display:"grid", placeItems:"center", fontSize:11, fontWeight:800, flexShrink:0, marginTop:2 }}>{i+1}</div>
                          <div style={{ flex:1 }}>
                            <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:6 }}>
                              <span style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background: TYPE_COLORS[qq.type||"mcq"], color:"white" }}>{(qq.type||"mcq").toUpperCase()}</span>
                            </div>
                            <div style={{ fontWeight:600, fontSize:14, marginBottom:8 }}>{qq.q}</div>
                            {(qq.type||"mcq") === "mcq" && qq.opts && (
                              <div style={{ display:"flex", flexDirection:"column", gap:4 }}>
                                {qq.opts.map((o,oi) => (
                                  <div key={oi} style={{ display:"flex", alignItems:"center", gap:8, padding:"5px 10px", borderRadius:8, background: oi===qq.ans ? "var(--paper-card)" : "transparent", border: oi===qq.ans ? "1.5px solid var(--moss)" : "1px solid var(--rule)", fontSize:13 }}>
                                    <span style={{ color: oi===qq.ans ? "var(--moss)" : "var(--ink-mute)", fontWeight:700, fontSize:11 }}>{oi===qq.ans ? "✓" : String.fromCharCode(65+oi)}</span>
                                    {o}
                                  </div>
                                ))}
                              </div>
                            )}
                            {(qq.type) === "video" && qq.video_url && (() => {
                              const m = qq.video_url.match(/(?:v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
                              const vid = m ? m[1] : null;
                              return vid ? (
                                <div style={{ marginTop:8 }}><SafeYouTube videoId={vid} title="Video"/></div>
                              ) : (
                                <div style={{ fontSize:12, color:"var(--sky)", marginTop:4 }}>▶ {qq.video_url}</div>
                              );
                            })()}
                            {(qq.type) === "paragraph" && (
                              <div style={{ fontSize:12, color:"var(--ink-mute)", fontStyle:"italic" }}>Students write a free-text response</div>
                            )}
                            {qq.hint && (
                              <div style={{ fontSize:12, color:"var(--gold-deep)", marginTop:6, display:"flex", alignItems:"center", gap:4 }}>
                                <span>💡 Hint:</span> <span>{qq.hint}</span>
                              </div>
                            )}
                            {qq.explanation && (
                              <div style={{ fontSize:12, color:"var(--moss)", marginTop:4, display:"flex", alignItems:"center", gap:4 }}>
                                <span>📖 Explanation:</span> <span>{qq.explanation}</span>
                              </div>
                            )}
                          </div>
                          <div style={{ display:"flex", alignItems:"center", gap:4 }}>
                            <button title="Edit question" onClick={() => startEditQ(qq)} style={{ border:"none", background:"transparent", color:"var(--ink-mute)", cursor:"pointer", padding:4, borderRadius:6 }}>{I.edit ? I.edit({ size:15 }) : "✏️"}</button>
                            <button title="Delete question" onClick={() => deleteQuestion(qq.id)} style={{ border:"none", background:"transparent", color:"var(--coral)", cursor:"pointer", padding:4, borderRadius:6 }}>{I.x({ size:16 })}</button>
                          </div>
                        </div>
                      )}
                    </div>
                  ))}

                  {/* Add question form */}
                  {showAddQ ? (
                    <div className="card" style={{ padding:18 }}>
                      <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:10 }}>ADD QUESTION</div>
                      <div style={{ display:"flex", gap:8, marginBottom:12 }}>
                        {["mcq","paragraph","video"].map(t => (
                          <button key={t} onClick={() => setQType(t)} style={{ padding:"5px 14px", borderRadius:999, border:"var(--border-thin)", fontSize:12, fontWeight:700, cursor:"pointer", background: qType===t ? TYPE_COLORS[t] : "var(--paper-deep)", color: qType===t ? "white" : "var(--ink-mute)" }}>{t.toUpperCase()}</button>
                        ))}
                      </div>
                      <FormField label="QUESTION">
                        <input style={inputStyle} value={qText} onChange={e=>setQText(e.target.value)} placeholder="Enter your question…"/>
                      </FormField>
                      {qType === "mcq" && (
                        <>
                          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:6, marginTop:4 }}>OPTIONS · click radio to mark correct</div>
                          {qOpts.map((o,i) => (
                            <div key={i} style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                              <input type="radio" name="correct" checked={qCorrect===i} onChange={() => setQCorrect(i)} style={{ accentColor:"var(--moss)", width:16, height:16 }}/>
                              <input style={{ ...inputStyle, flex:1 }} value={o} onChange={e => { const n=[...qOpts]; n[i]=e.target.value; setQOpts(n); }} placeholder={`Option ${String.fromCharCode(65+i)}`}/>
                              {qOpts.length > 2 && (
                                <button type="button" onClick={() => removeOpt(i)} style={{ border:"none", background:"transparent", color:"var(--coral)", cursor:"pointer", padding:"2px 6px", fontSize:14 }}>✕</button>
                              )}
                            </div>
                          ))}
                          {qOpts.length < 6 && (
                            <button type="button" onClick={addOpt} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, marginBottom:10 }}>+ Add option</button>
                          )}
                        </>
                      )}
                      {qType === "video" && (
                        <FormField label="YOUTUBE URL">
                          <input style={inputStyle} value={qVideo} onChange={e=>setQVideo(e.target.value)} placeholder="https://youtube.com/watch?v=…"/>
                        </FormField>
                      )}
                      {qType === "paragraph" && (
                        <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4, padding:"8px 12px", background:"var(--paper-deep)", borderRadius:8 }}>Students will type a paragraph response to this question.</div>
                      )}
                      <FormField label="HINT (OPTIONAL · ACCESSIBLE DURING QUIZ)">
                        <input style={inputStyle} value={qHint} onChange={e=>setQHint(e.target.value)} placeholder="e.g. Think about the order of operations"/>
                      </FormField>
                      <FormField label="EXPLANATION (OPTIONAL · REVEALED AFTER QUIZ SUBMISSION)">
                        <textarea style={{ ...inputStyle, minHeight:48, resize:"vertical" }} value={qExplanation} onChange={e=>setQExplanation(e.target.value)} placeholder="Explanation shown to students after submitting…"/>
                      </FormField>
                      {error && <div style={{ color:"var(--coral)", fontSize:13, marginTop:10 }}>{error}</div>}
                      <div style={{ display:"flex", gap:8, marginTop:12 }}>
                        <button onClick={addQuestion} disabled={qAdding} className="btn btn-primary" style={{ padding:"8px 18px", fontSize:12 }}>{qAdding ? "Adding…" : "Add question"}</button>
                        <button onClick={() => { setShowAddQ(false); setError(""); }} className="btn btn-ghost" style={{ padding:"8px 14px", fontSize:12 }}>Cancel</button>
                      </div>
                    </div>
                  ) : (
                    <button onClick={() => setShowAddQ(true)} className="btn btn-ghost" style={{ padding:"10px 0", fontSize:13, border:"1.5px dashed var(--rule-bold)", borderRadius:12, width:"100%" }}>
                      {I.plus({ size:14 })} Add question
                    </button>
                  )}
                </div>
              ) : (
                <div style={{ flex:1, overflow:"auto", padding:"20px 24px" }}>
                  {/* Deadline banner */}
                  {quiz.closes_at && (
                    <div style={{ marginBottom:18, padding:"10px 16px", borderRadius:12, background:"var(--paper-deep)", border:"var(--border-thin)", fontSize:12, display:"flex", alignItems:"center", justifyContent:"space-between", flexWrap:"wrap", gap:8 }}>
                      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                        <span style={{ fontWeight:700, color:"var(--ink-mute)" }}>Submission Deadline:</span>
                        <span style={{ color: new Date(quiz.closes_at) < new Date() ? "var(--coral)" : "var(--ink)", fontWeight:600 }}>
                          {new Date(quiz.closes_at).toLocaleString("en-IN", { day:"numeric", month:"short", year:"numeric", hour:"2-digit", minute:"2-digit" })}
                        </span>
                      </div>
                      {new Date(quiz.closes_at) < new Date() ? (
                        <span style={{ fontSize:11, fontWeight:700, padding:"2px 8px", borderRadius:999, background:"rgba(var(--coral-rgb,255,90,90),.12)", color:"var(--coral)", border:"1px solid var(--coral)" }}>
                          Window Closed
                        </span>
                      ) : (
                        <span style={{ fontSize:11, fontWeight:700, padding:"2px 8px", borderRadius:999, background:"rgba(var(--moss-rgb,60,180,120),.12)", color:"var(--moss)", border:"1px solid var(--moss)" }}>
                          Open
                        </span>
                      )}
                    </div>
                  )}

                  {/* KPI Summary Cards */}
                  {(() => {
                    const totalEligible = quizResults.length;
                    const completedList = quizResults.filter(r => r.status === "completed");
                    const completedCount = completedList.length;
                    const inProgressCount = quizResults.filter(r => r.status === "in_progress").length;
                    const isClosed = quiz.closes_at && new Date(quiz.closes_at) < new Date();
                    const missedCount = quizResults.filter(r => r.status === "not_attempted" && isClosed).length;
                    const pendingCount = quizResults.filter(r => r.status === "not_attempted" && !isClosed).length;
                    const computedAvg = completedCount > 0
                      ? Math.round(completedList.reduce((acc, r) => acc + (Number(r.score) || 0), 0) / completedCount)
                      : null;
                    const classAvg = quiz.avgScore ?? computedAvg;

                    return (
                      <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit, minmax(130px, 1fr))", gap:12, marginBottom:22 }}>
                        <div style={{ background:"var(--paper-card)", borderRadius:12, padding:"12px 14px", border:"var(--border-thin)", boxShadow:"var(--sh-1)" }}>
                          <div style={{ fontSize:10, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em", textTransform:"uppercase" }}>Total Eligible</div>
                          <div className="display" style={{ fontSize:24, marginTop:4 }}>{totalEligible}</div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>Assigned students</div>
                        </div>
                        <div style={{ background:"var(--paper-card)", borderRadius:12, padding:"12px 14px", border:"var(--border-thin)", boxShadow:"var(--sh-1)" }}>
                          <div style={{ fontSize:10, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em", textTransform:"uppercase" }}>Submitted</div>
                          <div className="display" style={{ fontSize:24, marginTop:4, color:"var(--moss)" }}>{completedCount}</div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>{inProgressCount ? `${inProgressCount} in progress` : "Completed attempts"}</div>
                        </div>
                        <div style={{ background:"var(--paper-card)", borderRadius:12, padding:"12px 14px", border:"var(--border-thin)", boxShadow:"var(--sh-1)" }}>
                          <div style={{ fontSize:10, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em", textTransform:"uppercase" }}>Pending / Missed</div>
                          <div className="display" style={{ fontSize:24, marginTop:4, color: missedCount > 0 ? "var(--coral)" : "var(--ink-soft)" }}>
                            {pendingCount + missedCount}
                          </div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>
                            {missedCount > 0 ? `${missedCount} missed · ${pendingCount} pending` : `${pendingCount} pending`}
                          </div>
                        </div>
                        <div style={{ background:"var(--paper-card)", borderRadius:12, padding:"12px 14px", border:"var(--border-thin)", boxShadow:"var(--sh-1)" }}>
                          <div style={{ fontSize:10, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em", textTransform:"uppercase" }}>Class Average</div>
                          <div className="display" style={{ fontSize:24, marginTop:4, color: classAvg != null ? (classAvg >= 80 ? "var(--moss)" : classAvg >= 60 ? "var(--gold)" : "var(--coral)") : "var(--ink-mute)" }}>
                            {classAvg != null ? `${classAvg}%` : "—"}
                          </div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>Across submissions</div>
                        </div>
                      </div>
                    );
                  })()}

                  {/* Empty state or Results Table */}
                  {quizResults.length === 0 ? (
                    <div style={{ textAlign:"center", padding:"48px 20px", color:"var(--ink-mute)", background:"var(--paper-card)", borderRadius:14, border:"var(--border-thin)" }}>
                      <div style={{ fontSize:14, fontWeight:600, color:"var(--ink-soft)", marginBottom:4 }}>No submissions or assignees yet</div>
                      <div style={{ fontSize:12 }}>Students assigned to this quiz will appear in this table.</div>
                    </div>
                  ) : (
                    <div style={{ background:"var(--paper-card)", borderRadius:14, border:"var(--border-thin)", overflow:"hidden", boxShadow:"var(--sh-1)" }}>
                      <div style={{ overflowX:"auto" }}>
                        <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
                          <thead>
                            <tr style={{ background:"var(--paper-deep)", borderBottom:"var(--border-thin)", textAlign:"left", color:"var(--ink-mute)", fontSize:11, letterSpacing:".06em", textTransform:"uppercase" }}>
                              <th style={{ padding:"12px 16px", fontWeight:700 }}>Student</th>
                              <th style={{ padding:"12px 16px", fontWeight:700 }}>Batch</th>
                              <th style={{ padding:"12px 16px", fontWeight:700 }}>Status</th>
                              <th style={{ padding:"12px 16px", fontWeight:700 }}>Time Taken</th>
                              <th style={{ padding:"12px 16px", fontWeight:700, textAlign:"right" }}>Score</th>
                              <th style={{ padding:"12px 16px", fontWeight:700, textAlign:"center" }}>Action</th>
                            </tr>
                          </thead>
                          <tbody>
                            {quizResults.map((r, i) => {
                              const isCompleted = r.status === "completed";
                              const isInProgress = r.status === "in_progress";
                              const isMissed = r.status === "not_attempted" && quiz.closes_at && new Date(quiz.closes_at) < new Date();

                              return (
                                <tr key={r.student_id || i} style={{ borderTop: i ? "var(--border-thin)" : "none", transition:"background 0.15s" }}>
                                  {/* Student */}
                                  <td style={{ padding:"12px 16px" }}>
                                    <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                                      <Avatar name={r.student ? r.student[0] : "?"} color={r.color} size={28}/>
                                      <span style={{ fontWeight:600, color:"var(--ink)" }}>{r.student}</span>
                                    </div>
                                  </td>

                                  {/* Batch */}
                                  <td style={{ padding:"12px 16px" }}>
                                    <span style={{ fontSize:12, color:"var(--ink-soft)", background:"var(--paper-deep)", padding:"3px 8px", borderRadius:6, border:"var(--border-thin)" }}>
                                      {r.batch || "1-on-1"}
                                    </span>
                                  </td>

                                  {/* Status */}
                                  <td style={{ padding:"12px 16px" }}>
                                    {isCompleted ? (
                                      <span className="chip flat" style={{ fontSize:11, fontWeight:700, padding:"3px 9px", background:"rgba(var(--moss-rgb,60,180,120),.12)", color:"var(--moss)", border:"1px solid var(--moss)", borderRadius:999 }}>
                                        ✓ Completed
                                      </span>
                                    ) : isInProgress ? (
                                      <span className="chip flat" style={{ fontSize:11, fontWeight:700, padding:"3px 9px", background:"rgba(var(--gold-rgb,220,160,40),.12)", color:"var(--gold)", border:"1px solid var(--gold)", borderRadius:999 }}>
                                        ⏱ In Progress
                                      </span>
                                    ) : isMissed ? (
                                      <span className="chip flat" style={{ fontSize:11, fontWeight:700, padding:"3px 9px", background:"rgba(var(--coral-rgb,255,90,90),.12)", color:"var(--coral)", border:"1px solid var(--coral)", borderRadius:999 }}>
                                        ✗ Missed
                                      </span>
                                    ) : (
                                      <span className="chip flat" style={{ fontSize:11, fontWeight:600, padding:"3px 9px", background:"var(--paper-deep)", color:"var(--ink-mute)", border:"var(--border-thin)", borderRadius:999 }}>
                                        ⏳ Pending
                                      </span>
                                    )}
                                  </td>

                                  {/* Time Taken */}
                                  <td style={{ padding:"12px 16px" }}>
                                    {r.time ? (
                                      <div style={{ display:"flex", alignItems:"center", gap:6 }}>
                                        <span style={{ fontSize:12, color:"var(--ink-soft)" }}>{r.time}</span>
                                        {r.is_late && (
                                          <span style={{ fontSize:9, fontWeight:800, padding:"1px 6px", borderRadius:999, background:"var(--coral)", color:"white" }}>
                                            LATE
                                          </span>
                                        )}
                                      </div>
                                    ) : (
                                      <span style={{ color:"var(--ink-mute)", fontSize:12 }}>—</span>
                                    )}
                                  </td>

                                  {/* Score */}
                                  <td style={{ padding:"12px 16px", textAlign:"right" }}>
                                    {r.score != null ? (
                                      <span style={{ fontWeight:800, fontSize:15, color: r.score >= 80 ? "var(--moss)" : r.score >= 60 ? "var(--gold)" : "var(--coral)" }}>
                                        {r.score}%
                                      </span>
                                    ) : (
                                      <span style={{ color:"var(--ink-mute)", fontSize:14 }}>—</span>
                                    )}
                                  </td>

                                  {/* Action */}
                                  <td style={{ padding:"12px 16px", textAlign:"center" }}>
                                    {isCompleted ? (
                                      <button
                                        className="btn btn-ghost"
                                        onClick={() => setReviewStudent({ studentId: r.student_id, studentName: r.student })}
                                        style={{ padding:"4px 10px", fontSize:12, fontWeight:700, color:"var(--plum)", display:"inline-flex", alignItems:"center", gap:4 }}
                                      >
                                        👁 Review
                                      </button>
                                    ) : (
                                      <span style={{ color:"var(--ink-mute)", fontSize:12 }}>—</span>
                                    )}
                                  </td>
                                </tr>
                              );
                            })}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  )}
                </div>
              )}
            </div>
          ) : (
            <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center", color:"var(--ink-mute)", flexDirection:"column", gap:10 }}>
              {I.puzzle({ size:32 })}
              <div style={{ fontSize:14 }}>Select a quiz to view and edit questions</div>
            </div>
          )}
        </div>
      </div>
      {reviewStudent && (
        <QuizReviewModal
          quizId={quiz?.id}
          studentId={reviewStudent.studentId}
          studentName={reviewStudent.studentName}
          onClose={() => setReviewStudent(null)}
          dark={dark}
        />
      )}
      {assignQuiz && (
        <Modal title={`Assign "${assignQuiz.title}"`} onClose={() => setAssignQuiz(null)}>
          <div style={{ display:"flex", flexDirection:"column", gap:14 }}>
            <FormField label="COURSE">
              <select style={selectStyle} value={assignForm.course_id} onChange={e=>onAssignCourse(e.target.value)}>
                <option value="">Select course…</option>
                {allCourses.map(c => <option key={c.id} value={c.id}>{c.name} · {c.level}</option>)}
              </select>
            </FormField>
            <FormField label="BATCH (OPTIONAL)">
              <select style={selectStyle} value={assignForm.batch_id} onChange={e=>setAssignForm(f=>({...f,batch_id:e.target.value}))}>
                <option value="">No specific batch</option>
                {allBatches.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </FormField>
            <FormField label="ASSIGN TO">
              <div style={{ display:"flex", gap:8, marginBottom: assignMode==="selected" ? 10 : 0 }}>
                {[["all","👥 All students in course"],["selected","☑ Selected students"]].map(([m,label])=>(
                  <button key={m} type="button" onClick={()=>setAssignMode(m)}
                    style={{ flex:1, padding:"8px 0", borderRadius:10, border:"var(--border-thin)", fontSize:12, fontWeight:700, cursor:"pointer",
                      background: assignMode===m ? "var(--coral)" : "var(--paper-deep)", color: assignMode===m ? "white" : "var(--ink-mute)" }}>{label}</button>
                ))}
              </div>
              {assignMode==="selected" && (
                <div style={{ border:"var(--border-thin)", borderRadius:8, padding:10, maxHeight:180, overflow:"auto", background:"var(--paper-deep)" }}>
                  {!assignForm.course_id ? (
                    <div style={{ fontSize:12, color:"var(--ink-mute)" }}>Select a course first.</div>
                  ) : roster.length===0 ? (
                    <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No students in this course yet.</div>
                  ) : (
                    <>
                      <label style={{ display:"flex", alignItems:"center", gap:8, fontSize:12, fontWeight:700, paddingBottom:6, marginBottom:6, borderBottom:"var(--border-thin)", cursor:"pointer" }}>
                        <input type="checkbox" checked={selectedStudents.length===roster.length}
                          onChange={e=>setSelectedStudents(e.target.checked ? roster.map(s=>s.id) : [])}/>
                        Select all ({roster.length})
                      </label>
                      {roster.map(s=>(
                        <label key={s.id} style={{ display:"flex", alignItems:"center", gap:8, fontSize:13, padding:"4px 0", cursor:"pointer" }}>
                          <input type="checkbox" checked={selectedStudents.includes(s.id)}
                            onChange={e=>setSelectedStudents(cur => e.target.checked ? [...cur, s.id] : cur.filter(x=>x!==s.id))}/>
                          {s.name}
                        </label>
                      ))}
                      <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:6 }}>{selectedStudents.length} selected</div>
                    </>
                  )}
                </div>
              )}
            </FormField>
            {assignMsg && <div style={{ fontSize:13, fontWeight:600, color: assignMsg.type==="ok" ? "var(--moss)" : "var(--coral)" }}>{assignMsg.text}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end" }}>
              <button type="button" onClick={()=>setAssignQuiz(null)} className="btn btn-ghost">Cancel</button>
              <button type="button" onClick={saveAssign} disabled={assignSaving} className="btn btn-primary">{assignSaving ? "Assigning…" : "Assign quiz"}</button>
            </div>
          </div>
        </Modal>
      )}
      {showCreate && (
        <Modal title="Create quiz" onClose={() => { setShowCreate(false); setError(""); }}>
          <form onSubmit={create}>
            <div style={{ fontSize:12, color:"var(--ink-mute)", marginBottom:12, padding:"8px 12px", background:"var(--paper-deep)", borderRadius:8 }}>
              Quizzes are created as unassigned drafts. Once you add at least 2 questions in the builder, you can assign this quiz to batches or students using the <strong>Assign</strong> button.
            </div>
            <FormField label="TITLE">
              <input required style={inputStyle} value={form.title} onChange={e=>setForm(f=>({...f,title:e.target.value}))} placeholder="e.g. Functions recap"/>
            </FormField>
            <FormField label="INSTRUCTIONS (OPTIONAL)">
              <textarea style={{ ...inputStyle, minHeight:54, resize:"vertical" }} value={form.instructions} onChange={e=>setForm(f=>({...f, instructions:e.target.value}))} placeholder="Read all questions carefully before submitting…"/>
            </FormField>
            <FormField label="TIMER">
              <label style={{ display:"flex", alignItems:"center", gap:8, cursor:"pointer", fontSize:13, fontWeight:600 }}>
                <input type="checkbox" checked={form.timer_enabled} onChange={e=>setForm(f=>({...f, timer_enabled:e.target.checked}))} style={{ accentColor:"var(--moss)", width:16, height:16, cursor:"pointer" }}/>
                Enable countdown timer
              </label>
            </FormField>
            {form.timer_enabled && (
              <FormField label="TIME LIMIT">
                <input style={inputStyle} value={form.time_limit} onChange={e=>setForm(f=>({...f,time_limit:e.target.value}))} placeholder="20 minutes"/>
              </FormField>
            )}
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
              <FormField label="EXAM WINDOW OPENS (OPTIONAL)">
                <input type="datetime-local" style={inputStyle} value={form.opens_at} onChange={e=>setForm(f=>({...f,opens_at:e.target.value}))}/>
              </FormField>
              <FormField label="EXAM WINDOW CLOSES / DEADLINE (OPTIONAL)">
                <input type="datetime-local" style={inputStyle} value={form.closes_at} onChange={e=>setForm(f=>({...f,closes_at:e.target.value}))}/>
              </FormField>
            </div>
            <FormField label="ALLOW RETAKES">
              <div style={{ display:"flex", gap:8 }}>
                {[[false,"⊘ No (single attempt)"],[true,"♻ Yes (students can retry)"]].map(([v,label])=>(
                  <button key={String(v)} type="button" onClick={()=>setForm(f=>({...f,allow_retakes:v}))}
                    style={{ flex:1, padding:"8px 0", borderRadius:10, border:"var(--border-thin)", fontSize:12, fontWeight:700, cursor:"pointer",
                      background: form.allow_retakes===v ? "var(--coral)" : "var(--paper-deep)",
                      color: form.allow_retakes===v ? "white" : "var(--ink-mute)" }}>{label}</button>
                ))}
              </div>
            </FormField>
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:10 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:4 }}>
              <button type="button" onClick={() => { setShowCreate(false); setError(""); }} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving ? "Creating…" : "Create quiz"}</button>
            </div>
          </form>
        </Modal>
      )}
    </Themed>
  );
};

// ── Teacher: Homework Grading + Create ───────────────────────────────────────
const TeacherHomework = ({ dark = false, go, session }) => {
  const { data: HW_SUBMISSIONS, reload: reloadSubmissions } = useApi("/hw-submissions");
  const { data: allCourses } = useApi("/courses/list");
  const { data: allBatches } = useApi("/batches");
  const [tab, setTab] = React.useState("grade"); // "grade" | "batch" | "create" | "manage"
  const [active, setActive] = React.useState(null);
  const [grades, setGrades] = React.useState({});
  const [feedbacks, setFeedbacks] = React.useState({});
  const [saving, setSaving] = React.useState(false);

  // Batch / Session view filters
  const [filterBatch, setFilterBatch] = React.useState("all");
  const [filterHw, setFilterHw] = React.useState("all");

  const [hwForm, setHwForm] = React.useState({ title:"", course_id:"", due_date:"", xp:"40", type:"paragraph", description:"", video_url:"" });
  const [editingHwId, setEditingHwId] = React.useState(null);
  const [hwSaving, setHwSaving] = React.useState(false);
  const [hwError, setHwError] = React.useState("");
  const [hwSuccess, setHwSuccess] = React.useState("");
  // Assignment targeting: "all" students in the course, or a "selected" subset.
  const [assignMode, setAssignMode] = React.useState("all");
  const [roster, setRoster] = React.useState([]);
  const [selectedStudents, setSelectedStudents] = React.useState([]);
  // Optional worksheet/reference file the teacher attaches to the homework.
  const [hwFile, setHwFile] = React.useState(null); // { id, title }
  const [hwUploading, setHwUploading] = React.useState(false);
  const attachHwFile = file => {
    if (!file) return;
    if (!hwForm.course_id) { setHwError("Pick a course before attaching a file."); return; }
    setHwError(""); setHwUploading(true);
    const ext = (file.name.split(".").pop() || "").toLowerCase();
    const reader = new FileReader();
    reader.onload = async () => {
      const base64 = String(reader.result).split(",")[1] || "";
      const res = await apiFetch("/course-files", { method:"POST", body: JSON.stringify({ course_id: parseInt(hwForm.course_id), title: file.name, file_type: ext, file_data: base64 }) });
      const d = await res.json().catch(()=>({}));
      if (!res.ok) { setHwError(d.error || "Upload failed"); setHwUploading(false); return; }
      setHwFile({ id: d.id, title: d.title }); setHwUploading(false);
    };
    reader.onerror = () => { setHwError("Could not read file"); setHwUploading(false); };
    reader.readAsDataURL(file);
  };

  // Load the course roster for the "selected students" picker.
  React.useEffect(() => {
    if (!hwForm.course_id) { setRoster([]); setSelectedStudents([]); return; }
    apiFetch(`/courses/${hwForm.course_id}/roster`).then(r=>r.ok?r.json():[]).then(d=>setRoster(Array.isArray(d)?d:[])).catch(()=>setRoster([]));
    if (!editingHwId) setSelectedStudents([]);
  }, [hwForm.course_id]);

  // "Manage homework" list.
  const { data: initHwList } = useApi("/homework/manage");
  const [hwListLocal, setHwListLocal] = React.useState(null);
  const hwList = hwListLocal ?? (Array.isArray(initHwList) ? initHwList : []);
  const refreshHwList = () => apiFetch("/homework/manage").then(r=>r.json()).then(setHwListLocal).catch(()=>{});
  const deleteHw = async (id, title) => {
    if (!confirm(`Delete homework "${title}"? This also removes its submissions.`)) return;
    const r = await apiFetch(`/homework/${id}`, { method:"DELETE" });
    if (r.ok) refreshHwList();
  };

  const startEditHw = (h) => {
    setEditingHwId(h.id);
    setHwForm({
      title: h.title || "",
      course_id: h.course_id ? String(h.course_id) : "",
      due_date: h.due_date ? String(h.due_date).slice(0, 10) : "",
      xp: String(h.xp || 40),
      type: h.type || "paragraph",
      description: h.description || "",
      video_url: h.video_url || "",
    });
    setHwFile(h.file_id ? { id: h.file_id, title: h.file_name || "Attached file" } : null);
    const assignedIds = Array.isArray(h.student_ids) ? h.student_ids : [];
    setAssignMode(assignedIds.length > 0 ? "selected" : "all");
    setSelectedStudents(assignedIds);
    setHwError("");
    setHwSuccess("");
    setTab("create");
  };

  const saveGrade = async () => {
    if (active == null) return;
    const sub = HW_SUBMISSIONS[active];
    if (!sub) return;
    const gradeToSave = grades[active] || sub.grade;
    if (!gradeToSave) return;
    const feedbackToSave = feedbacks[active] !== undefined ? feedbacks[active] : (sub.feedback || "");
    setSaving(true);
    const r = await apiFetch(`/hw-submissions/${sub.id}`, {
      method: "PATCH",
      body: JSON.stringify({ grade: gradeToSave, feedback: feedbackToSave }),
    }).catch(() => null);
    setSaving(false);
    if (r?.ok) {
      sub.grade = gradeToSave;
      sub.feedback = feedbackToSave;
      if (reloadSubmissions) reloadSubmissions();
      setActive(null);
    }
  };

  const createHw = async e => {
    e.preventDefault(); setHwError(""); setHwSuccess("");
    if (assignMode === "selected" && !selectedStudents.length) { setHwError("Pick at least one student, or choose 'All students'."); return; }
    setHwSaving(true);
    const hwType = hwForm.type || "paragraph";
    const payload = { title: hwForm.title, course_id: parseInt(hwForm.course_id), due_date: hwForm.due_date || null, xp: parseInt(hwForm.xp)||40, type: hwType, description: hwForm.description||"" };
    // Only include video_url when type is "video" — backend enforces the same rule.
    if (hwType === "video" && hwForm.video_url && hwForm.video_url.trim()) {
      payload.video_url = hwForm.video_url.trim();
    }
    if (hwFile) payload.file_id = hwFile.id;
    if (assignMode === "selected") payload.student_ids = selectedStudents;
    else if (editingHwId) payload.student_ids = [];

    const url = editingHwId ? `/homework/${editingHwId}` : "/homework";
    const method = editingHwId ? "PATCH" : "POST";
    const res = await apiFetch(url, { method, body: JSON.stringify(payload) });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) { setHwError(data.error || "Failed"); setHwSaving(false); return; }
    const who = assignMode === "selected" ? `${selectedStudents.length} student${selectedStudents.length===1?"":"s"}` : "the whole course";
    setHwSuccess(editingHwId ? `"${hwForm.title}" updated successfully!` : `"${hwForm.title}" assigned to ${who}!`);
    setHwForm({ title:"", course_id: hwForm.course_id, due_date:"", xp:"40", type:"paragraph", description:"", video_url:"" });
    setHwFile(null);
    setEditingHwId(null);
    setSelectedStudents([]); setAssignMode("all");
    setHwSaving(false);
    refreshHwList();
  };

  const sub = active != null ? HW_SUBMISSIONS[active] : null;

  // Filtered submissions for Batch / Session view
  const batchList = Array.from(new Set(HW_SUBMISSIONS.map(s => s.batch || "1-on-1"))).sort();
  const homeworkList = Array.from(new Set(HW_SUBMISSIONS.map(s => s.hw))).sort();
  const filteredSubmissions = HW_SUBMISSIONS.filter(s => {
    if (filterBatch !== "all" && (s.batch || "1-on-1") !== filterBatch) return false;
    if (filterHw !== "all" && s.hw !== filterHw) return false;
    return true;
  });

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/homework" go={go} session={session}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0 }}>
        <div style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)" }}>
          <div>
            <div className="display" style={{ fontSize:22 }}>Homework</div>
            <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{HW_SUBMISSIONS.filter(s=>!s.grade).length} pending review · {HW_SUBMISSIONS.filter(s=>s.grade).length} graded</div>
          </div>
          <div style={{ flex:1 }}/>
          <Tabs
            items={["Grade submissions", "Batch / Session view", "Create & assign", "Manage"]}
            active={tab==="grade" ? "Grade submissions" : tab==="batch" ? "Batch / Session view" : tab==="create" ? "Create & assign" : "Manage"}
            onChange={v => {
              if (v === "Grade submissions") setTab("grade");
              else if (v === "Batch / Session view") setTab("batch");
              else if (v === "Create & assign") { setEditingHwId(null); setTab("create"); }
              else setTab("manage");
            }}
          />
        </div>

        {tab === "create" ? (
          <div style={{ flex:1, overflow:"auto", padding:32, display:"flex", justifyContent:"center" }}>
            <div style={{ width:"100%", maxWidth:520 }}>
              <div className="display" style={{ fontSize:20, marginBottom:20 }}>
                {editingHwId ? "Edit homework task" : "Create homework"}
              </div>
              <form onSubmit={createHw} style={{ display:"flex", flexDirection:"column", gap:14 }}>
                <FormField label="TYPE">
                  <div style={{ display:"flex", gap:8 }}>
                    {[["paragraph","📝 Paragraph"],["mcq","🔘 MCQ"],["video","▶ Video"]].map(([t,label]) => (
                      <button key={t} type="button" onClick={() => setHwForm(f=>({...f,type:t}))}
                        style={{ flex:1, padding:"8px 0", borderRadius:10, border:"var(--border-thin)", fontSize:12, fontWeight:700, cursor:"pointer",
                          background: (hwForm.type||"paragraph")===t ? "var(--coral)" : "var(--paper-deep)",
                          color: (hwForm.type||"paragraph")===t ? "white" : "var(--ink-mute)" }}>{label}</button>
                    ))}
                  </div>
                </FormField>
                <FormField label="TITLE / SESSION">
                  <input required style={inputStyle} value={hwForm.title} onChange={e=>setHwForm(f=>({...f,title:e.target.value}))} placeholder="e.g. Session 3 - Build a simple calculator"/>
                </FormField>
                <FormField label="INSTRUCTIONS / QUESTION PROMPT">
                  <textarea style={{ ...inputStyle, minHeight:80, resize:"vertical" }} value={hwForm.description||""} onChange={e=>setHwForm(f=>({...f,description:e.target.value}))} placeholder="Describe the question or instructions students need to complete…"/>
                </FormField>
                {(hwForm.type||"paragraph") === "video" && (
                  <FormField label="VIDEO URL">
                    <input style={inputStyle} value={hwForm.video_url||""} onChange={e=>setHwForm(f=>({...f,video_url:e.target.value}))} placeholder="https://youtube.com/watch?v=…"/>
                  </FormField>
                )}
                <FormField label="COURSE">
                  <select required style={selectStyle} value={hwForm.course_id} onChange={e=>setHwForm(f=>({...f,course_id:e.target.value}))}>
                    <option value="">Select course…</option>
                    {allCourses.map(c => <option key={c.id} value={c.id}>{c.name} · {c.level}</option>)}
                  </select>
                </FormField>
                {(hwForm.type||"paragraph") !== "video" && (
                  <FormField label="ATTACH FILE (OPTIONAL)">
                    {hwFile ? (
                      <div style={{ display:"flex", alignItems:"center", gap:8, padding:"8px 10px", borderRadius:8, border:"var(--border-thin)", background:"var(--paper-deep)" }}>
                        <span style={{ fontSize:16 }}>📎</span>
                        <span style={{ flex:1, fontSize:13, fontWeight:600, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{hwFile.title}</span>
                        <button type="button" onClick={()=>setHwFile(null)} className="btn btn-ghost" style={{ padding:"3px 10px", fontSize:11, color:"var(--coral)" }}>Remove</button>
                      </div>
                    ) : (
                      <label style={{ display:"flex", alignItems:"center", gap:8, padding:"10px 12px", borderRadius:8, border:"1.5px dashed var(--rule-bold)", cursor: hwUploading?"default":"pointer", fontSize:13, color:"var(--ink-mute)" }}>
                        {I.plus({ size:14 })} {hwUploading ? "Uploading…" : "Attach a worksheet / reference file"}
                        <input type="file" disabled={hwUploading} style={{ display:"none" }} onChange={e=>{ attachHwFile(e.target.files[0]); e.target.value=""; }}/>
                      </label>
                    )}
                    <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:4 }}>Students can download this when they open the homework.</div>
                  </FormField>
                )}
                <FormField label="ASSIGN TO">
                  <div style={{ display:"flex", gap:8, marginBottom: assignMode==="selected"?10:0 }}>
                    {[["all","👥 All students in course"],["selected","☑ Selected students"]].map(([m,label])=>(
                      <button key={m} type="button" onClick={()=>setAssignMode(m)}
                        style={{ flex:1, padding:"8px 0", borderRadius:10, border:"var(--border-thin)", fontSize:12, fontWeight:700, cursor:"pointer",
                          background: assignMode===m ? "var(--coral)" : "var(--paper-deep)", color: assignMode===m ? "white" : "var(--ink-mute)" }}>{label}</button>
                    ))}
                  </div>
                  {assignMode==="selected" && (
                    <div style={{ border:"var(--border-thin)", borderRadius:8, padding:10, maxHeight:180, overflow:"auto", background:"var(--paper-deep)" }}>
                      {!hwForm.course_id ? (
                        <div style={{ fontSize:12, color:"var(--ink-mute)" }}>Select a course first.</div>
                      ) : roster.length===0 ? (
                        <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No students in this course yet.</div>
                      ) : (
                        <>
                          <label style={{ display:"flex", alignItems:"center", gap:8, fontSize:12, fontWeight:700, paddingBottom:6, marginBottom:6, borderBottom:"var(--border-thin)", cursor:"pointer" }}>
                            <input type="checkbox" checked={selectedStudents.length===roster.length}
                              onChange={e=>setSelectedStudents(e.target.checked ? roster.map(s=>s.id) : [])}/>
                            Select all ({roster.length})
                          </label>
                          {roster.map(s=>(
                            <label key={s.id} style={{ display:"flex", alignItems:"center", gap:8, fontSize:13, padding:"4px 0", cursor:"pointer" }}>
                              <input type="checkbox" checked={selectedStudents.includes(s.id)}
                                onChange={e=>setSelectedStudents(cur => e.target.checked ? [...cur, s.id] : cur.filter(x=>x!==s.id))}/>
                              {s.name}
                            </label>
                          ))}
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:6 }}>{selectedStudents.length} selected</div>
                        </>
                      )}
                    </div>
                  )}
                </FormField>
                <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:12 }}>
                  <FormField label="DUE DATE">
                    <input type="date" style={inputStyle} value={hwForm.due_date} onChange={e=>setHwForm(f=>({...f,due_date:e.target.value}))}/>
                  </FormField>
                  <FormField label="XP REWARD">
                    <input type="number" min="0" style={inputStyle} value={hwForm.xp} onChange={e=>setHwForm(f=>({...f,xp:e.target.value}))}/>
                  </FormField>
                </div>
                {hwError && <div style={{ color:"var(--coral)", fontSize:13 }}>{hwError}</div>}
                {hwSuccess && <div style={{ color:"var(--moss)", fontSize:13, fontWeight:700 }}>✓ {hwSuccess}</div>}
                <div style={{ display:"flex", gap:10 }}>
                  {editingHwId && (
                    <button type="button" onClick={() => { setEditingHwId(null); setTab("manage"); }} className="btn btn-ghost" style={{ padding:"12px 20px", fontSize:14 }}>Cancel</button>
                  )}
                  <button type="submit" disabled={hwSaving} className="btn btn-primary" style={{ flex:1, padding:"12px 0", fontSize:14 }}>
                    {hwSaving ? (editingHwId ? "Updating…" : "Assigning…") : (editingHwId ? "Update homework" : "Assign homework")}
                  </button>
                </div>
              </form>
            </div>
          </div>
        ) : tab === "batch" ? (
          <div style={{ flex:1, overflow:"auto", padding:24, display:"flex", flexDirection:"column", gap:16 }}>
            {/* Filter Bar */}
            <div style={{ display:"flex", gap:12, alignItems:"center", flexWrap:"wrap", background:"var(--paper-card)", padding:"12px 16px", borderRadius:12, border:"var(--border-thin)" }}>
              <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                <span className="mono" style={{ fontSize:11, color:"var(--ink-mute)", fontWeight:700 }}>BATCH:</span>
                <select style={{ ...selectStyle, padding:"6px 12px", fontSize:12, minWidth:160 }} value={filterBatch} onChange={e => setFilterBatch(e.target.value)}>
                  <option value="all">All Batches ({batchList.length})</option>
                  {batchList.map(b => <option key={b} value={b}>{b}</option>)}
                </select>
              </div>
              <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                <span className="mono" style={{ fontSize:11, color:"var(--ink-mute)", fontWeight:700 }}>TASK / SESSION:</span>
                <select style={{ ...selectStyle, padding:"6px 12px", fontSize:12, minWidth:200 }} value={filterHw} onChange={e => setFilterHw(e.target.value)}>
                  <option value="all">All Tasks ({homeworkList.length})</option>
                  {homeworkList.map(h => <option key={h} value={h}>{h}</option>)}
                </select>
              </div>
              <div style={{ flex:1 }}/>
              <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{filteredSubmissions.length} submissions shown</div>
            </div>

            {filteredSubmissions.length === 0 ? (
              <div style={{ padding:"60px 0", textAlign:"center", color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:10 }}>📂</div>
                <div style={{ fontWeight:700 }}>No homework submissions match this filter</div>
                <div style={{ fontSize:13, marginTop:6 }}>Change the batch or task selection above.</div>
              </div>
            ) : (
              <div style={{ display:"flex", flexDirection:"column", gap:12, maxWidth:900, margin:"0 auto", width:"100%" }}>
                {filteredSubmissions.map((s, i) => {
                  const idxInAll = HW_SUBMISSIONS.findIndex(x => x.id === s.id);
                  return (
                    <div key={s.id || i} className="card" style={{ padding:16, borderLeft: s.grade ? "4px solid var(--moss)" : "4px solid var(--gold)" }}>
                      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"flex-start", gap:12, marginBottom:8, flexWrap:"wrap" }}>
                        <div style={{ fontWeight:800, fontSize:15, color:"var(--ink)" }}>
                          [{s.batch || "1-on-1"}] {s.hw}
                        </div>
                        <div>
                          {s.grade ? (
                            <span className="chip flat" style={{ fontSize:12, fontWeight:700, background:"var(--moss)", color:"white" }}>Grade: {s.grade}</span>
                          ) : (
                            <span className="chip flat" style={{ fontSize:11, fontWeight:700, background:"var(--gold)", color:"white" }}>Pending Review</span>
                          )}
                        </div>
                      </div>

                      <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fit, minmax(200px, 1fr))", gap:8, fontSize:13, marginTop:8, padding:"10px 12px", background:"var(--paper-deep)", borderRadius:8 }}>
                        <div>
                          <span style={{ color:"var(--ink-mute)", fontWeight:600 }}>Submitted by: </span>
                          <span style={{ fontWeight:700, color:"var(--ink)" }}>{s.student}</span>
                        </div>
                        <div>
                          <span style={{ color:"var(--ink-mute)", fontWeight:600 }}>Date/Time: </span>
                          <span className="mono" style={{ fontSize:12, fontWeight:600 }}>{s.submitted}</span>
                          {s.is_late && <span className="chip flat" style={{ marginLeft:6, fontSize:9, background:"var(--coral)", color:"white", fontWeight:700 }}>LATE</span>}
                        </div>
                        <div>
                          <span style={{ color:"var(--ink-mute)", fontWeight:600 }}>Grade: </span>
                          <span style={{ fontWeight:700, color: s.grade ? "var(--moss)" : "var(--gold)" }}>{s.grade || "Pending"}</span>
                        </div>
                      </div>

                      {s.feedback && (
                        <div style={{ marginTop:8, fontSize:12, color:"var(--ink-soft)", background:"var(--paper-card)", padding:"6px 10px", borderRadius:6, border:"var(--border-thin)" }}>
                          <span style={{ fontWeight:700, color:"var(--ink-mute)" }}>Teacher Feedback: </span>
                          {s.feedback}
                        </div>
                      )}

                      <div style={{ marginTop:10, display:"flex", justifyContent:"flex-end" }}>
                        <button
                          onClick={() => {
                            if (idxInAll !== -1) setActive(idxInAll);
                            setTab("grade");
                          }}
                          className="btn btn-ghost"
                          style={{ padding:"4px 12px", fontSize:12 }}>
                          Inspect &amp; Grade →
                        </button>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        ) : tab === "manage" ? (
          <div style={{ flex:1, overflow:"auto", padding:24 }}>
            {hwList.length === 0 ? (
              <div style={{ padding:"60px 0", textAlign:"center", color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:10 }}>📋</div>
                <div style={{ fontWeight:700 }}>No homework created yet</div>
                <div style={{ fontSize:13, marginTop:6 }}>Use “Create &amp; assign” to add homework.</div>
              </div>
            ) : (
              <div style={{ display:"flex", flexDirection:"column", gap:10, maxWidth:820, margin:"0 auto" }}>
                {hwList.map(h => {
                  const who = h.assigned_count === 0 ? "All students in course" : `${h.assigned_count} student${h.assigned_count===1?"":"s"}`;
                  const names = Array.isArray(h.assignees) && h.assignees.length ? h.assignees.join(", ") : "";
                  return (
                    <div key={h.id} className="card-flat" style={{ padding:16, display:"flex", alignItems:"flex-start", gap:14 }}>
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ display:"flex", alignItems:"center", gap:8, flexWrap:"wrap" }}>
                          <span style={{ fontWeight:700, fontSize:14 }}>{h.title}</span>
                          <span className="chip flat" style={{ fontSize:9, padding:"1px 6px", background:"var(--paper-deep)", textTransform:"uppercase" }}>{h.type}</span>
                        </div>
                        <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4 }}>{h.course}{h.due?` · due ${h.due}`:""} · {h.xp} XP</div>
                        {h.description && (
                          <div style={{ fontSize:12, color:"var(--ink-soft)", marginTop:6, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap", maxWidth:480 }}>
                            {h.description}
                          </div>
                        )}
                        <div style={{ display:"flex", alignItems:"center", gap:10, marginTop:8, flexWrap:"wrap" }}>
                          <span title={names} style={{ fontSize:11, fontWeight:700, padding:"2px 8px", borderRadius:999, background: h.assigned_count===0?"var(--sky-deep)":"var(--plum-deep)", color:"white" }}>{who}</span>
                          <span style={{ fontSize:11, color:"var(--ink-mute)" }}>{h.submission_count} submission{h.submission_count===1?"":"s"}</span>
                          {h.file_id && (
                            <button onClick={()=>openCourseFile(h.file_course_id, h.file_id)} className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11, display:"inline-flex", alignItems:"center", gap:4 }}>📎 {h.file_name || "Attachment"}</button>
                          )}
                          {names && <span style={{ fontSize:11, color:"var(--ink-mute)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap", maxWidth:320 }}>({names})</span>}
                        </div>
                      </div>
                      <div style={{ display:"flex", gap:6, flexShrink:0 }}>
                        <button onClick={()=>startEditHw(h)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, color:"var(--sky)" }}>Edit</button>
                        <button onClick={()=>deleteHw(h.id, h.title)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, color:"var(--coral)" }}>Delete</button>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        ) : (
        <div style={{ flex:1, display:"grid", gridTemplateColumns: sub ? "1fr 1.6fr" : "1fr", overflow:"hidden" }}>
          <div style={{ overflow:"auto", padding:18, display:"flex", flexDirection:"column", gap:8 }}>
            {HW_SUBMISSIONS.length === 0 ? (
              <div style={{ padding:"60px 0", textAlign:"center", color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:10 }}>📭</div>
                <div style={{ fontWeight:700 }}>No submissions yet</div>
                <div style={{ fontSize:13, marginTop:6 }}>Students haven't submitted homework yet</div>
              </div>
            ) : HW_SUBMISSIONS.map((s,i) => (
              <div key={i} onClick={() => setActive(active===i?null:i)} className="card-flat" style={{ padding:14, cursor:"pointer", borderLeft: active===i ? "3px solid var(--coral)" : "3px solid transparent", background: active===i ? "var(--paper-card)" : "transparent" }}>
                <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                  <Avatar name={s.student[0]} color={s.color} size={32}/>
                  <div style={{ flex:1 }}>
                    <div style={{ fontWeight:700, fontSize:13 }}>{s.student}</div>
                    <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{s.hw} · {s.submitted}</div>
                  </div>
                  {s.is_late && <span className="chip flat" style={{ fontSize:10, background:"var(--coral)", color:"white", fontWeight:700 }}>LATE</span>}
                  {grades[i] || s.grade
                    ? <span className="chip flat" style={{ fontSize:11, background:"var(--moss)", color:"white" }}>{grades[i] || s.grade}</span>
                    : <span className="chip flat" style={{ fontSize:10, background:"var(--gold)", color:"white" }}>review</span>}
                </div>
              </div>
            ))}
          </div>
          {sub && (
            <div style={{ borderLeft:"var(--border-thin)", padding:22, overflow:"auto", background:"var(--paper-card)", display:"flex", flexDirection:"column", gap:16 }}>
              <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                <Avatar name={sub.student[0]} color={sub.color} size={36}/>
                <div>
                  <div className="display" style={{ fontSize:18 }}>{sub.student}</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{sub.hw} · submitted {sub.submitted}</div>
                </div>
              </div>

              {/* Item 4: Task / Question details with session info */}
              <div style={{ padding:14, borderRadius:10, background:"var(--paper-deep)", border:"var(--border-thin)" }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:4 }}>TASK &amp; QUESTION DETAILS</div>
                <div style={{ fontWeight:700, fontSize:14, color:"var(--ink)" }}>{sub.hw}</div>
                {sub.batch && <div style={{ fontSize:12, color:"var(--sky)", fontWeight:600, marginTop:2 }}>Batch: {sub.batch}</div>}
                {sub.question ? (
                  <div style={{ marginTop:8, fontSize:13, color:"var(--ink-soft)", lineHeight:1.5, whiteSpace:"pre-wrap" }}>
                    {sub.question}
                  </div>
                ) : (
                  <div style={{ marginTop:6, fontSize:12, color:"var(--ink-mute)", fontStyle:"italic" }}>No specific instructions recorded.</div>
                )}
              </div>

              <div>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:6 }}>STUDENT SUBMISSION</div>
                {sub.code && (
                  <pre style={{ margin:0, padding:16, background:"oklch(0.18 0.02 250)", color:"oklch(0.92 0.01 250)", borderRadius:10, fontSize:13, lineHeight:1.7, overflowX:"auto", border:"var(--border-thin)" }}>
                    {sub.code}
                  </pre>
                )}
                {sub.drive_link && (
                  <a href={sub.drive_link} target="_blank" rel="noreferrer" style={{ display:"inline-flex", alignItems:"center", gap:6, marginTop:8, fontSize:13, color:"var(--sky)", fontWeight:600 }}>🔗 {sub.drive_link}</a>
                )}
                {sub.file_id && (
                  <button onClick={()=>openCourseFile(sub.file_course_id, sub.file_id)} className="btn btn-ghost" style={{ marginTop:8, padding:"6px 12px", fontSize:12, display:"inline-flex", alignItems:"center", gap:6 }}>📎 {sub.file_name || "Download submitted file"}</button>
                )}
                {!sub.code && !sub.drive_link && !sub.file_id && (
                  <div style={{ fontSize:13, color:"var(--ink-mute)" }}>No content submitted.</div>
                )}
              </div>

              <div>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:8 }}>GRADE &amp; FEEDBACK</div>
                <div style={{ display:"flex", gap:8, flexWrap:"wrap", marginBottom:8 }}>
                  {["100%","90%","80%","70%","60%","Needs redo"].map(g => (
                    <button key={g} onClick={() => setGrades(gr => ({ ...gr, [active]:g }))} style={{ padding:"6px 14px", borderRadius:999, border:"var(--border-thin)", background: (grades[active]||sub.grade)===g ? "var(--coral)" : "var(--paper-deep)", color: (grades[active]||sub.grade)===g ? "white" : "var(--ink)", fontSize:12, fontWeight:700, cursor:"pointer" }}>{g}</button>
                  ))}
                </div>
                <textarea
                  placeholder="Feedback for student & parent (e.g. Great use of variables, try adding comments next time!)…"
                  value={feedbacks[active] !== undefined ? feedbacks[active] : (sub.feedback || "")}
                  onChange={e => setFeedbacks(fb => ({ ...fb, [active]: e.target.value }))}
                  style={{ width:"100%", minHeight:72, padding:"10px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", resize:"vertical", outline:"none", boxSizing:"border-box" }}
                />
                <button className="btn btn-primary" onClick={saveGrade} disabled={saving || (!grades[active] && !sub.grade)} style={{ marginTop:10, width:"100%", padding:"10px 0", fontSize:13 }}>
                  {saving ? "Saving…" : "Save grade & feedback"}
                </button>
              </div>
            </div>
          )}
        </div>
        )}
      </div>
    </Themed>
  );
};

// ── Teacher: Analytics ────────────────────────────────────────────────────────
const TeacherAnalytics = ({ dark = false, go, session }) => {
  const tid = session?.teacherId;
  const { data: dash } = useApi(tid ? `/teacher/dashboard/${tid}` : "/teacher/dashboard/0", {});
  const batches = dash.batches || [];
  const [activeBatch, setActiveBatch] = React.useState(null);
  const batchId = activeBatch || (batches[0] ? batches[0].id : null);
  const activeBatchData = batches.find(b => b.id === batchId) || batches[0] || {};
  const { data: students } = useApi(batchId ? `/students?batch=${batchId}` : "/students");
  return (
  <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
    <TeacherSidebar active="/app/teacher/analytics" go={go} session={session}/>
    <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0 }}>
      <div style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)" }}>
        <div>
          <div className="display" style={{ fontSize:22 }}>Analytics</div>
          <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>My batches · performance overview</div>
        </div>
        <div style={{ flex:1 }}/>
        {batches.length > 0 && <Tabs items={batches.map(b=>b.name)} active={activeBatchData.name || ""} onChange={name => { const b = batches.find(x=>x.name===name); if(b) setActiveBatch(b.id); }}/>}
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22, display:"flex", flexDirection:"column", gap:18 }}>
        {batches.length === 0 ? (
          <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
            <div style={{ fontSize:32, marginBottom:12 }}>📊</div>
            <div style={{ fontWeight:700, fontSize:16 }}>No batches assigned yet</div>
          </div>
        ) : (
        <>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:14 }}>
          {[
            { l:"BATCH STUDENTS", v: activeBatchData.students ?? 0, c:"var(--moss)" },
            { l:"TOTAL BATCHES",  v: batches.length,                 c:"var(--sky)" },
            { l:"AVG XP",         v: students.length ? Math.round(students.reduce((a,s)=>a+(s.xp||0),0)/students.length) : 0, c:"var(--coral)" },
          ].map(k=>(
            <div key={k.l} className="card-flat" style={{ padding:14 }}>
              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>{k.l}</div>
              <div className="display" style={{ fontSize:28, color:k.c, marginTop:4 }}>{k.v}</div>
            </div>
          ))}
        </div>
        <div className="card-flat" style={{ padding:18 }}>
          <SectionHead eyebrow={`${activeBatchData.name || "BATCH"} · ${activeBatchData.course || ""}`} title="Student performance"/>
          <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
            {students.length === 0 ? (
              <div style={{ padding:"24px 0", textAlign:"center", color:"var(--ink-mute)", fontSize:13 }}>No students in this batch yet.</div>
            ) : students.map((r,i) => (
              <div key={i} style={{ display:"flex", alignItems:"center", gap:14 }}>
                <Avatar name={r.name[0]} color={r.color || "var(--coral)"} size={28}/>
                <div style={{ width:80, fontSize:13, fontWeight:600 }}>{r.name}</div>
                <div style={{ flex:1, display:"grid", gridTemplateColumns:"1fr 1fr", gap:8 }}>
                  {[["XP", r.xp ?? 0, "var(--coral)"], ["Status", r.status || "active", r.status==="at-risk"?"var(--gold)":r.status==="churning"?"var(--coral)":"var(--moss)"]].map(([l,v,c])=>(
                    <div key={l} style={{ display:"flex", flexDirection:"column" }}>
                      <div style={{ fontSize:10, color:"var(--ink-mute)" }}>{l}</div>
                      <div style={{ fontWeight:700, fontSize:13, color:c }}>{v}</div>
                    </div>
                  ))}
                </div>
                <div style={{ width:100 }}>
                  <div className="progress" style={{ height:6 }}><i style={{ width:`${Math.min(100, Math.round((r.xp||0)/10))}%`, background:"var(--coral)" }}/></div>
                </div>
              </div>
            ))}
          </div>
        </div>
        <div className="card-flat" style={{ padding:18 }}>
          <SectionHead eyebrow="AT RISK" title="Students to watch"/>
          {students.filter(r => r.status === "at-risk" || r.status === "churning").length === 0 ? (
            <div style={{ padding:"18px 0", textAlign:"center", color:"var(--ink-mute)", fontSize:13 }}>No at-risk students right now.</div>
          ) : students.filter(r => r.status === "at-risk" || r.status === "churning").map((r,i) => (
            <div key={i} style={{ display:"flex", alignItems:"center", gap:10, padding:"8px 0", borderTop: i?"var(--border-thin)":"none" }}>
              <Avatar name={r.name[0]} color={r.color || "var(--coral)"} size={26}/>
              <div style={{ flex:1, fontSize:13 }}>{r.name}</div>
              <span className="chip flat" style={{ fontSize:10, background:"var(--gold)", color:"white" }}>{r.status}</span>
              <button className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11 }}>Notify</button>
            </div>
          ))}
        </div>
        </>
        )}
      </div>
    </div>
  </Themed>
  );
};

// ── Teacher: Messages ─────────────────────────────────────────────────────────
const TeacherMessages = ({ dark = false, go, session }) => {
  const [convos, setConvos] = React.useState(null);
  const { data: initConvos } = useApi("/conversations");
  const list = convos ?? initConvos;
  const [active, setActive] = React.useState(null);
  const [input, setInput] = React.useState("");
  const [localMsgs, setLocalMsgs] = React.useState([]);
  const [showCompose, setShowCompose] = React.useState(false);
  const [composeForm, setComposeForm] = React.useState({ name:"" });
  const [composeSaving, setComposeSaving] = React.useState(false);
  const thread = list.find(m => m.id === active);

  React.useEffect(() => {
    if (!active) return;
    apiFetch(`/conversations/${active}/messages`)
      .then(r => r.json())
      .then(msgs => setLocalMsgs(msgs.map(m => ({ from: m.fromMe ? "me" : "them", text: m.text }))))
      .catch(() => {});
  }, [active]);

  const send = () => {
    if (!input.trim() || !active) return;
    const text = input;
    setLocalMsgs(m => [...m, { from:"me", text }]);
    setInput("");
    apiFetch(`/conversations/${active}/messages`, {
      method:"POST", body: JSON.stringify({ from_me: true, text })
    }).catch(() => {});
  };

  const compose = async e => {
    e.preventDefault();
    if (!composeForm.name.trim()) return;
    setComposeSaving(true);
    const res = await apiFetch("/conversations", { method:"POST", body: JSON.stringify({ name: composeForm.name }) });
    const data = await res.json();
    setComposeSaving(false);
    if (res.ok) {
      setConvos(c => [...(c ?? initConvos), data]);
      setActive(data.id);
      setLocalMsgs([]);
      setShowCompose(false);
      setComposeForm({ name:"" });
    }
  };

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/messages" go={go} session={session}/>
      <div style={{ flex:1, display:"flex", minWidth:0, overflow:"hidden" }}>
        {/* Sidebar */}
        <div style={{ width:260, borderRight:"var(--border-thin)", display:"flex", flexDirection:"column", background:"var(--paper-card)", flexShrink:0 }}>
          <div style={{ padding:"12px 16px", borderBottom:"var(--border-thin)", display:"flex", alignItems:"center", gap:8 }}>
            <div className="display" style={{ fontSize:18, flex:1 }}>Messages</div>
            <button onClick={() => setShowCompose(true)} className="btn btn-primary" style={{ padding:"5px 10px", fontSize:11 }}>{I.plus({ size:13 })} New</button>
          </div>
          <div style={{ flex:1, overflow:"auto" }}>
            {list.length === 0 ? (
              <div style={{ padding:24, textAlign:"center", color:"var(--ink-mute)" }}>
                <div style={{ fontSize:28, marginBottom:8 }}>💬</div>
                <div style={{ fontSize:13, fontWeight:600 }}>No conversations yet</div>
                <button onClick={() => setShowCompose(true)} className="btn btn-ghost" style={{ marginTop:12, fontSize:12 }}>Start one</button>
              </div>
            ) : list.map(m => (
              <div key={m.id} onClick={() => setActive(m.id)} style={{ display:"flex", gap:10, padding:"12px 16px", cursor:"pointer", borderBottom:"var(--border-thin)", background: active===m.id ? "var(--paper-deep)" : "transparent" }}>
                <Avatar name={m.avatar||m.name[0]} color={m.color||"var(--coral)"} size={36}/>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontWeight:700, fontSize:13 }}>{m.name}</div>
                  <div style={{ fontSize:11, color:"var(--ink-mute)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{m.last_msg || "No messages yet"}</div>
                </div>
                {m.unread > 0 && <span style={{ width:18, height:18, borderRadius:"50%", background:"var(--coral)", color:"white", fontSize:10, fontWeight:700, display:"grid", placeItems:"center", flexShrink:0, alignSelf:"center" }}>{m.unread}</span>}
              </div>
            ))}
          </div>
        </div>

        {/* Thread */}
        {thread ? (
          <div style={{ flex:1, display:"flex", flexDirection:"column", background:"var(--paper)" }}>
            <div style={{ padding:"12px 20px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:10 }}>
              <Avatar name={thread.avatar||thread.name[0]} color={thread.color||"var(--coral)"} size={32}/>
              <div className="display" style={{ fontSize:16 }}>{thread.name}</div>
            </div>
            <div style={{ flex:1, overflow:"auto", padding:20, display:"flex", flexDirection:"column", gap:10 }}>
              {localMsgs.length === 0 && (
                <div style={{ textAlign:"center", padding:40, color:"var(--ink-mute)", fontSize:13 }}>No messages yet. Say hello!</div>
              )}
              {localMsgs.map((m,i) => (
                <div key={i} style={{ display:"flex", justifyContent: m.from==="me"?"flex-end":"flex-start" }}>
                  <div style={{ maxWidth:"70%", padding:"10px 14px", borderRadius:14, background: m.from==="me"?"var(--coral)":"var(--paper-card)", color: m.from==="me"?"white":"var(--ink)", fontSize:14, lineHeight:1.5, border: m.from==="me"?"none":"var(--border-thin)" }}>
                    {m.text}
                  </div>
                </div>
              ))}
            </div>
            <div style={{ padding:"12px 20px", borderTop:"var(--border-thin)", display:"flex", gap:10 }}>
              <input value={input} onChange={e=>setInput(e.target.value)} onKeyDown={e=>e.key==="Enter"&&send()} placeholder="Type a message…" style={{ flex:1, padding:"10px 14px", border:"var(--border-thin)", borderRadius:999, background:"var(--paper-card)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }}/>
              <button onClick={send} className="btn btn-primary" style={{ padding:"10px 18px", fontSize:13 }}>{I.send({ size:16 })}</button>
            </div>
          </div>
        ) : (
          <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center", color:"var(--ink-mute)", flexDirection:"column", gap:12 }}>
            {I.send({ size:32 })}
            <div style={{ fontSize:14 }}>Select a conversation to start messaging</div>
          </div>
        )}
      </div>

      {showCompose && (
        <Modal title="New conversation" onClose={() => setShowCompose(false)}>
          <form onSubmit={compose}>
            <FormField label="RECIPIENT NAME">
              <input required style={inputStyle} value={composeForm.name} onChange={e=>setComposeForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Priya Sharma (Parent)"/>
            </FormField>
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:4 }}>
              <button type="button" onClick={() => setShowCompose(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={composeSaving} className="btn btn-primary">{composeSaving ? "Creating…" : "Start conversation"}</button>
            </div>
          </form>
        </Modal>
      )}
    </Themed>
  );
};
