// ── 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 [showCreate, setShowCreate] = React.useState(false);
  const [form, setForm] = React.useState({ title:"", batch_id:"", course_id:"", questions:"5", time_limit:"20 minutes" });
  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 [qAdding, setQAdding] = React.useState(false);
  const [showAddQ, setShowAddQ] = React.useState(false);

  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").then(r => r.json()).then(setQuizzes);

  const create = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/quizzes", { method:"POST", body: JSON.stringify({ title: form.title, batch_id: parseInt(form.batch_id), course_id: parseInt(form.course_id), questions: parseInt(form.questions)||5, time_limit: form.time_limit }) });
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh(); setShowCreate(false); setSaving(false);
    setForm(f => ({ ...f, title:"", questions:"5", time_limit:"20 minutes" }));
  };

  const addQuestion = async () => {
    if (!qText.trim() || !activeQuiz) return;
    if (qType === "mcq" && qOpts.some(o => !o.trim())) return;
    setQAdding(true);
    await apiFetch(`/quizzes/${activeQuiz}/questions`, {
      method:"POST",
      body: JSON.stringify({ question: qText, type: qType, options: qType==="mcq" ? qOpts : [], correct_ans: qCorrect, video_url: qType==="video" ? qVideo : null })
    });
    await loadQuestions(activeQuiz);
    await refresh();
    setQText(""); setQOpts(["","","",""]); setQCorrect(0); setQVideo(""); 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 }}/>
          <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 => (
              <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" }}>
                <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 }}>{q.title}</div>
                    <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{q.batch} · {q.questions} Qs</div>
                  </div>
                  {q.avgScore != null && <span style={{ fontWeight:800, fontSize:13, color:"var(--moss)" }}>{q.avgScore}%</span>}
                </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}</div>
                </div>
                <div style={{ flex:1 }}/>
                <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 }}>
                      <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, borderRadius:8, overflow:"hidden", position:"relative", paddingBottom:"56.25%", background:"#000" }}>
                                <iframe src={`https://www.youtube.com/embed/${vid}`} title="Video" style={{ position:"absolute", top:0, left:0, width:"100%", height:"100%", border:"none" }} allowFullScreen/>
                              </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>
                          )}
                        </div>
                        <button 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>
                  ))}

                  {/* 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)}`}/>
                            </div>
                          ))}
                        </>
                      )}
                      {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>
                      )}
                      <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)} 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:20 }}>
                  {quizResults.length === 0 ? (
                    <div style={{ textAlign:"center", padding:40, color:"var(--ink-mute)" }}>No submissions yet.</div>
                  ) : quizResults.map((r,i) => (
                    <div key={i} style={{ display:"flex", alignItems:"center", gap:12, padding:"10px 0", borderTop: i ? "var(--border-thin)" : "none" }}>
                      <Avatar name={r.student[0]} color={r.color} size={32}/>
                      <div style={{ flex:1 }}>
                        <div style={{ fontWeight:600, fontSize:13 }}>{r.student}</div>
                        {r.time && <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{r.time}</div>}
                      </div>
                      {r.status==="absent"
                        ? <span className="chip flat" style={{ fontSize:10, background:"var(--coral)", color:"white" }}>absent</span>
                        : <span style={{ fontWeight:800, fontSize:15, color: r.score>=80?"var(--moss)":r.score>=60?"var(--gold)":"var(--coral)" }}>{r.score}%</span>}
                    </div>
                  ))}
                  {quiz.avgScore && (
                    <div style={{ marginTop:20, padding:14, background:"var(--paper-deep)", borderRadius:12, border:"var(--border-thin)", textAlign:"center" }}>
                      <div style={{ fontSize:11, color:"var(--ink-mute)" }}>Class average</div>
                      <div className="display" style={{ fontSize:32, color:"var(--moss)" }}>{quiz.avgScore}%</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>
      {showCreate && (
        <Modal title="Create quiz" onClose={() => { setShowCreate(false); setError(""); }}>
          <form onSubmit={create}>
            <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="BATCH">
              <select required style={selectStyle} value={form.batch_id} onChange={e => {
                const b = allBatches.find(x => String(x.id) === e.target.value);
                setForm(f => ({ ...f, batch_id: e.target.value, course_id: b?.course_id ? String(b.course_id) : f.course_id }));
              }}>
                <option value="">Select batch…</option>
                {allBatches.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </FormField>
            <FormField label="COURSE">
              <select required style={selectStyle} value={form.course_id} onChange={e=>setForm(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>
            <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>
            {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 } = useApi("/hw-submissions");
  const { data: allCourses } = useApi("/courses/list");
  const [tab, setTab] = React.useState("grade");
  const [active, setActive] = React.useState(null);
  const [grades, setGrades] = React.useState({});
  const [saving, setSaving] = React.useState(false);

  const [hwForm, setHwForm] = React.useState({ title:"", course_id:"", due_date:"", xp:"40", type:"paragraph", description:"", video_url:"" });
  const [hwSaving, setHwSaving] = React.useState(false);
  const [hwError, setHwError] = React.useState("");
  const [hwSuccess, setHwSuccess] = React.useState("");

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

  const createHw = async e => {
    e.preventDefault(); setHwError(""); setHwSuccess(""); setHwSaving(true);
    const res = await apiFetch("/homework", { method:"POST", body: JSON.stringify({ title: hwForm.title, course_id: parseInt(hwForm.course_id), due_date: hwForm.due_date || null, xp: parseInt(hwForm.xp)||40, type: hwForm.type||"paragraph", description: hwForm.description||"" }) });
    const data = await res.json();
    if (!res.ok) { setHwError(data.error||"Failed"); setHwSaving(false); return; }
    setHwSuccess(`"${hwForm.title}" assigned successfully!`);
    setHwForm({ title:"", course_id: hwForm.course_id, due_date:"", xp:"40", type:"paragraph", description:"", video_url:"" });
    setHwSaving(false);
  };

  const sub = active != null ? HW_SUBMISSIONS[active] : null;
  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","Create & assign"]} active={tab==="grade"?"Grade submissions":"Create & assign"} onChange={v=>setTab(v==="Grade submissions"?"grade":"create")}/>
        </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 }}>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">
                  <input required style={inputStyle} value={hwForm.title} onChange={e=>setHwForm(f=>({...f,title:e.target.value}))} placeholder="e.g. Build a simple calculator"/>
                </FormField>
                <FormField label="INSTRUCTIONS">
                  <textarea style={{ ...inputStyle, minHeight:80, resize:"vertical" }} value={hwForm.description||""} onChange={e=>setHwForm(f=>({...f,description:e.target.value}))} placeholder="Describe what students need to do…"/>
                </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>
                <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>}
                <button type="submit" disabled={hwSaving} className="btn btn-primary" style={{ padding:"12px 0", fontSize:14 }}>{hwSaving ? "Assigning…" : "Assign homework"}</button>
              </form>
            </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>
                  {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>
              <div>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:6 }}>SUBMISSION</div>
                <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>
              </div>
              <div>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:8 }}>GRADE</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 (optional)…" 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:"none", outline:"none", boxSizing:"border-box" }}/>
                <button className="btn btn-primary" onClick={saveGrade} disabled={saving || !grades[active]} style={{ marginTop:10, width:"100%", padding:"10px 0", fontSize:13 }}>{saving ? "Saving…" : "Save grade & notify parent"}</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>
  );
};

// ── Admin: Courses & Content ──────────────────────────────────────────────────
const COURSE_COLORS = ["var(--coral)","var(--sky)","var(--moss)","var(--plum)","var(--gold)"];

// ── Course Edit Panel ─────────────────────────────────────────────────────────
const FILE_ICONS = { pdf:"📄", txt:"📝", ppt:"📊", pptx:"📊" };
const PERM_LIST = [
  { key:"manage_students",     label:"Manage Students" },
  { key:"manage_teachers",     label:"Manage Teachers" },
  { key:"manage_batches",      label:"Manage Batches" },
  { key:"manage_courses",      label:"Manage Courses" },
  { key:"manage_schedule",     label:"Manage Schedule" },
  { key:"manage_billing",      label:"Manage Billing" },
  { key:"manage_quizzes",      label:"Manage Quizzes" },
  { key:"manage_homework",     label:"Manage Homework" },
  { key:"view_analytics",      label:"View Analytics" },
  { key:"manage_users",        label:"Manage Users" },
  { key:"broadcast",           label:"Broadcast" },
  { key:"manage_kits",         label:"Manage Kits" },
  { key:"manage_certificates", label:"Manage Certificates" },
  { key:"manage_roles",        label:"Manage Roles (super only)" },
  { key:"upload_content",      label:"Upload Course Content" },
  { key:"view_courses",        label:"View Courses (student)" },
  { key:"take_quiz",           label:"Take Quizzes (student)" },
  { key:"submit_homework",     label:"Submit Homework (student)" },
  { key:"view_dashboard",      label:"View Dashboard (parent)" },
];

const getCourseRole = () => (typeof currentRole === "function" ? currentRole() || "" : "");

const CourseEditPanel = ({ course, courseContent, onClose, onRefreshContent, onDeleteCourse }) => {
  const isAdmin = ["admin","superadmin"].includes(getCourseRole());
  const [tab, setTab] = React.useState("units");
  const [unitTitle, setUnitTitle] = React.useState("");
  const [addingUnit, setAddingUnit] = React.useState(false);
  const [unitError, setUnitError] = React.useState("");
  const [deleting, setDeleting] = React.useState(false);
  const [deleteError, setDeleteError] = React.useState("");

  // Assignment tab state
  const [assignedData, setAssignedData] = React.useState(null);
  const [availBatches, setAvailBatches] = React.useState(null);
  const [availStudents, setAvailStudents] = React.useState(null);
  const [selBatch, setSelBatch] = React.useState("");
  const [selStudent, setSelStudent] = React.useState("");
  const [assignSaving, setAssignSaving] = React.useState(false);
  const [assignError, setAssignError] = React.useState("");

  const loadAssigned = React.useCallback(() => {
    if (!course) return;
    apiFetch(`/courses/${course.id}/assigned`).then(r=>r.json()).then(setAssignedData);
    apiFetch(`/courses/${course.id}/available-batches`).then(r=>r.json()).then(setAvailBatches);
    apiFetch(`/courses/${course.id}/available-students`).then(r=>r.json()).then(setAvailStudents);
  }, [course?.id]);

  React.useEffect(() => { if (tab === "assign") loadAssigned(); }, [tab, course?.id]);

  const assignBatch = async () => {
    if (!selBatch) return;
    setAssignSaving(true); setAssignError("");
    const res = await apiFetch(`/courses/${course.id}/assign-batch`, { method:"POST", body: JSON.stringify({ batch_id: parseInt(selBatch) }) });
    if (!res.ok) { const d=await res.json(); setAssignError(d.error||"Failed"); setAssignSaving(false); return; }
    setSelBatch(""); setAssignSaving(false); loadAssigned();
  };

  const assignStudent = async () => {
    if (!selStudent) return;
    setAssignSaving(true); setAssignError("");
    const res = await apiFetch(`/courses/${course.id}/assign-student`, { method:"POST", body: JSON.stringify({ student_id: parseInt(selStudent) }) });
    if (!res.ok) { const d=await res.json(); setAssignError(d.error||"Failed"); setAssignSaving(false); return; }
    setSelStudent(""); setAssignSaving(false); loadAssigned();
  };

  const removeStudent = async (sid) => {
    await apiFetch(`/courses/${course.id}/students/${sid}`, { method:"DELETE" });
    loadAssigned();
  };
  const { data: initFiles,    loading: filesLoading }    = useApi(course ? `/course-files/${course.id}` : null);
  const { data: initHomework, loading: hwLoading }       = useApi(course ? `/courses/${course.id}/homework` : null);
  const { data: initQuizzes, loading: quizzesLoading }   = useApi(course ? `/courses/${course.id}/quizzes` : null);
  const { data: BATCHES } = useApi("/batches");
  const [files,    setFiles]    = React.useState(null);
  const [homework, setHomework] = React.useState(null);
  const [quizzes,  setQuizzes]  = React.useState(null);
  const [uploading, setUploading] = React.useState(false);
  const [hwForm,   setHwForm]   = React.useState({ title:"", due_date:"", xp:"40", type:"paragraph", description:"" });
  const [qForm,    setQForm]    = React.useState({ title:"", batch_id:"", time_limit:"20 minutes" });
  const [saving,   setSaving]   = React.useState(false);

  const fileList = files    ?? initFiles    ?? [];
  const hwList   = homework ?? initHomework ?? [];
  const qList    = quizzes  ?? initQuizzes  ?? [];

  const refreshFiles    = () => apiFetch(`/course-files/${course.id}`).then(r=>r.json()).then(setFiles);
  const refreshHomework = () => apiFetch(`/courses/${course.id}/homework`).then(r=>r.json()).then(setHomework);
  const refreshQuizzes  = () => apiFetch(`/courses/${course.id}/quizzes`).then(r=>r.json()).then(setQuizzes);

  const uploadFile = async e => {
    const file = e.target.files[0];
    if (!file) return;
    setUploading(true);
    const ext = file.name.split(".").pop().toLowerCase();
    const reader = new FileReader();
    reader.onload = async ev => {
      const base64 = ev.target.result.split(",")[1];
      await apiFetch("/course-files", { method:"POST", body: JSON.stringify({ course_id: course.id, title: file.name, file_type: ext, file_data: base64 }) });
      await refreshFiles();
      setUploading(false);
    };
    reader.readAsDataURL(file);
    e.target.value = "";
  };

  const deleteFile = async id => {
    await apiFetch(`/course-files/${id}`, { method:"DELETE" });
    setFiles(prev => (prev ?? initFiles ?? []).filter(f=>f.id!==id));
  };

  const viewFile = async (fileId, title, fileType) => {
    const r = await apiFetch(`/course-files/${course.id}/${fileId}/data`);
    const { file_data, file_type } = await r.json();
    const mime = file_type==="pdf" ? "application/pdf" : file_type==="txt" ? "text/plain" : "application/octet-stream";
    const url = `data:${mime};base64,${file_data}`;
    if (file_type === "txt") {
      const decoded = atob(file_data);
      const win = window.open("","_blank");
      win.document.write(`<pre style="font-family:monospace;white-space:pre-wrap;padding:20px">${decoded}</pre>`);
    } else {
      const a = document.createElement("a"); a.href = url; a.download = title; a.click();
    }
  };

  const addHomework = async e => {
    e.preventDefault(); setSaving(true);
    await apiFetch("/homework", { method:"POST", body: JSON.stringify({ ...hwForm, course_id: course.id, xp: parseInt(hwForm.xp)||40 }) });
    await refreshHomework();
    setHwForm({ title:"", due_date:"", xp:"40", type:"paragraph", description:"" });
    setSaving(false);
  };

  const addQuiz = async e => {
    e.preventDefault(); setSaving(true);
    await apiFetch("/quizzes", { method:"POST", body: JSON.stringify({ title: qForm.title, course_id: course.id, batch_id: parseInt(qForm.batch_id)||null, time_limit: qForm.time_limit, questions:0 }) });
    await refreshQuizzes();
    setQForm({ title:"", batch_id:"", time_limit:"20 minutes" });
    setSaving(false);
  };

  const saveUnit = async () => {
    if (!unitTitle.trim()) { setUnitError("Title required"); return; }
    setUnitError(""); setAddingUnit(true);
    const res = await apiFetch(`/courses/${course.id}/units`, { method:"POST", body: JSON.stringify({ title: unitTitle.trim() }) });
    if (!res.ok) { const d=await res.json(); setUnitError(d.error||"Failed"); setAddingUnit(false); return; }
    setUnitTitle(""); setAddingUnit(false);
    if (onRefreshContent) onRefreshContent();
  };

  const pStyle = { padding:"6px 10px", borderRadius:6, border:"none", fontSize:11, cursor:"pointer", fontWeight:600 };
  const tabs = [["units","Units"],["assign","Assign"],["files","Files"],["homework","Homework"],["quizzes","Quizzes"]];

  const handleDelete = async () => {
    if (!window.confirm(`Delete "${course.title}"? This cannot be undone.`)) return;
    setDeleting(true); setDeleteError("");
    const res = await apiFetch(`/courses/${course.id}`, { method:"DELETE" });
    if (res.ok) { onDeleteCourse && onDeleteCourse(course.id); onClose(); }
    else { const d=await res.json(); setDeleteError(d.error||"Failed"); setDeleting(false); }
  };

  return (
    <div style={{ width:340, borderLeft:"var(--border-thin)", display:"flex", flexDirection:"column", flexShrink:0, background:"var(--paper-card)" }}>
      <div style={{ padding:"14px 16px", borderBottom:"var(--border-thin)" }}>
        <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
          <div className="display" style={{ fontSize:16, flex:1 }}>{course.title}</div>
          {isAdmin && (
            <button onClick={handleDelete} disabled={deleting} style={{ ...pStyle, background:"var(--coral)", color:"white" }} title="Delete course">
              {deleting ? "…" : "Delete"}
            </button>
          )}
          <button onClick={onClose} style={{ ...pStyle, background:"var(--paper-deep)", color:"var(--ink-soft)" }}>✕</button>
        </div>
        {deleteError && <div style={{ color:"var(--coral)", fontSize:11, marginBottom:6, padding:"4px 8px", background:"rgba(255,80,80,.1)", borderRadius:4 }}>{deleteError}</div>}
        <div style={{ display:"flex", gap:4, flexWrap:"wrap" }}>
          {tabs.map(([k,l])=>(
            <button key={k} onClick={()=>setTab(k)} style={{ ...pStyle, background: tab===k?"var(--coral)":"var(--paper-deep)", color: tab===k?"white":"var(--ink-soft)" }}>{l}</button>
          ))}
        </div>
      </div>

      <div style={{ flex:1, overflow:"auto", padding:14 }}>
        {tab === "units" && (
          <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
            {/* Add unit form */}
            <div style={{ background:"var(--paper-deep)", borderRadius:8, padding:10, border:"var(--border-thin)" }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:6, letterSpacing:".06em" }}>ADD UNIT</div>
              <div style={{ display:"flex", gap:6 }}>
                <input
                  value={unitTitle}
                  onChange={e=>setUnitTitle(e.target.value)}
                  placeholder="e.g. Unit 1 · Getting Started"
                  style={{ flex:1, padding:"6px 10px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none" }}
                  onKeyDown={async e => { if (e.key==="Enter") { e.preventDefault(); await saveUnit(); } }}
                />
                <button
                  disabled={addingUnit}
                  onClick={async () => { await saveUnit(); }}
                  className="btn btn-primary"
                  style={{ padding:"6px 12px", fontSize:12 }}>
                  {addingUnit ? "…" : "+ Add"}
                </button>
              </div>
              {unitError && <div style={{ color:"var(--coral)", fontSize:11, marginTop:4 }}>{unitError}</div>}
            </div>

            {courseContent.length === 0
              ? <div style={{ fontSize:12, color:"var(--ink-mute)", padding:"4px 0" }}>No units yet — add one above.</div>
              : courseContent.map(u=>(
                <div key={u.id} style={{ padding:"8px 10px", background:"var(--paper-deep)", borderRadius:8, border:"var(--border-thin)" }}>
                  <div style={{ fontWeight:700, fontSize:12 }}>{u.unit}</div>
                  <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>{u.lessons?.length ?? 0} lessons</div>
                </div>
              ))
            }
          </div>
        )}

        {tab === "assign" && (
          <div style={{ display:"flex", flexDirection:"column", gap:12 }}>
            {/* Batches */}
            <div style={{ background:"var(--paper-deep)", borderRadius:8, padding:10, border:"var(--border-thin)" }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:8, letterSpacing:".06em" }}>ASSIGN BATCH</div>
              <div style={{ display:"flex", gap:6, marginBottom:8 }}>
                <select value={selBatch} onChange={e=>setSelBatch(e.target.value)}
                  style={{ flex:1, padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none" }}>
                  <option value="">— pick a batch —</option>
                  {(availBatches||[]).map(b=>(
                    <option key={b.id} value={b.id}>{b.name}{b.current_course ? ` (currently: ${b.current_course})` : ""}</option>
                  ))}
                </select>
                <button onClick={assignBatch} disabled={!selBatch||assignSaving} className="btn btn-primary" style={{ padding:"6px 12px", fontSize:12 }}>
                  {assignSaving ? "…" : "Assign"}
                </button>
              </div>
              {(assignedData?.batches||[]).length === 0
                ? <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No batches assigned yet.</div>
                : (assignedData.batches||[]).map(b=>(
                  <div key={b.id} style={{ display:"flex", alignItems:"center", gap:8, padding:"6px 10px", background:"var(--paper-card)", borderRadius:6, border:"var(--border-thin)", marginBottom:4 }}>
                    <div style={{ flex:1 }}>
                      <div style={{ fontSize:12, fontWeight:600 }}>{b.name}</div>
                      <div style={{ fontSize:10, color:"var(--ink-mute)" }}>{b.students} student{b.students!==1?"s":""}</div>
                    </div>
                  </div>
                ))
              }
            </div>
            {/* Individual students */}
            <div style={{ background:"var(--paper-deep)", borderRadius:8, padding:10, border:"var(--border-thin)" }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:8, letterSpacing:".06em" }}>ASSIGN INDIVIDUAL STUDENT</div>
              <div style={{ display:"flex", gap:6, marginBottom:8 }}>
                <select value={selStudent} onChange={e=>setSelStudent(e.target.value)}
                  style={{ flex:1, padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none" }}>
                  <option value="">— pick a student —</option>
                  {(availStudents||[]).map(s=>(
                    <option key={s.id} value={s.id}>{s.name}{s.age ? ` (age ${s.age})` : ""}</option>
                  ))}
                </select>
                <button onClick={assignStudent} disabled={!selStudent||assignSaving} className="btn btn-primary" style={{ padding:"6px 12px", fontSize:12 }}>
                  {assignSaving ? "…" : "Assign"}
                </button>
              </div>
              {assignError && <div style={{ color:"var(--coral)", fontSize:11, marginBottom:6 }}>{assignError}</div>}
              {(assignedData?.students||[]).length === 0
                ? <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No individual students assigned yet.</div>
                : (assignedData.students||[]).map(s=>(
                  <div key={s.id} style={{ display:"flex", alignItems:"center", gap:8, padding:"6px 10px", background:"var(--paper-card)", borderRadius:6, border:"var(--border-thin)", marginBottom:4 }}>
                    <div style={{ flex:1 }}>
                      <div style={{ fontSize:12, fontWeight:600 }}>{s.name}</div>
                      <div style={{ fontSize:10, color:"var(--ink-mute)" }}>Age {s.age||"—"} · {s.xp||0} XP</div>
                    </div>
                    <button onClick={()=>removeStudent(s.id)} style={{ ...pStyle, background:"var(--paper-deep)", color:"var(--coral)", fontSize:11, padding:"4px 8px" }}>✕</button>
                  </div>
                ))
              }
            </div>
            {!assignedData && <Spinner/>}
          </div>
        )}

        {tab === "files" && (
          <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
            <label style={{ display:"flex", alignItems:"center", gap:8, padding:"10px 14px", background:"var(--paper-deep)", borderRadius:8, border:"2px dashed var(--rule)", cursor:"pointer", fontSize:13, color:"var(--ink-soft)" }}>
              {uploading ? "Uploading…" : `${I.upload({size:14})} Upload file (PDF, TXT, PPT)`}
              <input type="file" accept=".pdf,.txt,.ppt,.pptx" style={{ display:"none" }} onChange={uploadFile} disabled={uploading}/>
            </label>
            {filesLoading ? <Spinner/> : fileList.length === 0 ? (
              <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No files uploaded yet.</div>
            ) : fileList.map(f=>(
              <div key={f.id} style={{ display:"flex", alignItems:"center", gap:8, padding:"8px 10px", background:"var(--paper-deep)", borderRadius:8, border:"var(--border-thin)" }}>
                <span style={{ fontSize:18 }}>{FILE_ICONS[f.file_type]||"📁"}</span>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:12, fontWeight:600, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{f.title}</div>
                  <div style={{ fontSize:10, color:"var(--ink-mute)", textTransform:"uppercase" }}>{f.file_type} · {Math.round((f.size_bytes||0)/1024)}KB</div>
                </div>
                <button onClick={()=>viewFile(f.id, f.title, f.file_type)} style={{ ...pStyle, background:"var(--sky)", color:"white" }}>View</button>
                <button onClick={()=>deleteFile(f.id)} style={{ ...pStyle, background:"var(--paper-card)", color:"var(--coral)" }}>✕</button>
              </div>
            ))}
          </div>
        )}

        {tab === "homework" && (
          <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
            <form onSubmit={addHomework} style={{ background:"var(--paper-deep)", borderRadius:8, padding:12, border:"var(--border-thin)" }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:8, letterSpacing:".06em" }}>ADD HOMEWORK</div>
              <input required placeholder="Title" value={hwForm.title} onChange={e=>setHwForm(f=>({...f,title:e.target.value}))} style={{ width:"100%", padding:"7px 10px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none", marginBottom:6, boxSizing:"border-box" }}/>
              <textarea placeholder="Description (optional)" value={hwForm.description} onChange={e=>setHwForm(f=>({...f,description:e.target.value}))} style={{ width:"100%", padding:"7px 10px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none", resize:"vertical", minHeight:54, marginBottom:6, boxSizing:"border-box" }}/>
              <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:6 }}>
                <input type="date" value={hwForm.due_date} onChange={e=>setHwForm(f=>({...f,due_date:e.target.value}))} style={{ padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:11, color:"var(--ink)", outline:"none" }}/>
                <input type="number" placeholder="XP" value={hwForm.xp} onChange={e=>setHwForm(f=>({...f,xp:e.target.value}))} style={{ padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:11, color:"var(--ink)", outline:"none" }}/>
                <select value={hwForm.type} onChange={e=>setHwForm(f=>({...f,type:e.target.value}))} style={{ padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:11, color:"var(--ink)", outline:"none" }}>
                  {["paragraph","mcq","video"].map(t=><option key={t} value={t}>{t}</option>)}
                </select>
              </div>
              <button type="submit" disabled={saving} className="btn btn-primary" style={{ marginTop:8, width:"100%", padding:"7px 0", fontSize:12 }}>{saving?"Saving…":"Add homework"}</button>
            </form>
            {hwLoading ? <Spinner/> : hwList.length === 0 ? (
              <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No homework for this course yet.</div>
            ) : hwList.map(h=>(
              <div key={h.id} style={{ padding:"8px 10px", background:"var(--paper-deep)", borderRadius:8, border:"var(--border-thin)" }}>
                <div style={{ fontWeight:600, fontSize:12 }}>{h.title}</div>
                <div style={{ fontSize:10, color:"var(--ink-mute)", marginTop:2 }}>{h.type?.toUpperCase()} · Due {h.due} · +{h.xp} XP</div>
              </div>
            ))}
          </div>
        )}

        {tab === "quizzes" && (
          <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
            <form onSubmit={addQuiz} style={{ background:"var(--paper-deep)", borderRadius:8, padding:12, border:"var(--border-thin)" }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:8, letterSpacing:".06em" }}>ADD QUIZ</div>
              <input required placeholder="Quiz title" value={qForm.title} onChange={e=>setQForm(f=>({...f,title:e.target.value}))} style={{ width:"100%", padding:"7px 10px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:12, color:"var(--ink)", outline:"none", marginBottom:6, boxSizing:"border-box" }}/>
              <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:6, marginBottom:6 }}>
                <select value={qForm.batch_id} onChange={e=>setQForm(f=>({...f,batch_id:e.target.value}))} style={{ padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:11, color:"var(--ink)", outline:"none" }}>
                  <option value="">— any batch —</option>
                  {BATCHES.map(b=><option key={b.id} value={b.id}>{b.name}</option>)}
                </select>
                <select value={qForm.time_limit} onChange={e=>setQForm(f=>({...f,time_limit:e.target.value}))} style={{ padding:"6px 8px", border:"var(--border-thin)", borderRadius:6, background:"var(--paper-card)", fontSize:11, color:"var(--ink)", outline:"none" }}>
                  {["10 minutes","15 minutes","20 minutes","30 minutes","45 minutes","60 minutes"].map(t=><option key={t} value={t}>{t}</option>)}
                </select>
              </div>
              <button type="submit" disabled={saving} className="btn btn-primary" style={{ width:"100%", padding:"7px 0", fontSize:12 }}>{saving?"Saving…":"Create quiz"}</button>
            </form>
            {quizzesLoading ? <Spinner/> : qList.length === 0 ? (
              <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No quizzes for this course yet.</div>
            ) : qList.map(q=>(
              <div key={q.id} style={{ padding:"8px 10px", background:"var(--paper-deep)", borderRadius:8, border:"var(--border-thin)" }}>
                <div style={{ fontWeight:600, fontSize:12 }}>{q.title}</div>
                <div style={{ fontSize:10, color:"var(--ink-mute)", marginTop:2 }}>{q.batch} · {q.assigned} · {q.questions} Qs</div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

const AdminCourses = ({ dark = true, go }) => {
  const { data: initCourses } = useApi("/courses");
  const [courses, setCourses]   = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const [showAdd, setShowAdd]   = React.useState(false);
  const [form, setForm]         = React.useState({ name:"", level:"Beginner" });
  const [saving, setSaving]     = React.useState(false);
  const [error, setError]       = React.useState("");
  const list = courses ?? initCourses;
  const course = selected ? list.find(c=>c.id===selected) : null;

  const { data: initCourseContent } = useApi(selected ? `/content/${selected}` : "/content/0");
  const [courseContent, setCourseContent] = React.useState(null);
  React.useEffect(() => { setCourseContent(null); }, [selected]);
  const cc = courseContent ?? initCourseContent;
  const refreshCourseContent = () => selected && apiFetch(`/content/${selected}`).then(r=>r.json()).then(setCourseContent);

  const refresh = () => apiFetch("/courses").then(r=>r.json()).then(setCourses);

  const save = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/courses/list", { method:"POST", body: JSON.stringify(form) });
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh(); setForm({ name:"", level:"Beginner" }); setShowAdd(false); setSaving(false);
  };

  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showAdd && (
        <Modal title="New course" onClose={()=>setShowAdd(false)}>
          <form onSubmit={save}>
            <FormField label="COURSE NAME">
              <input required style={inputStyle} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Python · Beginner"/>
            </FormField>
            <FormField label="LEVEL">
              <select style={selectStyle} value={form.level} onChange={e=>setForm(f=>({...f,level:e.target.value}))}>
                {["Beginner","Intermediate","Advanced"].map(l=><option key={l} value={l}>{l}</option>)}
              </select>
            </FormField>
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:12 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:4 }}>
              <button type="button" onClick={()=>setShowAdd(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Saving…":"Create course"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/courses" go={go}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
        <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:20 }}>Courses</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} courses · {list.filter(c=>c.status==="active").length} active</div>
          </div>
          <div style={{ flex:1 }}/>
          <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} New course</button>
        </div>
        <div style={{ flex:1, display:"flex", overflow:"hidden" }}>
          <div style={{ flex:1, overflow:"auto", padding:22 }}>
            {list.length === 0 ? (
              <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:12 }}>📚</div>
                <div style={{ fontSize:16, fontWeight:700 }}>No courses yet</div>
                <div style={{ fontSize:13, marginTop:4, marginBottom:20 }}>Create your first course to get started</div>
                <button onClick={()=>setShowAdd(true)} className="btn btn-primary">{I.plus({ size:14 })} New course</button>
              </div>
            ) : (
              <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(260px,1fr))", gap:16 }}>
                {list.map((c, idx) => {
                  const color = COURSE_COLORS[idx % COURSE_COLORS.length];
                  return (
                    <div key={c.id} onClick={() => setSelected(selected===c.id?null:c.id)} className="card" style={{ padding:0, cursor:"pointer", overflow:"hidden", border: selected===c.id ? `2px solid ${color}` : "var(--border)" }}>
                      <div style={{ background:color, padding:"20px 18px", color:"white", position:"relative", overflow:"hidden" }}>
                        <div style={{ position:"absolute", top:-20, right:-20, width:80, height:80, borderRadius:"50%", background:"rgba(255,255,255,.12)" }}/>
                        <div style={{ width:36, height:36, borderRadius:10, background:"rgba(255,255,255,.2)", display:"grid", placeItems:"center", marginBottom:10 }}>{I.book({ size:18 })}</div>
                        <div className="display" style={{ fontSize:20 }}>{c.title}</div>
                        <span className="chip" style={{ marginTop:8, background:"rgba(255,255,255,.25)", color:"white", fontSize:10, display:"inline-flex" }}>{c.status}</span>
                      </div>
                      <div style={{ padding:"14px 18px", display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:10 }}>
                        {[["Batches",c.batches],["Students",c.students],["Lessons",c.lessons]].map(([l,v])=>(
                          <div key={l}>
                            <div style={{ fontSize:10, color:"var(--ink-mute)" }}>{l}</div>
                            <div className="display" style={{ fontSize:22 }}>{v}</div>
                          </div>
                        ))}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>
          {course && (
            <CourseEditPanel
              course={course}
              courseContent={cc}
              onClose={()=>setSelected(null)}
              onRefreshContent={refreshCourseContent}
              onDeleteCourse={id=>{ setCourses(prev=>(prev||initCourses||[]).filter(c=>c.id!==id)); setSelected(null); }}
            />
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Sub-centres ────────────────────────────────────────────────────────
const AdminCentres = ({ dark = true, go }) => {
  const { data: CENTRES } = useApi("/centres");
  return (
  <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
    <AdminSidebar active="/app/admin/centres" go={go}/>
    <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
      <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:20 }}>Sub-centres</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{CENTRES.length} centres · {CENTRES.reduce((a,c)=>a+c.students,0)} total students</div>
        </div>
        <div style={{ flex:1 }}/>
        <button className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add centre</button>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22 }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fill,minmax(280px,1fr))", gap:16, marginBottom:22 }}>
          {CENTRES.map(c=>(
            <div key={c.id} className="card" style={{ padding:0, overflow:"hidden" }}>
              <div style={{ background:c.color, padding:"18px 20px", color:"white", display:"flex", justifyContent:"space-between", alignItems:"center" }}>
                <div>
                  <div className="display" style={{ fontSize:18 }}>{c.name}</div>
                  <div style={{ fontSize:12, opacity:.85 }}>{c.city}</div>
                </div>
                <span style={{ padding:"3px 10px", borderRadius:999, background:"rgba(255,255,255,.25)", fontSize:10, fontWeight:700 }}>{c.status}</span>
              </div>
              <div style={{ padding:"14px 20px", display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:10 }}>
                {[["Students",c.students],["Teachers",c.teachers],["Revenue",c.revenue]].map(([l,v])=>(
                  <div key={l}>
                    <div style={{ fontSize:10, color:"var(--ink-mute)" }}>{l}</div>
                    <div style={{ fontWeight:700, fontSize:l==="Revenue"?14:20 }}>{v}</div>
                  </div>
                ))}
              </div>
              <div style={{ padding:"0 20px 14px", display:"flex", gap:8 }}>
                <button className="btn btn-ghost" style={{ flex:1, padding:"6px 0", fontSize:12 }}>{I.users({ size:14 })} Students</button>
                <button className="btn btn-ghost" style={{ flex:1, padding:"6px 0", fontSize:12 }}>{I.chart({ size:14 })} Analytics</button>
              </div>
            </div>
          ))}
        </div>
        <div className="card-flat" style={{ padding:18 }}>
          <SectionHead eyebrow="TOTAL NETWORK" title="Revenue by centre"/>
          <div style={{ display:"flex", alignItems:"end", gap:8, height:120 }}>
            {CENTRES.map((c,i)=>{
              const h = [50,45,33,14,100][i];
              return (
                <div key={i} style={{ flex:1, display:"flex", flexDirection:"column", alignItems:"center", gap:6 }}>
                  <div style={{ width:"100%", height:`${h}%`, background:c.color, border:"1.5px solid var(--rule-bold)", borderRadius:"4px 4px 0 0" }}/>
                  <div style={{ fontSize:10, color:"var(--ink-mute)", textAlign:"center", fontFamily:"var(--font-mono)" }}>{c.city.split(" ")[0]}</div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  </Themed>
  );
};

// ── Admin: Certificates ───────────────────────────────────────────────────────
const AdminCertificates = ({ dark = true, go }) => {
  const { data: initCerts } = useApi("/certificates/all");
  const { data: STUDENTS }  = useApi("/students");
  const { data: COURSES }   = useApi("/courses/list");
  const [certs, setCerts]   = React.useState(null);
  const [showAdd, setShowAdd] = React.useState(false);
  const [form, setForm]       = React.useState({ student_id:"", course:"" });
  const [saving, setSaving]   = React.useState(false);
  const [error, setError]     = React.useState("");
  const list = certs ?? initCerts;

  const refresh = () => apiFetch("/certificates/all").then(r=>r.json()).then(setCerts);

  const issue = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/certificates", { method:"POST", body: JSON.stringify(form) });
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh(); setForm({ student_id:"", course:"" }); setShowAdd(false); setSaving(false);
  };

  return (
  <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
    {showAdd && (
      <Modal title="Issue certificate" onClose={()=>setShowAdd(false)}>
        <form onSubmit={issue}>
          <FormField label="STUDENT">
            <select required style={selectStyle} value={form.student_id} onChange={e=>setForm(f=>({...f,student_id:e.target.value}))}>
              <option value="">— select student —</option>
              {STUDENTS.map(s=><option key={s.id} value={s.id}>{s.name}</option>)}
            </select>
          </FormField>
          <FormField label="COURSE">
            <select required style={selectStyle} value={form.course} onChange={e=>setForm(f=>({...f,course:e.target.value}))}>
              <option value="">— select course —</option>
              {COURSES.map(c=><option key={c.id} value={`${c.name} · ${c.level}`}>{c.name} · {c.level}</option>)}
            </select>
          </FormField>
          {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:12 }}>{error}</div>}
          <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:4 }}>
            <button type="button" onClick={()=>setShowAdd(false)} className="btn btn-ghost">Cancel</button>
            <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Issuing…":"Issue certificate"}</button>
          </div>
        </form>
      </Modal>
    )}
    <AdminSidebar active="/app/admin/certificates" go={go}/>
    <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
      <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:20 }}>Certificates</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} issued total</div>
        </div>
        <div style={{ flex:1 }}/>
        <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Issue certificate</button>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22 }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(2,1fr)", gap:14, marginBottom:22 }}>
          {[
            { l:"TOTAL ISSUED", v:list.length, c:"var(--moss)" },
            { l:"STUDENTS WITH CERTS", v: new Set(list.map(c=>c.student)).size, c:"var(--sky)" },
          ].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>
        {list.length === 0 ? (
          <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
            <div style={{ fontSize:32, marginBottom:12 }}>🏆</div>
            <div style={{ fontSize:16, fontWeight:700 }}>No certificates issued yet</div>
            <div style={{ fontSize:13, marginTop:4, marginBottom:20 }}>Issue certificates to students who complete courses</div>
            <button onClick={()=>setShowAdd(true)} className="btn btn-primary">{I.plus({ size:14 })} Issue first certificate</button>
          </div>
        ) : (
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                {["Student","Course","Cert ID","Issued"].map(h=>(
                  <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {list.map((c,i)=>(
                <tr key={i} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                  <td style={{ padding:"12px" }}>
                    <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                      <Avatar name={c.student[0]} color={c.color||"var(--coral)"} size={26}/>
                      <span style={{ fontWeight:700 }}>{c.student}</span>
                    </div>
                  </td>
                  <td style={{ padding:"12px", color:"var(--ink-soft)" }}>{c.course}</td>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:11 }}>CERT-{String(c.id).padStart(4,"0")}</span></td>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{c.date}</span></td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  </Themed>
  );
};

// ── Admin: Settings ───────────────────────────────────────────────────────────
// ── Admin: Institutions & Divisions ───────────────────────────────────────────
const AdminInstitutions = ({ dark = true, go }) => {
  const { data: initInst, loading } = useApi("/institutions");
  const { data: TEACHERS } = useApi("/teachers");
  const { data: COURSES } = useApi("/courses/list");
  const [inst, setInst] = React.useState(null);
  const [selected, setSelected] = React.useState(null);   // selected institution id
  const [divisions, setDivisions] = React.useState([]);
  const [divLoading, setDivLoading] = React.useState(false);
  const [showInst, setShowInst] = React.useState(false);
  const [showDiv, setShowDiv] = React.useState(false);
  const [instForm, setInstForm] = React.useState({ name:"", city:"", contact:"" });
  const [divForm, setDivForm] = React.useState({ name:"", grade_label:"", teacher_id:"", course_id:"" });
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState("");
  const list = inst ?? initInst;
  const current = selected ? list.find(i => i.id === selected) : null;
  const canManageInst = hasPerm("manage_institutions");
  const canManageDiv = hasPerm("manage_divisions");

  const refresh = () => apiFetch("/institutions").then(r => r.json()).then(setInst);
  const loadDivisions = (id) => {
    setDivLoading(true);
    apiFetch(`/institutions/${id}/divisions`).then(r => r.json())
      .then(d => setDivisions(Array.isArray(d) ? d : []))
      .finally(() => setDivLoading(false));
  };
  const openInst = (i) => { setSelected(i.id); loadDivisions(i.id); };

  const addInst = async (e) => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/institutions", { method:"POST", body: JSON.stringify(instForm) });
    const data = await res.json();
    if (!res.ok) { setError(data.error || "Failed"); setSaving(false); return; }
    await refresh(); setInstForm({ name:"", city:"", contact:"" }); setShowInst(false); setSaving(false);
  };
  const deleteInst = async (id) => {
    if (!confirm("Delete this institution and all its divisions?")) return;
    await apiFetch(`/institutions/${id}`, { method:"DELETE" });
    if (selected === id) { setSelected(null); setDivisions([]); }
    await refresh();
  };
  const toggleInstStatus = async (i) => {
    await apiFetch(`/institutions/${i.id}`, { method:"PATCH", body: JSON.stringify({ status: i.status === "active" ? "inactive" : "active" }) });
    await refresh();
  };

  const addDiv = async (e) => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch(`/institutions/${selected}/divisions`, { method:"POST", body: JSON.stringify({
      name: divForm.name, grade_label: divForm.grade_label || null,
      teacher_id: divForm.teacher_id || null, course_id: divForm.course_id || null,
    })});
    const data = await res.json();
    if (!res.ok) { setError(data.error || "Failed"); setSaving(false); return; }
    loadDivisions(selected); await refresh();
    setDivForm({ name:"", grade_label:"", teacher_id:"", course_id:"" }); setShowDiv(false); setSaving(false);
  };
  const deleteDiv = async (id) => {
    if (!confirm("Delete this division?")) return;
    await apiFetch(`/divisions/${id}`, { method:"DELETE" });
    loadDivisions(selected); await refresh();
  };

  if (loading) return <Spinner/>;
  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showInst && (
        <Modal title="New institution" onClose={()=>setShowInst(false)}>
          <form onSubmit={addInst}>
            <FormField label="NAME"><input required style={inputStyle} value={instForm.name} onChange={e=>setInstForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Greenwood International School"/></FormField>
            <FormField label="CITY"><input style={inputStyle} value={instForm.city} onChange={e=>setInstForm(f=>({...f,city:e.target.value}))} placeholder="e.g. Mumbai"/></FormField>
            <FormField label="CONTACT"><input style={inputStyle} value={instForm.contact} onChange={e=>setInstForm(f=>({...f,contact:e.target.value}))} placeholder="Name / phone / email"/></FormField>
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:10 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end" }}>
              <button type="button" onClick={()=>setShowInst(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Creating…":"Create"}</button>
            </div>
          </form>
        </Modal>
      )}
      {showDiv && (
        <Modal title="New division" onClose={()=>setShowDiv(false)}>
          <form onSubmit={addDiv}>
            <FormField label="NAME"><input required style={inputStyle} value={divForm.name} onChange={e=>setDivForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Class 6 - A"/></FormField>
            <FormField label="GRADE LABEL"><input style={inputStyle} value={divForm.grade_label} onChange={e=>setDivForm(f=>({...f,grade_label:e.target.value}))} placeholder="e.g. Grade 6"/></FormField>
            <FormField label="TEACHER">
              <select style={selectStyle} value={divForm.teacher_id} onChange={e=>setDivForm(f=>({...f,teacher_id:e.target.value}))}>
                <option value="">— optional —</option>
                {TEACHERS.map(t=><option key={t.id} value={t.id}>{t.name}</option>)}
              </select>
            </FormField>
            <FormField label="COURSE">
              <select style={selectStyle} value={divForm.course_id} onChange={e=>setDivForm(f=>({...f,course_id:e.target.value}))}>
                <option value="">— optional —</option>
                {COURSES.map(c=><option key={c.id} value={c.id}>{c.name} · {c.level}</option>)}
              </select>
            </FormField>
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:10 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end" }}>
              <button type="button" onClick={()=>setShowDiv(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Creating…":"Create"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/institutions" go={go}/>
      <div style={{ flex:1, display:"flex", minWidth:0, background:"var(--paper)" }}>
        {/* Institution list */}
        <div style={{ width:280, borderRight:"var(--border-thin)", display:"flex", flexDirection:"column", background:"var(--paper-card)" }}>
          <div style={{ padding:"12px 16px", borderBottom:"var(--border-thin)", display:"flex", alignItems:"center", gap:8 }}>
            <div className="display" style={{ fontSize:16, flex:1 }}>Institutions</div>
            {canManageInst && <button onClick={()=>setShowInst(true)} className="btn btn-primary" style={{ padding:"4px 10px", fontSize:11 }}>{I.plus({size:12})} New</button>}
          </div>
          <div style={{ flex:1, overflow:"auto", padding:10 }}>
            {list.length === 0 && <div style={{ padding:16, fontSize:13, color:"var(--ink-mute)" }}>No institutions yet.</div>}
            {list.map(i=>(
              <button key={i.id} onClick={()=>openInst(i)} style={{ display:"flex", alignItems:"center", gap:10, width:"100%", padding:"10px 12px", borderRadius:8, border:"none", marginBottom:4,
                background: selected===i.id?"var(--paper-deep)":"transparent", cursor:"pointer", textAlign:"left" }}>
                <div style={{ width:8, height:8, borderRadius:"50%", background: i.status==="active"?"var(--moss)":"var(--ink-mute)", flexShrink:0 }}/>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontWeight:700, fontSize:13, color:"var(--ink)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{i.name}</div>
                  <div style={{ fontSize:10, color:"var(--ink-mute)", marginTop:1 }}>{i.city || "—"} · {i.divisions} div · {i.students} students</div>
                </div>
              </button>
            ))}
          </div>
        </div>

        {/* Detail */}
        {current ? (
          <div style={{ flex:1, display:"flex", flexDirection:"column", overflow:"hidden" }}>
            <div style={{ padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12 }}>
              <div style={{ flex:1 }}>
                <div className="display" style={{ fontSize:18 }}>{current.name}</div>
                <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{current.city || "—"}{current.contact ? " · " + current.contact : ""} · {current.status}</div>
              </div>
              {canManageInst && <button onClick={()=>toggleInstStatus(current)} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:11 }}>{current.status==="active"?"Deactivate":"Activate"}</button>}
              {canManageInst && <button onClick={()=>deleteInst(current.id)} style={{ fontSize:11, padding:"6px 12px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--coral)", cursor:"pointer", fontWeight:600 }}>Delete</button>}
              {canManageDiv && <button onClick={()=>setShowDiv(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({size:12})} New division</button>}
            </div>
            <div style={{ flex:1, overflow:"auto", padding:22 }}>
              {divLoading ? <Spinner/> : divisions.length === 0 ? (
                <div style={{ textAlign:"center", padding:48, color:"var(--ink-mute)" }}>
                  <div style={{ fontSize:32, marginBottom:8 }}>🏫</div>
                  <div style={{ fontWeight:700, fontSize:15 }}>No divisions yet</div>
                  <div style={{ fontSize:13, marginTop:4 }}>Create class divisions to enroll students into this institution.</div>
                </div>
              ) : (
                <div className="card-flat" style={{ overflow:"hidden" }}>
                  <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
                    <thead>
                      <tr style={{ background:"var(--paper-deep)" }}>
                        {["Division","Grade","Teacher","Students",""].map(h=>(
                          <th key={h} style={{ padding:"10px 14px", textAlign:"left", fontSize:11, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em" }}>{h.toUpperCase()}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {divisions.map((d,i)=>(
                        <tr key={d.id} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                          <td style={{ padding:"11px 14px", fontWeight:700 }}>{d.name}</td>
                          <td style={{ padding:"11px 14px", color:"var(--ink-soft)" }}>{d.grade_label || "—"}</td>
                          <td style={{ padding:"11px 14px", color:"var(--ink-soft)" }}>{d.teacher || "—"}</td>
                          <td style={{ padding:"11px 14px" }}>{d.students}</td>
                          <td style={{ padding:"11px 14px", textAlign:"right" }}>
                            {canManageDiv && <button onClick={()=>deleteDiv(d.id)} style={{ fontSize:11, padding:"4px 10px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--coral)", cursor:"pointer", fontWeight:600 }}>Delete</button>}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </div>
        ) : (
          <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center", color:"var(--ink-mute)", flexDirection:"column", gap:10 }}>
            <div style={{ fontSize:32 }}>🏫</div>
            <div style={{ fontSize:14, fontWeight:600 }}>Select an institution to manage its divisions</div>
          </div>
        )}
      </div>
    </Themed>
  );
};

// ── Admin: Audit Log viewer ───────────────────────────────────────────────────
const AdminAudit = ({ dark = true, go }) => {
  const PAGE = 50;
  const [offset, setOffset] = React.useState(0);
  const [rows, setRows] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [loading, setLoading] = React.useState(true);
  React.useEffect(() => {
    setLoading(true);
    apiFetch(`/audit?limit=${PAGE}&offset=${offset}`).then(r => r.json())
      .then(d => { setRows(d.data || []); setTotal(d.total || 0); })
      .finally(() => setLoading(false));
  }, [offset]);

  const actionColor = (a) => a.includes("delete") ? "var(--coral)"
    : a.includes("create") ? "var(--moss)"
    : a.includes("role") || a.includes("password") || a.includes("status") ? "var(--gold)"
    : "var(--sky)";

  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/audit" go={go}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
        <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:20 }}>Audit Log</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{total} events · security & admin actions</div>
          </div>
          <div style={{ flex:1 }}/>
          <button disabled={offset===0} onClick={()=>setOffset(o=>Math.max(0,o-PAGE))} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12, opacity: offset===0?0.5:1 }}>← Newer</button>
          <button disabled={offset+PAGE>=total} onClick={()=>setOffset(o=>o+PAGE)} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12, opacity: offset+PAGE>=total?0.5:1 }}>Older →</button>
        </div>
        <div style={{ flex:1, overflow:"auto", padding:22 }}>
          {loading ? <Spinner/> : rows.length === 0 ? (
            <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
              <div style={{ fontSize:32, marginBottom:8 }}>📋</div>
              <div style={{ fontWeight:700, fontSize:15 }}>No audit events yet</div>
            </div>
          ) : (
            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr>
                  {["When","Actor","Action","Entity","IP"].map(h=>(
                    <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)", textAlign:"left", color:"var(--ink-mute)" }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {rows.map((r,i)=>(
                  <tr key={r.id} style={{ borderTop:i?"var(--border-thin)":"none" }}>
                    <td style={{ padding:"10px 12px", fontSize:11, color:"var(--ink-mute)", whiteSpace:"nowrap" }}>{new Date(r.created_at).toLocaleString("en-IN",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"})}</td>
                    <td style={{ padding:"10px 12px" }}>
                      <div style={{ fontWeight:600, fontSize:12 }}>{r.actor_email || "—"}</div>
                      <div style={{ fontSize:10, color:"var(--ink-mute)" }}>{r.actor_role || ""}</div>
                    </td>
                    <td style={{ padding:"10px 12px" }}>
                      <span className="mono" style={{ fontSize:11, fontWeight:700, padding:"2px 8px", borderRadius:6, background:"var(--paper-deep)", color: actionColor(r.action) }}>{r.action}</span>
                    </td>
                    <td style={{ padding:"10px 12px", fontSize:12, color:"var(--ink-soft)" }}>{r.entity_type ? `${r.entity_type} #${r.entity_id ?? "—"}` : "—"}</td>
                    <td style={{ padding:"10px 12px", fontSize:11, color:"var(--ink-mute)", fontFamily:"var(--font-mono)" }}>{r.ip || "—"}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </Themed>
  );
};

// Setting field catalog: [storage key, label, placeholder]. Values persist to
// the `settings` table via PUT /settings/:key.
const SETTINGS_SECTIONS = [
  { section:"ORGANISATION", fields:[
    ["centre_name","Centre name","EpiqMinds · Mumbai"],
    ["admin_email","Admin email","admin@epiqminds.com"],
    ["support_phone","Support phone","+91 98765 00000"],
    ["timezone","Timezone","Asia/Kolkata (IST +5:30)"],
  ]},
  { section:"NOTIFICATIONS", fields:[
    ["whatsapp_api_key","WhatsApp API key","twilio_…"],
    ["sendgrid_api_key","SendGrid API key","SG.…"],
    ["sender_name","Default sender name","EpiqMinds Team"],
  ]},
  { section:"PAYMENTS", fields:[
    ["razorpay_key_id","Razorpay key ID","rzp_live_…"],
    ["currency","Currency","INR"],
    ["late_fee_days","Late fee after (days)","7"],
    ["reminder_schedule","Auto-reminder schedule","Day 0, Day 3, Day 7"],
  ]},
];

// ── Admin: Inquiries / Leads ──────────────────────────────────────────────────
const INQ_TABS = ["all", "inquired", "negotiating", "joined", "enrolled", "lost"];
const INQ_COLOR = { inquired:"var(--sky)", negotiating:"var(--gold)", joined:"var(--moss)", enrolled:"var(--moss)", lost:"var(--ink-mute)" };

const AdminInquiries = ({ dark = true, go, session = {} }) => {
  const [tab, setTab] = React.useState("all");
  const [list, setList] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [selectedId, setSelectedId] = React.useState(null);
  const [edit, setEdit] = React.useState({ negotiated_amount:"", notes:"", status:"" });
  const [saving, setSaving] = React.useState(false);
  const [convertResult, setConvertResult] = React.useState(null);

  const load = React.useCallback(() => {
    setLoading(true);
    apiFetch(`/admin/inquiries?status=${tab}&limit=100`).then(r=>r.json())
      .then(d => setList(d.data || [])).finally(()=>setLoading(false));
  }, [tab]);
  React.useEffect(load, [load]);

  const selected = selectedId ? list.find(i=>i.id===selectedId) : null;
  const openRow = (i) => {
    setSelectedId(i.id);
    setEdit({ negotiated_amount: i.negotiated_amount ?? "", notes: i.notes ?? "", status: i.status });
  };

  const patch = async (id, body) => {
    setSaving(true);
    await apiFetch(`/admin/inquiries/${id}`, { method:"PATCH", body: JSON.stringify(body) });
    load(); setSaving(false);
  };
  const saveEdit = () => patch(selectedId, {
    status: edit.status,
    negotiated_amount: edit.negotiated_amount === "" ? undefined : Number(edit.negotiated_amount),
    notes: edit.notes,
    payment_mode: edit.negotiated_amount !== "" ? "negotiated" : undefined,
  });
  const markJoined = (id) => patch(id, { status:"joined", payment_status:"paid" });

  const convert = async (i) => {
    if (!confirm(`Convert "${i.child_name || i.parent_name}" into a student${i.email ? " + parent login" : ""}?`)) return;
    setSaving(true);
    const res = await apiFetch(`/admin/inquiries/${i.id}/convert`, { method:"POST", body: JSON.stringify({}) });
    const data = await res.json().catch(()=>({}));
    setSaving(false);
    if (!res.ok) { alert(data.error || "Convert failed"); return; }
    setConvertResult(data);
    load();
  };

  const fmt$ = (n) => n == null || n === "" ? "—" : "$" + Number(n).toLocaleString();
  const amountOf = (i) => i.negotiated_amount ?? i.intended_amount;

  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {convertResult && (
        <Modal title="Converted to student ✓" onClose={()=>setConvertResult(null)}>
          <div style={{ fontSize:13, color:"var(--ink-soft)", lineHeight:1.6 }}>
            <div>Student <b>{convertResult.student?.name}</b> created.</div>
            {convertResult.parent_login_created ? (
              <div style={{ marginTop:12, padding:14, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)" }}>
                <div style={{ fontSize:11, color:"var(--ink-mute)", marginBottom:6 }}>PARENT LOGIN — share this once</div>
                <div><b>Email:</b> {convertResult.parent_email}</div>
                <div><b>Temp password:</b> <span className="mono" style={{ color:"var(--coral)" }}>{convertResult.temp_password}</span></div>
                <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:6 }}>They'll be asked to change it on first login.</div>
              </div>
            ) : convertResult.parent_email ? (
              <div style={{ marginTop:10, fontSize:12, color:"var(--ink-mute)" }}>A user with {convertResult.parent_email} already existed — no new login created.</div>
            ) : (
              <div style={{ marginTop:10, fontSize:12, color:"var(--ink-mute)" }}>No email on the lead, so no parent login was created. Add one via Users if needed.</div>
            )}
          </div>
          <div style={{ display:"flex", justifyContent:"flex-end", marginTop:16 }}>
            <button onClick={()=>setConvertResult(null)} className="btn btn-primary">Done</button>
          </div>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/leads" go={go}/>
      <div style={{ flex:1, display:"flex", minWidth:0, background:"var(--paper)" }}>
        {/* List */}
        <div style={{ flex: selected ? "0 0 55%" : 1, display:"flex", flexDirection:"column", minWidth:0 }}>
          <div style={{ padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12, flexWrap:"wrap" }}>
            <div>
              <div className="display" style={{ fontSize:20 }}>Leads</div>
              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} {tab==="all"?"total":tab}</div>
            </div>
            <div style={{ flex:1 }}/>
            <Tabs items={INQ_TABS.map(t=>t[0].toUpperCase()+t.slice(1))} active={tab[0].toUpperCase()+tab.slice(1)} onChange={(t)=>{setTab(t.toLowerCase()); setSelectedId(null);}}/>
          </div>
          <div style={{ flex:1, overflow:"auto", padding:18 }}>
            {loading ? <Spinner/> : list.length === 0 ? (
              <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
                <div style={{ fontSize:32, marginBottom:8 }}>📥</div>
                <div style={{ fontWeight:700, fontSize:15 }}>No leads {tab!=="all"?`in "${tab}"`:"yet"}</div>
                <div style={{ fontSize:13, marginTop:4 }}>New reservations from the website appear here.</div>
              </div>
            ) : (
              <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
                <thead>
                  <tr>{["Parent","Child","Plan","Amount","Status",""].map(h=>(
                    <th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)", textAlign:"left", color:"var(--ink-mute)" }}>{h}</th>
                  ))}</tr>
                </thead>
                <tbody>
                  {list.map((i,idx)=>(
                    <tr key={i.id} onClick={()=>openRow(i)} style={{ borderTop: idx?"var(--border-thin)":"none", cursor:"pointer", background: selectedId===i.id?"var(--paper-deep)":"transparent" }}>
                      <td style={{ padding:"10px", fontWeight:700 }}>{i.parent_name || "—"}<div style={{ fontSize:11, color:"var(--ink-mute)", fontWeight:400 }}>{i.email || i.phone || ""}</div></td>
                      <td style={{ padding:"10px", color:"var(--ink-soft)" }}>{i.child_name || "—"}{i.child_age?` · ${i.child_age}`:""}</td>
                      <td style={{ padding:"10px", color:"var(--ink-soft)", fontSize:12 }}>{i.plan_label || "—"}</td>
                      <td style={{ padding:"10px", fontWeight:700 }}>{fmt$(amountOf(i))}</td>
                      <td style={{ padding:"10px" }}><span style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background:INQ_COLOR[i.status]||"var(--sky)", color:"white" }}>{i.status}</span></td>
                      <td style={{ padding:"10px", fontSize:11, color:"var(--ink-mute)", whiteSpace:"nowrap" }}>{new Date(i.created_at).toLocaleDateString("en-IN",{day:"numeric",month:"short"})}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>
        </div>

        {/* Detail */}
        {selected && (
          <div style={{ flex:1, borderLeft:"var(--border-thin)", background:"var(--paper-card)", overflow:"auto", padding:22, minWidth:0 }}>
            <div style={{ display:"flex", alignItems:"flex-start", gap:10 }}>
              <div style={{ flex:1 }}>
                <div className="display" style={{ fontSize:18 }}>{selected.parent_name || "Lead"}</div>
                <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{selected.email || "—"}{selected.phone?` · ${selected.phone}`:""}</div>
              </div>
              <button onClick={()=>setSelectedId(null)} style={{ background:"none", border:"none", fontSize:20, cursor:"pointer", color:"var(--ink-mute)", lineHeight:1 }}>×</button>
            </div>

            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10, margin:"16px 0", fontSize:13 }}>
              {[["Child", `${selected.child_name||"—"}${selected.child_age?` · ${selected.child_age}`:""}`],
                ["Plan interest", selected.plan_label||"—"],
                ["Offered amount", fmt$(selected.intended_amount)],
                ["Source", selected.source]].map(([l,v])=>(
                <div key={l} className="card-flat" style={{ padding:"8px 12px" }}>
                  <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{l.toUpperCase()}</div>
                  <div style={{ fontWeight:600, marginTop:2 }}>{v}</div>
                </div>
              ))}
            </div>
            {selected.message && (
              <div style={{ padding:12, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)", fontSize:13, marginBottom:16 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:4 }}>MESSAGE</div>{selected.message}
              </div>
            )}

            <FormField label="STATUS">
              <select style={selectStyle} value={edit.status} onChange={e=>setEdit(s=>({...s,status:e.target.value}))}>
                {["inquired","negotiating","joined","enrolled","lost"].map(s=><option key={s} value={s}>{s}</option>)}
              </select>
            </FormField>
            <FormField label="NEGOTIATED AMOUNT (USD)">
              <input type="number" min="0" style={inputStyle} value={edit.negotiated_amount} onChange={e=>setEdit(s=>({...s,negotiated_amount:e.target.value}))} placeholder="e.g. 449"/>
            </FormField>
            <FormField label="NOTES">
              <textarea rows={3} style={{ ...inputStyle, resize:"vertical" }} value={edit.notes} onChange={e=>setEdit(s=>({...s,notes:e.target.value}))} placeholder="Call notes, agreed terms…"/>
            </FormField>

            <div style={{ display:"flex", gap:8, flexWrap:"wrap", marginTop:6 }}>
              <button onClick={saveEdit} disabled={saving} className="btn btn-primary" style={{ padding:"8px 16px", fontSize:12 }}>{saving?"Saving…":"Save"}</button>
              {selected.payment_status!=="paid" && selected.status!=="enrolled" && (
                <button onClick={()=>markJoined(selected.id)} disabled={saving} className="btn btn-ghost" style={{ padding:"8px 14px", fontSize:12, color:"var(--moss)" }}>✓ Mark joined</button>
              )}
              {!selected.student_id && (
                <button onClick={()=>convert(selected)} disabled={saving} className="btn btn-go" style={{ padding:"8px 14px", fontSize:12 }}>Convert to student →</button>
              )}
              {selected.student_id && <span className="chip flat" style={{ fontSize:11, background:"var(--moss)", color:"white" }}>Enrolled · student #{selected.student_id}</span>}
            </div>

            {/* Payment slot — Razorpay generation comes in the next phase */}
            <div style={{ marginTop:18, padding:14, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)" }}>
              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:6 }}>PAYMENT</div>
              <div style={{ fontSize:13 }}>Amount due: <b>{fmt$(amountOf(selected))}</b> · {selected.payment_status==="paid" ? <span style={{color:"var(--moss)"}}>paid ✓</span> : "unpaid"}</div>
              <button disabled title="Razorpay integration — coming next" className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:11, marginTop:8, opacity:.5, cursor:"default" }}>{I.wallet({size:13})} Generate payment link (soon)</button>
            </div>
          </div>
        )}
      </div>
    </Themed>
  );
};

const AdminSettings = ({ dark = true, go }) => {
  const [values, setValues] = React.useState({});
  const [loading, setLoading] = React.useState(true);
  const [savingKey, setSavingKey] = React.useState(null);
  const [savedKey, setSavedKey] = React.useState(null);

  React.useEffect(() => {
    apiFetch("/settings").then(r => r.ok ? r.json() : {}).then(d => setValues(d || {})).finally(() => setLoading(false));
  }, []);

  const setField = (k, v) => setValues(s => ({ ...s, [k]: v }));
  const saveField = async (k) => {
    setSavingKey(k); setSavedKey(null);
    const res = await apiFetch(`/settings/${k}`, { method:"PUT", body: JSON.stringify({ value: values[k] ?? "" }) });
    setSavingKey(null);
    if (res.ok) { setSavedKey(k); setTimeout(() => setSavedKey(c => c === k ? null : c), 1800); }
  };

  if (loading) return <Spinner/>;
  return (
  <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
    <AdminSidebar active="/app/admin/settings" go={go}/>
    <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
      <div style={{ padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)" }}>
        <div className="display" style={{ fontSize:20 }}>Settings</div>
        <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>Organisation, integrations & billing</div>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22, display:"flex", flexDirection:"column", gap:18 }}>
        {SETTINGS_SECTIONS.map(({section, fields})=>(
          <div key={section} className="card-flat" style={{ padding:20 }}>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".08em", marginBottom:14 }}>{section}</div>
            <div style={{ display:"flex", flexDirection:"column", gap:12 }}>
              {fields.map(([k,l,ph])=>(
                <div key={k} style={{ display:"grid", gridTemplateColumns:"200px 1fr auto", alignItems:"center", gap:14 }}>
                  <div style={{ fontSize:13, fontWeight:600, color:"var(--ink-soft)" }}>{l}</div>
                  <input value={values[k] ?? ""} placeholder={ph} onChange={e=>setField(k, e.target.value)}
                    style={{ padding:"7px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }}/>
                  <button onClick={()=>saveField(k)} disabled={savingKey===k} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:11, color: savedKey===k ? "var(--moss)" : "var(--ink)" }}>
                    {savingKey===k ? "Saving…" : savedKey===k ? "✓ Saved" : "Save"}
                  </button>
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  </Themed>
  );
};

// ── Admin: Quizzes (admin view across all batches) ────────────────────────────
const AdminQuizzes = ({ dark = true, go }) => {
  const { data: QUIZZES, loading } = useApi("/quizzes");
  const completed  = QUIZZES.filter(q => q.submitted > 0).length;
  const scored     = QUIZZES.filter(q => q.avgScore);
  const avgScore   = scored.length ? Math.round(scored.reduce((a,q)=>a+q.avgScore,0)/scored.length) : null;
  const passRate   = scored.length ? Math.round(scored.filter(q=>q.avgScore>=60).length/scored.length*100) : null;
  if (loading) return <Spinner />;
  return (
  <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
    <AdminSidebar active="/app/admin/quizzes" go={go}/>
    <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
      <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:20 }}>Quizzes</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>All batches · performance overview</div>
        </div>
        <div style={{ flex:1 }}/>
        <button className="btn btn-ghost" onClick={()=>go&&go("/app/teacher/quizzes")} style={{ padding:"6px 12px", fontSize:12 }}>Teacher view</button>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22, display:"flex", flexDirection:"column", gap:16 }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:14 }}>
          {[
            { l:"TOTAL QUIZZES", v: QUIZZES.length,                        c:"var(--sky)"  },
            { l:"WITH RESPONSES",v: completed,                              c:"var(--moss)" },
            { l:"AVG SCORE",     v: avgScore  != null ? `${avgScore}%`:"—", c:"var(--coral)"},
            { l:"PASS RATE",     v: passRate  != null ? `${passRate}%`:"—", c:"var(--moss)" },
          ].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>
        {QUIZZES.length === 0 ? (
          <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
            <div style={{ fontSize:32, marginBottom:12 }}>🧩</div>
            <div style={{ fontSize:16, fontWeight:700 }}>No quizzes yet</div>
            <div style={{ fontSize:13, marginTop:4 }}>Teachers can create quizzes from the Teacher view</div>
            <button onClick={()=>go&&go("/app/teacher/quizzes")} className="btn btn-ghost" style={{ marginTop:16 }}>Go to Teacher view →</button>
          </div>
        ) : (
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                {["Quiz","Batch","Questions","Assigned","Avg Score","Completed"].map(h=>(
                  <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {QUIZZES.map((q,i)=>(
                <tr key={q.id} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                  <td style={{ padding:"12px", fontWeight:700 }}>{q.title}</td>
                  <td style={{ padding:"12px", color:"var(--ink-soft)" }}>{q.batch}</td>
                  <td style={{ padding:"12px" }}>{q.questions}</td>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{q.assigned}</span></td>
                  <td style={{ padding:"12px", fontWeight:700, color: q.avgScore ? q.avgScore>=80?"var(--moss)":"var(--gold)" : "var(--ink-mute)" }}>{q.avgScore ? `${q.avgScore}%` : "—"}</td>
                  <td style={{ padding:"12px" }}>{q.submitted ?? 0}/{q.total ?? 0}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  </Themed>
  );
};

// ── Parent: Shop ──────────────────────────────────────────────────────────────
const ParentShop = ({ dark = false, session }) =>
  <ShopGrid dark={dark} studentId={session?.studentId}/>;

// ── Shop redemption grid (shared by student & parent) ─────────────────────────
// Items are redeemed with coins via POST /shop/orders, which deducts the
// student's balance server-side. `studentId` is the coin-holder (the child).
const ShopGrid = ({ theme = "", dark = false, studentId, go, backTo }) => {
  const { data: SHOP_ITEMS, loading } = useApi("/shop");
  const [tab, setTab] = React.useState("All");
  const [coins, setCoins] = React.useState(null);
  const [busy, setBusy] = React.useState(null);      // item id being redeemed
  const [done, setDone] = React.useState({});        // item id -> true after redeem
  const [toast, setToast] = React.useState(null);    // { ok, msg }

  const loadCoins = React.useCallback(() => {
    if (!studentId) return;
    apiFetch(`/student/dashboard/${studentId}`).then(r => r.ok ? r.json() : null)
      .then(d => { if (d && d.student) setCoins(d.student.coins ?? 0); }).catch(()=>{});
  }, [studentId]);
  React.useEffect(loadCoins, [loadCoins]);

  const filtered = (tab==="All" ? SHOP_ITEMS : SHOP_ITEMS.filter(i=>i.category===tab)) || [];

  const redeem = async (item) => {
    if (!studentId) { setToast({ ok:false, msg:"No student profile linked to this account." }); return; }
    setBusy(item.id); setToast(null);
    const res = await apiFetch("/shop/orders", { method:"POST", body: JSON.stringify({ item_id: item.id, qty: 1 }) });
    const data = await res.json().catch(()=>({}));
    setBusy(null);
    if (!res.ok) { setToast({ ok:false, msg: data.error || "Could not redeem this item." }); return; }
    setDone(d => ({ ...d, [item.id]: true }));
    setToast({ ok:true, msg: `Redeemed ${item.name}! 🎉` });
    setCoins(c => (c != null ? Math.max(0, c - Math.round(Number(item.price))) : c));
    loadCoins();
    setTimeout(() => setToast(null), 2600);
  };

  return (
    <Themed theme={theme} className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", background:"var(--paper)", display:"flex", flexDirection:"column" }}>
      <div style={{ display:"flex", alignItems:"center", gap:12, padding:"14px 26px", background:"var(--paper-card)", borderBottom:"var(--border-thin)" }}>
        {backTo && <button className="btn btn-ghost" onClick={() => go && go(backTo)} style={{ padding:"6px 10px", fontSize:12 }}>{I.arrowL({ size:14 })} Back</button>}
        <div className="display" style={{ fontSize:20 }}>
          <span style={{ color:"var(--coral)" }}>Epiq</span>Minds
          <span style={{ color:"var(--ink-mute)", fontSize:11, marginLeft:6, fontWeight:500 }}>shop</span>
        </div>
        <div style={{ flex:1 }}/>
        <Tabs items={["All","Kit","Merch"]} active={tab} onChange={setTab}/>
        <div className="chip" style={{ fontSize:13, fontWeight:800, gap:6 }}>{I.coin({ size:15 })} {coins != null ? coins : "—"} coins</div>
      </div>
      {toast && (
        <div style={{ padding:"10px 26px", background: toast.ok ? "var(--moss)" : "var(--coral)", color:"white", fontSize:13, fontWeight:700 }}>{toast.msg}</div>
      )}
      <div style={{ padding:26, overflow:"auto", flex:1 }}>
        {loading ? <Spinner/> : filtered.length === 0 ? (
          <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
            <div style={{ fontSize:40, marginBottom:12 }}>🛍️</div>
            <div style={{ fontWeight:700, fontSize:16 }}>Shop is empty</div>
            <div style={{ fontSize:13, marginTop:6 }}>Check back soon for cool merch and kits!</div>
          </div>
        ) : (
          <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fill,minmax(220px,1fr))", gap:18 }}>
            {filtered.map(item=>{
              const price = Math.round(Number(item.price) || 0);
              const affordable = coins == null || coins >= price;
              const redeemed = done[item.id];
              const disabled = !item.inStock || busy===item.id || redeemed || !affordable;
              return (
              <div key={item.id} className="card" style={{ padding:0, overflow:"hidden", opacity: item.inStock ? 1 : 0.65 }}>
                <div style={{ height:100, background:"var(--paper-deep)", display:"flex", alignItems:"center", justifyContent:"center", fontSize:44, position:"relative" }}>
                  {item.img}
                  {item.badge && (
                    <span style={{ position:"absolute", top:10, right:10, padding:"2px 8px", borderRadius:999, background: item.badge==="new"?"var(--moss)":"var(--gold)", color:"white", fontSize:10, fontWeight:700 }}>{item.badge}</span>
                  )}
                  {!item.inStock && (
                    <span style={{ position:"absolute", bottom:8, left:"50%", transform:"translateX(-50%)", padding:"2px 10px", borderRadius:999, background:"rgba(0,0,0,.5)", color:"white", fontSize:10, fontWeight:700 }}>Out of stock</span>
                  )}
                </div>
                <div style={{ padding:14 }}>
                  <div style={{ fontWeight:700, fontSize:14 }}>{item.name}</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4, lineHeight:1.4 }}>{item.desc}</div>
                  <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", marginTop:12 }}>
                    <span className="display" style={{ fontSize:18, display:"flex", alignItems:"center", gap:4 }}>{I.coin({ size:15 })} {price}</span>
                    <button onClick={() => !disabled && redeem(item)} disabled={disabled} className="btn btn-primary"
                      style={{ padding:"6px 12px", fontSize:12, background: redeemed ? "var(--moss)" : "var(--coral)", opacity: disabled && !redeemed ? 0.5 : 1, cursor: disabled ? "default" : "pointer" }}>
                      {redeemed ? "✓ Redeemed" : busy===item.id ? "…" : !item.inStock ? "Sold out" : !affordable ? "Not enough" : "Redeem"}
                    </button>
                  </div>
                </div>
              </div>
            );})}
          </div>
        )}
      </div>
    </Themed>
  );
};

// ── Student: Shop ─────────────────────────────────────────────────────────────
const StudentShop = ({ theme = "", go, session }) =>
  <ShopGrid theme={theme} studentId={session?.studentId} go={go} backTo="/app/student"/>;

// ── Student: Profile ──────────────────────────────────────────────────────────
const StudentProfile = ({ theme = "", go, session }) => {
  const sid = session?.studentId;
  const { data: dash } = useApi(sid ? `/student/dashboard/${sid}` : "/student/dashboard/0", {});
  const student = dash.student || {};
  const xp = student.xp || 0;
  const level = Math.floor(xp / 500) + 1;
  const xpInLevel = xp % 500;
  const { data: certs } = useApi(sid ? `/certificates/${sid}` : "/certificates/0");
  return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", background:"var(--paper)", overflow:"auto" }}>
      <div style={{ display:"flex", alignItems:"center", gap:12, padding:"14px 26px", background:"var(--paper-card)", borderBottom:"var(--border-thin)" }}>
        <button className="btn btn-ghost" onClick={() => go && go("/app/student")} style={{ padding:"6px 10px", fontSize:12 }}>{I.arrowL({ size:14 })} Back</button>
        <div className="display" style={{ fontSize:20 }}>My Profile</div>
      </div>
      <div style={{ padding:32, maxWidth:560, margin:"0 auto", display:"flex", flexDirection:"column", gap:20 }}>
        <div className="card" style={{ padding:28, display:"flex", alignItems:"center", gap:22 }}>
          <Avatar name={(student.name || session?.name || "?")[0]} color="var(--plum)" size={72}/>
          <div>
            <div style={{ fontWeight:800, fontSize:22 }}>{student.name || session?.name || "—"}</div>
            <div style={{ color:"var(--ink-mute)", fontSize:13, marginTop:4 }}>{session?.email || "—"}</div>
            {student.batch && <div style={{ marginTop:8 }}><span className="chip" style={{ background:"var(--coral)", color:"white", fontSize:11 }}>{student.batch}</span></div>}
          </div>
        </div>
        <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:14 }}>
          {[
            ["Level", level, I.bolt2],
            ["Total XP", xp, I.coin],
            ["Certificates", (certs || []).length, I.trophy],
          ].map(([l,v,Icon]) => (
            <div key={l} className="card-flat" style={{ padding:16, textAlign:"center" }}>
              <div style={{ color:"var(--coral)", marginBottom:6 }}><Icon size={22}/></div>
              <div style={{ fontWeight:800, fontSize:22 }}>{v}</div>
              <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>{l}</div>
            </div>
          ))}
        </div>
        <div className="card" style={{ padding:20 }}>
          <div style={{ fontWeight:700, fontSize:13, marginBottom:14, color:"var(--ink-mute)" }}>ACCOUNT</div>
          <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
            {[
              ["Name", student.name || session?.name || "—"],
              ["Email", session?.email || "—"],
              ["Batch", student.batch || "—"],
              ["Teacher", student.teacher || "—"],
              ["Course", student.course_name ? `${student.course_name} · ${student.course_level}` : "—"],
            ].map(([l,v]) => (
              <div key={l} style={{ display:"flex", justifyContent:"space-between", padding:"8px 0", borderBottom:"var(--border-thin)" }}>
                <span style={{ fontSize:13, color:"var(--ink-mute)" }}>{l}</span>
                <span style={{ fontSize:13, fontWeight:600 }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
        <div className="card" style={{ padding:20, display:"flex", alignItems:"center", justifyContent:"space-between" }}>
          <div>
            <div style={{ fontWeight:700, fontSize:14 }}>XP Progress — Level {level}</div>
            <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:2 }}>{xpInLevel} / 500 XP to next level</div>
          </div>
          <div style={{ width:120, height:8, background:"var(--paper-deep)", borderRadius:999, overflow:"hidden" }}>
            <div style={{ width:`${(xpInLevel/500)*100}%`, height:"100%", background:"var(--coral)", borderRadius:999 }}/>
          </div>
        </div>
      </div>
    </Themed>
  );
};

// ── Student: Course Tracking ──────────────────────────────────────────────────
const StudentCourseTracking = ({ theme = "", go, session }) => {
  const sid = session?.studentId;
  const { data: dash } = useApi(sid ? `/student/dashboard/${sid}` : "/student/dashboard/0", {});
  const student = dash.student || {};
  const courseId = student.course_id;
  const { data: COURSE_CONTENT } = useApi(courseId ? `/content/${courseId}` : "/content/0");
  const [activeUnit, setActiveUnit] = React.useState(null);
  const [videoLesson, setVideoLesson] = React.useState(null);
  React.useEffect(() => { if (COURSE_CONTENT.length && !activeUnit) setActiveUnit(COURSE_CONTENT[0].id); }, [COURSE_CONTENT.length]);

  const totalLessons    = COURSE_CONTENT.reduce((a,u) => a + (u.lessons||[]).length, 0);
  const publishedLessons= COURSE_CONTENT.reduce((a,u) => a + (u.lessons||[]).filter(l=>l.status==="published").length, 0);
  const totalUnits      = COURSE_CONTENT.length;
  const completedUnits  = COURSE_CONTENT.filter(u => (u.lessons||[]).length > 0 && (u.lessons||[]).every(l=>l.status==="published")).length;
  const overallPct      = totalLessons ? Math.round((publishedLessons/totalLessons)*100) : 0;
  const quizLessons     = COURSE_CONTENT.reduce((a,u) => a + (u.lessons||[]).filter(l=>l.type==="quiz").length, 0);

  return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", display:"flex", flexDirection:"column", background:"var(--paper)" }}>
      {/* Video player modal */}
      {videoLesson && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.78)", display:"flex", alignItems:"center", justifyContent:"center", zIndex:9999 }}
             onClick={e => e.target===e.currentTarget && setVideoLesson(null)}>
          <div style={{ background:"#111", borderRadius:16, overflow:"hidden", width:"min(860px,92vw)", boxShadow:"0 32px 80px rgba(0,0,0,.6)" }}>
            <div style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 18px", background:"#1a1a1a" }}>
              <span style={{ fontWeight:700, fontSize:14, color:"white", flex:1 }}>{videoLesson.title}</span>
              <button onClick={() => setVideoLesson(null)} style={{ background:"none", border:"none", color:"#aaa", fontSize:22, cursor:"pointer", lineHeight:1 }}>×</button>
            </div>
            <div style={{ position:"relative", paddingBottom:"56.25%", background:"#000" }}>
              <iframe src={`https://www.youtube.com/embed/${videoLesson.youtube_id}?autoplay=1`} title={videoLesson.title}
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowFullScreen style={{ position:"absolute", top:0, left:0, width:"100%", height:"100%", border:"none" }}/>
            </div>
          </div>
        </div>
      )}

      {/* Header */}
      <div style={{ padding:"14px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12 }}>
        <div className="display" style={{ fontSize:20 }}>My Courses</div>
        <div style={{ flex:1 }}/>
        {student.course_name && <span className="chip" style={{ background:"var(--coral)", color:"white", fontWeight:700 }}>{student.course_name} · {student.course_level}</span>}
        {student.batch && <span style={{ fontSize:12, color:"var(--ink-mute)" }}>{student.batch} · {student.teacher}</span>}
      </div>

      <div style={{ flex:1, overflow:"auto", padding:22, display:"grid", gridTemplateColumns:"480px 1fr", gap:22, alignItems:"start" }}>

        {/* Left: progress card + unit list */}
        <div style={{ display:"flex", flexDirection:"column", gap:14 }}>

          {/* Overall progress card */}
          <div className="card-flat" style={{ padding:20 }}>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".08em", marginBottom:6 }}>OVERALL PROGRESS</div>
            <div className="display" style={{ fontSize:22, marginBottom:10 }}>
              {student.course_name ? `${student.course_name} · ${student.course_level}` : "My Course"}
            </div>
            <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, color:"var(--ink-soft)", marginBottom:6 }}>
              <span style={{ fontWeight:600 }}>{overallPct}% complete</span>
              <span>{completedUnits} / {totalUnits} units</span>
            </div>
            <div style={{ height:8, background:"var(--paper-deep)", borderRadius:4, marginBottom:14, overflow:"hidden" }}>
              <div style={{ width:`${overallPct}%`, height:"100%", background:"var(--coral)", borderRadius:4, transition:"width .4s" }}/>
            </div>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:8 }}>
              {[
                ["XP Earned",    student.xp ?? 0],
                ["Lessons done", `${publishedLessons}/${totalLessons}`],
                ["Quizzes",      quizLessons],
                ["Streak",       student.streak ? `${student.streak} days` : "—"],
              ].map(([l,v]) => (
                <div key={l} style={{ padding:"10px 14px", background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)" }}>
                  <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{l}</div>
                  <div style={{ fontWeight:700, fontSize:20, marginTop:3 }}>{v}</div>
                </div>
              ))}
            </div>
          </div>

          {/* Unit cards */}
          {COURSE_CONTENT.length === 0 ? (
            <div style={{ textAlign:"center", padding:40, color:"var(--ink-mute)", fontSize:13 }}>No course content yet</div>
          ) : COURSE_CONTENT.map(u => {
            const total = (u.lessons||[]).length;
            const done  = (u.lessons||[]).filter(l=>l.status==="published").length;
            const pct   = total ? Math.round((done/total)*100) : 0;
            const unitXP= done * 20;
            const isActive = activeUnit === u.id;
            const barColor = pct===100 ? "var(--moss)" : "var(--coral)";
            return (
              <div key={u.id} onClick={() => setActiveUnit(u.id)} className="card" style={{ padding:"14px 16px", cursor:"pointer", border: isActive ? "2px solid var(--coral)" : "var(--border)" }}>
                <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:4 }}>
                  <span style={{ fontWeight:700, fontSize:14 }}>{u.unit}</span>
                  <span style={{ fontWeight:700, fontSize:13, color: pct===100?"var(--moss)":pct>0?"var(--coral)":"var(--ink-mute)" }}>{pct}%</span>
                </div>
                <div style={{ height:6, background:"var(--paper-deep)", borderRadius:3, marginBottom:8, overflow:"hidden" }}>
                  <div style={{ width:`${pct}%`, height:"100%", background:barColor, borderRadius:3 }}/>
                </div>
                <div style={{ display:"flex", justifyContent:"space-between", fontSize:11, color:"var(--ink-mute)" }}>
                  <span>{total} lesson{total!==1?"s":""}</span>
                  <span>+{unitXP} XP</span>
                </div>
              </div>
            );
          })}
        </div>

        {/* Right: unit detail */}
        <div>
          {COURSE_CONTENT.filter(u=>u.id===activeUnit).map(unit => (
            <div key={unit.id} className="card-flat" style={{ padding:20 }}>
              <div style={{ marginBottom:16 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".08em" }}>UNIT DETAIL</div>
                <div className="display" style={{ fontSize:22, marginTop:4 }}>{unit.unit}</div>
              </div>
              <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
                {unit.lessons.length === 0 && (
                  <div style={{ fontSize:13, color:"var(--ink-mute)", padding:"16px 0" }}>No lessons in this unit yet.</div>
                )}
                {unit.lessons.map((l, li) => {
                  const isVideo    = l.type === "video";
                  const isPublished= l.status === "published";
                  const typeColors = { video:"var(--coral)", quiz:"var(--sky)", homework:"var(--gold)", project:"var(--plum)" };
                  const iconBg     = isPublished ? "var(--moss)" : (typeColors[l.type] || "var(--paper-deep)");
                  return (
                    <div key={l.id||li} style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 14px", borderRadius:12, border:"var(--border-thin)", background:"var(--paper-card)" }}>
                      <div style={{ width:36, height:36, borderRadius:10, background:iconBg, color:"white", display:"grid", placeItems:"center", flexShrink:0 }}>
                        {isPublished ? I.check({ size:16 }) : isVideo ? I.play({ size:16 }) : l.type==="quiz" ? I.puzzle({ size:16 }) : I.book({ size:16 })}
                      </div>
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ fontWeight:700, fontSize:13 }}>{l.title}</div>
                        <div style={{ display:"flex", alignItems:"center", gap:6, marginTop:3 }}>
                          {isVideo && (
                            <span style={{ fontSize:10, fontWeight:700, padding:"1px 7px", borderRadius:4, background:"var(--coral)", color:"white", letterSpacing:".04em" }}>VIDEO</span>
                          )}
                          {l.type === "quiz" && (
                            <span style={{ fontSize:10, fontWeight:700, padding:"1px 7px", borderRadius:4, background:"var(--sky)", color:"white", letterSpacing:".04em" }}>QUIZ</span>
                          )}
                          {l.type === "homework" && (
                            <span style={{ fontSize:10, fontWeight:700, padding:"1px 7px", borderRadius:4, background:"var(--gold)", color:"white", letterSpacing:".04em" }}>HW</span>
                          )}
                          <span style={{ fontSize:11, color:"var(--ink-mute)" }}>{l.duration || (l.questions ? `${l.questions} questions` : "")}</span>
                        </div>
                      </div>
                      {isVideo && l.youtube ? (
                        <button
                          className="btn btn-primary"
                          onClick={() => setVideoLesson({ title:l.title, youtube_id:l.youtube })}
                          style={{ padding:"6px 14px", fontSize:12, display:"flex", alignItems:"center", gap:6, flexShrink:0 }}>
                          {I.play({ size:12 })} Play
                        </button>
                      ) : l.type === "quiz" ? (
                        <button className="btn btn-ghost" onClick={() => go&&go("/app/student/quiz")} style={{ padding:"6px 14px", fontSize:12, flexShrink:0 }}>Take quiz</button>
                      ) : l.type === "homework" ? (
                        <button className="btn btn-ghost" onClick={() => go&&go("/app/student/homework")} style={{ padding:"6px 14px", fontSize:12, flexShrink:0 }}>Submit</button>
                      ) : null}
                      <span style={{ color:"var(--moss)", fontWeight:700, fontSize:12, marginLeft:4, flexShrink:0 }}>+{(li+1)*20} XP</span>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
          {!activeUnit && COURSE_CONTENT.length > 0 && (
            <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
              <div style={{ fontSize:32, marginBottom:8 }}>👈</div>
              <div style={{ fontSize:14 }}>Select a unit to see lessons</div>
            </div>
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Teacher: Attendance ───────────────────────────────────────────────────────
const ATTEND_STATUSES = ["present","late","missed","tech_issue","pending"];
const ATTEND_LABELS   = { present:"Present", late:"Late", missed:"Missed", tech_issue:"Tech Issue", pending:"Pending", absent:"Absent" };
const ATTEND_COLOR    = { present:"var(--moss)", late:"var(--gold)", missed:"var(--coral)", tech_issue:"var(--sky)", pending:"var(--rule-bold)", absent:"var(--coral)" };

const fmtSessionDate = d => {
  if (!d) return "";
  try { return new Date(d + "T00:00:00").toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short"}); }
  catch { return d; }
};

const TeacherAttendance = ({ dark = false, go, session: _session }) => {
  const { data: initSessions, loading: loadingSessions } = useApi("/sessions-with-roster");
  const [allSessions, setAllSessions] = React.useState(null);
  const TEACHER_SESSIONS = allSessions ?? (Array.isArray(initSessions) ? initSessions : []);
  const [activeTab, setActiveTab] = React.useState("sessions");
  const [selectedSession, setSelectedSession] = React.useState(null);
  React.useEffect(() => {
    if (TEACHER_SESSIONS.length && !selectedSession)
      setSelectedSession(TEACHER_SESSIONS[0].id);
  }, [TEACHER_SESSIONS.length]);
  const [editRoster, setEditRoster] = React.useState(null);
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState({});

  const session = TEACHER_SESSIONS.find(s => s.id === selectedSession);
  const workingRoster = editRoster || (session ? session.roster : []);

  const cycleStatus = i => {
    const cycle = { present:"late", late:"missed", missed:"tech_issue", tech_issue:"pending", pending:"present", absent:"present" };
    setEditRoster(r => (r || session.roster).map((s, idx) => idx === i ? { ...s, status: cycle[s.status] || "present" } : s));
  };

  const saveSession = async () => {
    setSaving(true);
    await apiFetch(`/sessions-with-roster/${selectedSession}/attendance`, {
      method: "POST",
      body: JSON.stringify({ roster: workingRoster.map(r => ({ student_id: r.student_id, status: r.status })) }),
    });
    const fresh = await apiFetch("/sessions-with-roster").then(r=>r.json());
    setAllSessions(fresh);
    setSaved(s => ({ ...s, [selectedSession]: true }));
    setEditRoster(null);
    setSaving(false);
  };

  // Build per-student summary across all sessions
  const allStudents = [...new Set(TEACHER_SESSIONS.flatMap(s => s.roster.map(r => r.name)))];
  const studentSummary = allStudents.map(name => {
    const appearances = TEACHER_SESSIONS.filter(s => s.status !== "upcoming").flatMap(s => s.roster.filter(r => r.name === name));
    const present = appearances.filter(r => r.status === "present").length;
    const late    = appearances.filter(r => r.status === "late").length;
    const missed  = appearances.filter(r => r.status === "missed").length;
    const techIssue = appearances.filter(r => r.status === "tech_issue").length;
    const color = TEACHER_SESSIONS.flatMap(s => s.roster).find(r => r.name === name)?.color || "var(--coral)";
    const attended = present + late;
    const rate = appearances.length ? Math.round((attended / appearances.length) * 100) : 100;
    return { name, color, present, late, missed, techIssue, total: appearances.length, rate };
  }).sort((a, b) => a.rate - b.rate);

  const statusColor = s => ATTEND_COLOR[s] || "var(--ink-mute)";
  const statusBg    = s => ATTEND_COLOR[s] || "var(--ink-mute)";

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/attendance" go={go} session={session}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0 }}>
        {/* Header */}
        <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 }}>Attendance</div>
            <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>
              {TEACHER_SESSIONS.filter(s=>s.status!=="upcoming").length} sessions recorded
            </div>
          </div>
          <div style={{ flex:1 }}/>
          <Tabs items={["Sessions","By student"]} active={activeTab==="sessions"?"Sessions":"By student"} onChange={v => setActiveTab(v==="Sessions"?"sessions":"students")}/>
          <button onClick={() => go && go("/app/teacher/live")} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>
            {I.play({ size:14 })} Live class
          </button>
        </div>

        {activeTab === "sessions" ? (
          <div style={{ flex:1, display:"grid", gridTemplateColumns:"320px 1fr", overflow:"hidden" }}>
            {/* Session list */}
            <div style={{ borderRight:"var(--border-thin)", overflow:"auto", background:"var(--paper-card)" }}>
              {loadingSessions && !TEACHER_SESSIONS.length && (
                <div style={{ padding:32, textAlign:"center", color:"var(--ink-mute)", fontSize:13 }}>Loading sessions…</div>
              )}
              {!loadingSessions && !TEACHER_SESSIONS.length && (
                <div style={{ padding:32, textAlign:"center", color:"var(--ink-mute)", fontSize:13 }}>No sessions found. Add sessions in the Schedule tab first.</div>
              )}
              {TEACHER_SESSIONS.map(s => {
                const present = s.roster.filter(r=>r.status==="present"||r.status==="late").length;
                const rate = s.roster.length ? Math.round((present/s.roster.length)*100) : 0;
                return (
                  <div key={s.id} onClick={() => { setSelectedSession(s.id); setEditRoster(null); }} style={{
                    padding:"14px 18px", cursor:"pointer", borderBottom:"var(--border-thin)",
                    background: selectedSession===s.id ? "var(--paper-deep)" : "transparent",
                    borderLeft: selectedSession===s.id ? "3px solid var(--coral)" : "3px solid transparent",
                  }}>
                    <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", marginBottom:4 }}>
                      <div style={{ fontWeight:700, fontSize:13 }}>{s.batch} · {fmtSessionDate(s.day)}</div>
                      <span className="chip flat" style={{ fontSize:10, padding:"1px 7px", background: s.status==="live"?"var(--coral)":s.status==="done"?"var(--moss)":"var(--paper-deep)", color: s.status==="upcoming"?"var(--ink-mute)":"white" }}>
                        {s.status}
                      </span>
                    </div>
                    <div style={{ fontSize:12, color:"var(--ink-mute)", marginBottom:6 }}>{s.time} · {s.course}</div>
                    {s.status !== "upcoming" && (
                      <>
                        <div className="progress" style={{ height:4, marginBottom:4 }}>
                          <i style={{ width:`${rate}%`, background: rate>=80?"var(--moss)":"var(--gold)" }}/>
                        </div>
                        <div style={{ display:"flex", justifyContent:"space-between", fontSize:11, color:"var(--ink-mute)" }}>
                          <span>{present}/{s.roster.length} present</span>
                          <span style={{ fontWeight:700, color: rate>=80?"var(--moss)":"var(--gold)" }}>{rate}%</span>
                        </div>
                      </>
                    )}
                    {saved[s.id] && <div style={{ fontSize:10, color:"var(--moss)", marginTop:4, fontWeight:700 }}>✓ Attendance saved</div>}
                  </div>
                );
              })}
            </div>

            {/* Session detail / mark attendance */}
            {session && (
              <div style={{ overflow:"auto", padding:22, background:"var(--paper)" }}>
                <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", marginBottom:18 }}>
                  <div>
                    <div className="display" style={{ fontSize:20 }}>{session.batch} · {fmtSessionDate(session.day)}</div>
                    <div style={{ fontSize:13, color:"var(--ink-mute)", marginTop:2 }}>{session.time} · {session.course}</div>
                  </div>
                  {session.status !== "upcoming" && (
                    <div style={{ display:"flex", gap:8 }}>
                      {(saved[session.id] || session.status === "done") && !editRoster
                        ? <button onClick={() => setEditRoster(session.roster.map(r=>({...r})))} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>Edit</button>
                        : session.status !== "upcoming" && (
                          <button onClick={saveSession} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.check({ size:14 })} Save attendance</button>
                        )}
                    </div>
                  )}
                </div>

                {/* Summary chips */}
                <div style={{ display:"flex", gap:10, marginBottom:18 }}>
                  {ATTEND_STATUSES.map(st=>(
                    <div key={st} style={{ padding:"8px 16px", borderRadius:10, background:ATTEND_COLOR[st], color:"white", textAlign:"center", minWidth:68 }}>
                      <div className="display" style={{ fontSize:22 }}>{workingRoster.filter(r=>r.status===st).length}</div>
                      <div style={{ fontSize:10, opacity:.85 }}>{ATTEND_LABELS[st]}</div>
                    </div>
                  ))}
                  <div style={{ flex:1, display:"flex", alignItems:"center" }}>
                    <div style={{ width:"100%" }}>
                      <div style={{ display:"flex", justifyContent:"space-between", fontSize:12, fontWeight:700, marginBottom:6 }}>
                        <span>Attendance rate</span>
                        <span>{workingRoster.length ? Math.round((workingRoster.filter(r=>r.status==="present"||r.status==="late").length/workingRoster.length)*100) : 0}%</span>
                      </div>
                      <div className="progress" style={{ height:8 }}>
                        <i style={{ width:`${workingRoster.length ? Math.round((workingRoster.filter(r=>r.status==="present"||r.status==="late").length/workingRoster.length)*100) : 0}%`, background:"var(--moss)" }}/>
                      </div>
                    </div>
                  </div>
                </div>

                {/* Roster with editable status */}
                <div className="card-flat" style={{ padding:16 }}>
                  <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", marginBottom:12 }}>
                    <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>STUDENT ROSTER</div>
                    {session.status !== "upcoming" && <div style={{ fontSize:11, color:"var(--ink-mute)" }}>Click status pill to change</div>}
                  </div>
                  {workingRoster.map((s, i) => (
                    <div key={i} style={{ display:"flex", alignItems:"center", gap:12, padding:"10px 0", borderTop: i ? "var(--border-thin)" : "none" }}>
                      <Avatar name={s.name[0]} color={s.color} size={32}/>
                      <div style={{ flex:1 }}>
                        <div style={{ fontWeight:700, fontSize:13 }}>{s.name}</div>
                        {/* mini sparkline of this student's last 4 sessions */}
                        <div style={{ display:"flex", gap:3, marginTop:4 }}>
                          {TEACHER_SESSIONS.filter(sess=>sess.status!=="upcoming").slice(0,4).map((sess,si)=>{
                            const entry = sess.roster.find(r=>r.name===s.name);
                            const st = entry ? entry.status : "absent";
                            return <div key={si} style={{ width:8, height:8, borderRadius:2, background:statusColor(st) }} title={`${fmtSessionDate(sess.day)}: ${ATTEND_LABELS[st]||st}`}/>;
                          })}
                          <span style={{ fontSize:10, color:"var(--ink-mute)", marginLeft:4 }}>last {TEACHER_SESSIONS.filter(s=>s.status!=="upcoming").length} sessions</span>
                        </div>
                      </div>
                      <div style={{ display:"flex", gap:5, flexWrap:"wrap" }}>
                        {session.status !== "upcoming" && ATTEND_STATUSES.map(st=>(
                          <button key={st} style={{
                            padding:"3px 9px", borderRadius:8, border:`1.5px solid ${s.status===st?statusBg(st):"var(--rule)"}`,
                            background: s.status===st ? statusBg(st) : "transparent",
                            color: s.status===st ? "white" : "var(--ink-mute)",
                            fontSize:11, fontWeight:700, cursor: session.status==="done"&&!editRoster ? "default" : "pointer",
                            opacity: session.status==="done" && !editRoster && s.status!==st ? 0.4 : 1,
                          }} onClick={() => (session.status!=="done"||editRoster) && setEditRoster(r => (r||session.roster).map((x,idx)=>idx===i?{...x,status:st}:x))}>
                            {ATTEND_LABELS[st]}
                          </button>
                        ))}
                        {session.status === "upcoming" && (
                          <span className="chip flat" style={{ fontSize:10 }}>—</span>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        ) : (
          /* By student view */
          <div style={{ flex:1, overflow:"auto", padding:22 }}>
            <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:14, marginBottom:22 }}>
              {[
                { l:"AVG ATTENDANCE",  v:`${Math.round(studentSummary.reduce((a,s)=>a+s.rate,0)/studentSummary.length)}%`, c:studentSummary.reduce((a,s)=>a+s.rate,0)/studentSummary.length >= 80?"var(--moss)":"var(--gold)" },
                { l:"PERFECT (100%)",  v:studentSummary.filter(s=>s.rate===100).length, c:"var(--moss)" },
                { l:"AT RISK (<75%)",  v:studentSummary.filter(s=>s.rate<75).length, 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:32, marginTop:4, color:k.c }}>{k.v}</div>
                </div>
              ))}
            </div>

            {studentSummary.filter(s=>s.rate<75).length > 0 && (
              <div className="card-flat" style={{ padding:14, marginBottom:16, borderLeft:"3px solid var(--coral)", display:"flex", alignItems:"center", gap:12 }}>
                {I.bell({ size:16 })}
                <div style={{ flex:1 }}>
                  <div style={{ fontWeight:700, fontSize:13 }}>At-risk students</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{studentSummary.filter(s=>s.rate<75).map(s=>s.name).join(", ")} — attendance below 75%</div>
                </div>
                <button className="btn btn-primary" style={{ padding:"6px 12px", fontSize:12 }}>{I.send({ size:14 })} Notify parents</button>
              </div>
            )}

            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                  {["Student","Sessions","Present","Late","Missed","Tech Issue","Rate","Last 4 sessions",""].map(h=>(
                    <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {studentSummary.map((s,i)=>(
                  <tr key={i} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                    <td style={{ padding:"12px" }}>
                      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                        <Avatar name={s.name[0]} color={s.color} size={28}/>
                        <span style={{ fontWeight:700 }}>{s.name}</span>
                      </div>
                    </td>
                    <td style={{ padding:"12px", textAlign:"center" }}>{s.total}</td>
                    <td style={{ padding:"12px", textAlign:"center", color:"var(--moss)", fontWeight:700 }}>{s.present}</td>
                    <td style={{ padding:"12px", textAlign:"center", color:"var(--gold)", fontWeight:700 }}>{s.late}</td>
                    <td style={{ padding:"12px", textAlign:"center", color:"var(--coral)", fontWeight:700 }}>{s.missed}</td>
                    <td style={{ padding:"12px", textAlign:"center", color:"var(--sky)", fontWeight:700 }}>{s.techIssue}</td>
                    <td style={{ padding:"12px" }}>
                      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                        <div className="progress" style={{ width:80, height:6 }}>
                          <i style={{ width:`${s.rate}%`, background: s.rate>=90?"var(--moss)":s.rate>=75?"var(--gold)":"var(--coral)" }}/>
                        </div>
                        <span style={{ fontWeight:700, fontSize:13, color: s.rate>=90?"var(--moss)":s.rate>=75?"var(--gold)":"var(--coral)" }}>{s.rate}%</span>
                      </div>
                    </td>
                    <td style={{ padding:"12px" }}>
                      <div style={{ display:"flex", gap:3 }}>
                        {TEACHER_SESSIONS.filter(sess=>sess.status!=="upcoming").slice(0,4).map((sess,si)=>{
                          const entry = sess.roster.find(r=>r.name===s.name);
                          const st = entry ? entry.status : "absent";
                          return (
                            <div key={si} title={`${fmtSessionDate(sess.day)}: ${ATTEND_LABELS[st]||st}`} style={{ width:12, height:20, borderRadius:3, background:statusColor(st), display:"flex", alignItems:"center", justifyContent:"center" }}>
                              <div style={{ width:4, height:4, borderRadius:"50%", background:"rgba(255,255,255,.7)" }}/>
                            </div>
                          );
                        })}
                      </div>
                    </td>
                    <td style={{ padding:"12px" }}>
                      <button className="btn btn-ghost" style={{ padding:"3px 8px", fontSize:11 }}>Message</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </Themed>
  );
};

// ── Parent: Schedule (read-only, child-filtered) ─────────────────────────────
// Shows only Maya's sessions (Batch C). No admin controls.

const ParentSchedule = ({ go, session }) => {
  const sid = session?.studentId;
  const { data: PARENT_SESSIONS, loading } = useApi(sid ? `/parent/sessions/${sid}` : "/parent/sessions/0");
  const [copied, setCopied] = React.useState(null);
  const copyLink = (link, id) => {
    navigator.clipboard?.writeText(link).catch(()=>{});
    setCopied(id);
    setTimeout(() => setCopied(null), 2000);
  };
  const statusStyle = s => ({
    today:    { bg:"var(--coral)",    label:"TODAY" },
    upcoming: { bg:"var(--moss)",     label:"UPCOMING" },
    done:     { bg:"var(--ink-mute)", label:"DONE" },
  }[s] || { bg:"var(--ink-mute)", label:"—" });
  const upcomingCount = PARENT_SESSIONS.filter(s => s.status === "upcoming" || s.status === "today").length;

  return (
    <div className="codeland" style={{ width:"100%", height:"100%", background:"var(--paper)", display:"flex", flexDirection:"column" }}>
      {/* Header */}
      <div style={{ padding:"14px 26px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:14 }}>
        <button onClick={() => go && go("/app/parent")} style={{ display:"flex", alignItems:"center", gap:6, background:"none", border:"none", cursor:"pointer", color:"var(--ink-soft)", fontSize:13, fontFamily:"var(--font-ui)" }}>
          {I.arrowL({ size:16 })} Back
        </button>
        <div style={{ width:1, height:20, background:"var(--rule)" }}/>
        <div>
          <div className="display" style={{ fontSize:20 }}>Class Schedule</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>Upcoming &amp; past sessions</div>
        </div>
        <div style={{ flex:1 }}/>
        {upcomingCount > 0
          ? <div className="chip" style={{ background:"var(--moss)", color:"white" }}>{I.check({ size:14 })} {upcomingCount} upcoming</div>
          : <div className="chip" style={{ background:"var(--paper-deep)", color:"var(--ink-mute)" }}>{I.check({ size:14 })} All caught up</div>
        }
      </div>

      {/* Session cards */}
      <div style={{ flex:1, overflow:"auto", padding:"24px 26px", display:"flex", flexDirection:"column", gap:14 }}>
        {loading && <Spinner/>}
        {!loading && PARENT_SESSIONS.length === 0 && (
          <div style={{ flex:1, display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", gap:16, padding:60, textAlign:"center" }}>
            <div style={{ width:64, height:64, borderRadius:999, background:"var(--paper-card)", border:"var(--border-thin)", display:"grid", placeItems:"center", color:"var(--ink-mute)" }}>
              {I.check({ size:28 })}
            </div>
            <div>
              <div className="display" style={{ fontSize:22 }}>You're all caught up!</div>
              <div style={{ fontSize:13, color:"var(--ink-mute)", marginTop:6 }}>No upcoming classes scheduled right now. Check back soon.</div>
            </div>
            <button onClick={() => go && go("/app/parent")} className="btn btn-ghost" style={{ padding:"8px 20px", fontSize:13 }}>
              {I.arrowL({ size:14 })} Back to home
            </button>
          </div>
        )}
        {!loading && PARENT_SESSIONS.length > 0 && PARENT_SESSIONS.map((s, i) => {
          const style = statusStyle(s.status);
          return (
            <div key={i} className="card" style={{ padding:0, overflow:"hidden", opacity: s.status==="done" ? 0.75 : 1 }}>
              <div style={{ display:"flex", alignItems:"stretch" }}>
                {/* Left accent + date */}
                <div style={{ width:100, background:"var(--paper-deep)", borderRight:"var(--border-thin)", padding:"18px 14px", display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", gap:4, flexShrink:0 }}>
                  <span style={{ fontSize:9, fontWeight:800, letterSpacing:".08em", color:style.bg, fontFamily:"var(--font-mono)" }}>{style.label}</span>
                  <div className="display" style={{ fontSize:15, textAlign:"center", lineHeight:1.2 }}>{s.date.split(", ")[0]}<br/><span style={{ fontSize:12, fontWeight:500 }}>{s.date.split(", ")[1]}</span></div>
                  <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", textAlign:"center" }}>{s.time.split(" – ")[0]}</div>
                </div>

                {/* Main content */}
                <div style={{ flex:1, padding:"16px 20px", display:"flex", alignItems:"center", gap:16 }}>
                  <div style={{ flex:1 }}>
                    <div className="display" style={{ fontSize:18 }}>{s.topic}</div>
                    <div style={{ fontSize:13, color:"var(--ink-mute)", marginTop:4 }}>
                      {s.time} · {s.teacher}
                    </div>
                    {s.note && (
                      <div style={{ marginTop:8, padding:"6px 12px", background:"var(--gold)", borderRadius:8, fontSize:12, fontWeight:600, display:"inline-flex", alignItems:"center", gap:6 }}>
                        📝 {s.note}
                      </div>
                    )}
                  </div>

                  {/* Actions */}
                  <div style={{ display:"flex", flexDirection:"column", gap:8, flexShrink:0 }}>
                    {s.status === "today" && (
                      <a href={s.meet} target="_blank" rel="noopener noreferrer" style={{ textDecoration:"none" }}>
                        <button className="btn btn-primary" style={{ padding:"8px 20px", fontSize:13, width:"100%" }}>
                          {I.play({ size:14 })} Join class
                        </button>
                      </a>
                    )}
                    {s.status === "upcoming" && s.meet && (
                      <button onClick={() => copyLink(s.meet, i)} className="btn btn-ghost" style={{ padding:"6px 14px", fontSize:12 }}>
                        {copied===i ? "✓ Copied!" : `${I.upload({ size:13 })} Copy link`}
                      </button>
                    )}
                    {s.status === "done" && (
                      <span style={{ fontSize:12, color:"var(--ink-mute)", fontWeight:600 }}>
                        {I.check({ size:14 })} Completed
                      </span>
                    )}
                  </div>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ── Teacher: My Schedule (read-only, teacher-filtered) ────────────────────────
// Shows only the logged-in teacher's sessions. No admin edit controls.
const TeacherMySchedule = ({ dark = false, go, session }) => {
  const { data: initSessions, loading } = useApi("/schedule");
  const [sessions, setSessions] = React.useState(null);
  const [statusChanging, setStatusChanging] = React.useState(null);
  const allSessions = sessions ?? initSessions;
  const teacherName = session?.name || "";
  const TEACHER_MY_SESSIONS = allSessions.filter(s => !teacherName || s.teacher === teacherName);
  const days = [...new Set(TEACHER_MY_SESSIONS.map(s=>s.day))].sort();
  const fmtDay = d => { try { return new Date(d + "T00:00:00").toLocaleDateString("en-GB", { weekday:"short", day:"numeric", month:"short" }).toUpperCase(); } catch { return d.toUpperCase(); } };
  const statusColor = s => s==="live"?"var(--coral)":s==="done"?"var(--ink-mute)":"var(--moss)";

  const markStatus = async (id, status) => {
    setStatusChanging(id);
    await apiFetch(`/schedule/${id}/status`, { method:"PATCH", body: JSON.stringify({ status }) });
    const fresh = await apiFetch("/schedule").then(r=>r.json());
    setSessions(fresh);
    setStatusChanging(null);
  };

  if (loading) return <Spinner />;
  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/schedule" 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 }}>My Schedule</div>
            <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{teacherName || "Teacher"} · {TEACHER_MY_SESSIONS.length} sessions</div>
          </div>
          <div style={{ flex:1 }}/>
          <div style={{ display:"flex", gap:10, alignItems:"center" }}>
            {[["live","var(--coral)"],["upcoming","var(--moss)"],["done","var(--ink-mute)"]].map(([l,c])=>(
              <span key={l} style={{ display:"inline-flex", alignItems:"center", gap:5, fontSize:12, color:"var(--ink-mute)" }}>
                <span style={{ width:8, height:8, borderRadius:"50%", background:c, display:"inline-block" }}/>{l}
              </span>
            ))}
          </div>
        </div>

        <div style={{ flex:1, overflow:"auto", padding:22, display:"flex", flexDirection:"column", gap:20 }}>
          {/* Stats row */}
          <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:14 }}>
            {[
              { l:"MY BATCHES",   v:[...new Set(TEACHER_MY_SESSIONS.map(s=>s.batch))].length, c:"var(--sky)"   },
              { l:"THIS WEEK",    v:TEACHER_MY_SESSIONS.length, c:"var(--coral)" },
              { l:"LIVE NOW",     v:TEACHER_MY_SESSIONS.filter(s=>s.status==="live").length, c:"var(--coral)" },
              { l:"TOTAL STUDENTS", v:TEACHER_MY_SESSIONS.reduce((a,s)=>a+(s.students||0),0), c:"var(--moss)" },
            ].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, marginTop:4, color:k.c }}>{k.v}</div>
              </div>
            ))}
          </div>

          {/* Sessions by day */}
          {days.map(day => (
            <div key={day}>
              <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)", fontWeight:700, marginBottom:10, letterSpacing:".06em" }}>{fmtDay(day)}</div>
              <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
                {TEACHER_MY_SESSIONS.filter(s=>s.day===day).map(s => (
                  <div key={s.id} className="card-flat" style={{ padding:16, display:"grid", gridTemplateColumns:"90px 1fr 1fr auto", alignItems:"center", gap:16, borderLeft:`3px solid ${statusColor(s.status)}` }}>
                    <div>
                      <div style={{ fontWeight:700, fontSize:14 }}>{s.time}</div>
                      <div style={{ fontSize:11, color:"var(--ink-mute)" }}>–{s.end}</div>
                    </div>
                    <div>
                      <div style={{ fontWeight:700, fontSize:14 }}>{s.batch}</div>
                      <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{s.course}</div>
                    </div>
                    <div style={{ fontSize:12, color:"var(--ink-soft)" }}>
                      <span className="chip flat" style={{ fontSize:10, marginRight:8 }}>{s.students} students</span>
                      <span className="chip flat" style={{ fontSize:10, background:statusColor(s.status), color:"white" }}>{s.status}</span>
                    </div>
                    <div style={{ display:"flex", gap:6, alignItems:"center" }}>
                      {s.meet && s.status !== "done" && (
                        <a href={s.meet} target="_blank" rel="noreferrer" className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12, textDecoration:"none", display:"inline-flex", alignItems:"center", gap:4 }}>
                          {I.play({ size:14 })} Join class
                        </a>
                      )}
                      {s.status === "done" && (
                        <button onClick={() => go && go("/app/teacher/attendance")} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>
                          {I.check({ size:14 })} Recap
                        </button>
                      )}
                      {s.status !== "done" && !s.meet && (
                        <button className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>
                          {I.calendar({ size:13 })} Prepare
                        </button>
                      )}
                      {s.status !== "done" ? (
                        <button
                          disabled={statusChanging === s.id}
                          onClick={() => markStatus(s.id, "done")}
                          style={{ padding:"4px 10px", borderRadius:6, border:"1.5px solid var(--moss)", background:"transparent", color:"var(--moss)", cursor:"pointer", fontSize:11, fontWeight:600, opacity: statusChanging===s.id ? .5 : 1 }}
                        >
                          {statusChanging === s.id ? "…" : "✓ Complete"}
                        </button>
                      ) : (
                        <button
                          disabled={statusChanging === s.id}
                          onClick={() => markStatus(s.id, "upcoming")}
                          style={{ padding:"4px 10px", borderRadius:6, border:"1.5px solid var(--rule-bold)", background:"transparent", color:"var(--ink-mute)", cursor:"pointer", fontSize:11, fontWeight:600 }}
                        >
                          Reopen
                        </button>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: User Accounts (superadmin) ─────────────────────────────────────────
const AdminUsers = ({ dark = true, go }) => {
  const { data: initUsers, loading } = useApi("/admin/users");
  const { data: STUDENTS } = useApi("/students");
  const { data: TEACHERS } = useApi("/teachers");
  const [users, setUsers] = React.useState(null);
  const [showAdd, setShowAdd] = React.useState(false);
  const [form, setForm] = React.useState({ email:"", password:"", role:"admin", name:"", student_id:"", teacher_id:"" });
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState("");
  const list = users ?? initUsers;
  const roleColors = { student:"var(--sky)", parent:"var(--plum)", teacher:"var(--moss)", admin:"var(--coral)", superadmin:"var(--gold)" };

  const refresh = () => apiFetch("/admin/users").then(r=>r.json()).then(setUsers);

  const addUser = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/admin/users", { method:"POST", body: JSON.stringify({
      email: form.email, password: form.password, role: form.role, name: form.name,
      student_id: form.student_id||null, teacher_id: form.teacher_id||null,
    })});
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh();
    setForm({ email:"", password:"", role:"admin", name:"", student_id:"", teacher_id:"" });
    setShowAdd(false); setSaving(false);
  };

  const deleteUser = async id => {
    if (!confirm("Delete this user?")) return;
    await apiFetch(`/admin/users/${id}`, { method:"DELETE" });
    await refresh();
  };

  const toggleStatus = async u => {
    const next = u.status === "suspended" ? "active" : "suspended";
    if (next === "suspended" && !confirm(`Suspend ${u.name || u.email}? Their active sessions will be revoked.`)) return;
    const res = await apiFetch(`/admin/users/${u.id}/status`, { method:"PATCH", body: JSON.stringify({ status: next }) });
    if (!res.ok) { const d = await res.json().catch(()=>({})); alert(d.error || "Failed"); return; }
    await refresh();
  };

  const resetPassword = async u => {
    const pw = prompt(`Set a new password for ${u.name || u.email} (min 8 chars). They'll be asked to change it on next login.`);
    if (pw == null) return;
    if (pw.length < 8) { alert("Password must be at least 8 characters."); return; }
    const res = await apiFetch(`/admin/users/${u.id}/password`, { method:"PATCH", body: JSON.stringify({ password: pw }) });
    if (!res.ok) { const d = await res.json().catch(()=>({})); alert(d.error || "Failed"); return; }
    alert("Password reset. The user's sessions were revoked.");
  };

  if (loading) return <Spinner/>;
  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showAdd && (
        <Modal title="Create user account" onClose={()=>setShowAdd(false)}>
          <form onSubmit={addUser}>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
              <div style={{ gridColumn:"1/-1" }}>
                <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, letterSpacing:".06em" }}>FULL NAME</div>
                <input required style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", boxSizing:"border-box", outline:"none" }} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Priya Raman"/>
              </div>
              {[["EMAIL","email","email","you@epiqminds.com"],["PASSWORD","password","password","min 6 chars"]].map(([l,k,t,ph])=>(
                <div key={k}>
                  <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, letterSpacing:".06em" }}>{l}</div>
                  <input required type={t} style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", boxSizing:"border-box", outline:"none" }} value={form[k]} onChange={e=>setForm(f=>({...f,[k]:e.target.value}))} placeholder={ph}/>
                </div>
              ))}
            </div>
            <div style={{ marginTop:10 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, letterSpacing:".06em" }}>ROLE</div>
              <select style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }} value={form.role} onChange={e=>setForm(f=>({...f,role:e.target.value}))}>
                {["student","parent","teacher","admin","superadmin"].map(r=><option key={r} value={r}>{r}</option>)}
              </select>
            </div>
            {form.role === "student" && (
              <div style={{ marginTop:10 }}>
                <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, letterSpacing:".06em" }}>LINK STUDENT PROFILE</div>
                <select style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }} value={form.student_id} onChange={e=>setForm(f=>({...f,student_id:e.target.value}))}>
                  <option value="">— optional —</option>
                  {STUDENTS.map(s=><option key={s.id} value={s.id}>{s.name}</option>)}
                </select>
              </div>
            )}
            {form.role === "teacher" && (
              <div style={{ marginTop:10 }}>
                <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, letterSpacing:".06em" }}>LINK TEACHER PROFILE</div>
                <select style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }} value={form.teacher_id} onChange={e=>setForm(f=>({...f,teacher_id:e.target.value}))}>
                  <option value="">— optional —</option>
                  {TEACHERS.map(t=><option key={t.id} value={t.id}>{t.name}</option>)}
                </select>
              </div>
            )}
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginTop:10 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:16 }}>
              <button type="button" onClick={()=>setShowAdd(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Creating…":"Create account"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/users" go={go}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
        <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:20 }}>User Accounts</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} accounts</div>
          </div>
          <div style={{ flex:1 }}/>
          <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({size:14})} Create account</button>
        </div>
        <div style={{ flex:1, overflow:"auto", padding:22 }}>
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr>
                {["Name","Email","Role","Linked to","Status","Created",""].map(h=>(
                  <th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)", textAlign:"left", color:"var(--ink-mute)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {list.map((u,i)=>{
                const suspended = u.status === "suspended";
                return (
                <tr key={u.id} style={{ borderTop:i?"var(--border-thin)":"none", opacity: suspended ? 0.6 : 1 }}>
                  <td style={{ padding:"10px 10px", fontWeight:700 }}>{u.name}</td>
                  <td style={{ padding:"10px 10px", color:"var(--ink-soft)", fontSize:12 }}>{u.email}</td>
                  <td style={{ padding:"10px 10px" }}>
                    <span style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background:roleColors[u.role]||"var(--sky)", color:"white" }}>{u.role}</span>
                  </td>
                  <td style={{ padding:"10px 10px", fontSize:12, color:"var(--ink-soft)" }}>{u.student_name || u.teacher_name || "—"}</td>
                  <td style={{ padding:"10px 10px" }}>
                    <span style={{ fontSize:10, fontWeight:700, padding:"2px 8px", borderRadius:999, background: suspended ? "var(--coral)" : "var(--moss)", color:"white" }}>{suspended ? "suspended" : "active"}</span>
                  </td>
                  <td style={{ padding:"10px 10px", fontSize:11, color:"var(--ink-mute)" }}>{new Date(u.created_at).toLocaleDateString("en-IN",{day:"numeric",month:"short",year:"numeric"})}</td>
                  <td style={{ padding:"10px 10px", whiteSpace:"nowrap" }}>
                    <button onClick={()=>resetPassword(u)} style={{ fontSize:11, padding:"4px 10px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--ink-soft)", cursor:"pointer", fontWeight:600, marginRight:6 }}>Reset PW</button>
                    <button onClick={()=>toggleStatus(u)} style={{ fontSize:11, padding:"4px 10px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color: suspended ? "var(--moss)" : "var(--gold)", cursor:"pointer", fontWeight:600, marginRight:6 }}>{suspended ? "Activate" : "Suspend"}</button>
                    <button onClick={()=>deleteUser(u.id)} style={{ fontSize:11, padding:"4px 10px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--coral)", cursor:"pointer", fontWeight:600 }}>Delete</button>
                  </td>
                </tr>
              );})}
            </tbody>
          </table>
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Roles & Permissions (superadmin RBAC) ──────────────────────────────
const AdminRoles = ({ dark = true, go, session = {} }) => {
  const { data: initRoles, loading } = useApi("/roles");
  const { data: initUsers, loading: usersLoading } = useApi("/admin/users");
  const { data: permCatalog } = useApi("/permissions", {});
  // Build the permission list from the backend catalog so it can never drift
  // out of sync with what the server actually enforces. Falls back to the
  // static PERM_LIST until the catalog loads.
  const permList = React.useMemo(() => {
    const cat = permCatalog && permCatalog.permissions;
    if (!cat || !Object.keys(cat).length) return PERM_LIST;
    return Object.entries(cat).map(([key, desc]) => ({
      key,
      label: key.replace(/_/g, " ").replace(/\b\w/g, c => c.toUpperCase()),
      desc,
    }));
  }, [permCatalog]);
  const [roles, setRoles] = React.useState(null);
  const [users, setUsers] = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const [editing, setEditing] = React.useState(null); // permissions array being edited
  const [showCreate, setShowCreate] = React.useState(false);
  const [newName, setNewName] = React.useState("");
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState("");
  const [tab, setTab] = React.useState("roles"); // "roles" | "users"
  const [changingRole, setChangingRole] = React.useState(null); // userId being changed
  const list = roles ?? initRoles;
  const userList = users ?? initUsers;
  const role = selected ? list.find(r=>r.id===selected) : null;

  const refresh = () => apiFetch("/roles").then(r=>r.json()).then(setRoles);
  const refreshUsers = () => apiFetch("/admin/users").then(r=>r.json()).then(setUsers);

  const changeUserRole = async (uid, newRole) => {
    setChangingRole(uid);
    await apiFetch(`/admin/users/${uid}/role`, { method:"PATCH", body: JSON.stringify({ role: newRole }) });
    await refreshUsers();
    setChangingRole(null);
  };

  const openRole = r => {
    setSelected(r.id);
    setEditing([...(r.permissions||[])]);
  };

  const togglePerm = key => {
    setEditing(prev => prev.includes(key) ? prev.filter(p=>p!==key) : [...prev, key]);
  };

  const savePerms = async () => {
    setSaving(true);
    await apiFetch(`/roles/${selected}`, { method:"PATCH", body: JSON.stringify({ permissions: editing }) });
    await refresh();
    setSaving(false);
  };

  const createRole = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/roles", { method:"POST", body: JSON.stringify({ name: newName, permissions: [] }) });
    const data = await res.json();
    if (!res.ok) { setError(data.error||"Failed"); setSaving(false); return; }
    await refresh(); setNewName(""); setShowCreate(false); setSaving(false);
  };

  const deleteRole = async id => {
    if (!confirm("Delete this role?")) return;
    const res = await apiFetch(`/roles/${id}`, { method:"DELETE" });
    if (!res.ok) { const d = await res.json(); alert(d.error); return; }
    setSelected(null); await refresh();
  };

  if (loading) return <Spinner/>;
  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showCreate && (
        <Modal title="Create role" onClose={()=>setShowCreate(false)}>
          <form onSubmit={createRole}>
            <div style={{ marginBottom:14 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:6, letterSpacing:".06em" }}>ROLE NAME</div>
              <input required style={{ width:"100%", padding:"9px 12px", borderRadius:10, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", boxSizing:"border-box", outline:"none" }} value={newName} onChange={e=>setNewName(e.target.value)} placeholder="e.g. coordinator"/>
            </div>
            {error && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:12 }}>{error}</div>}
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end" }}>
              <button type="button" onClick={()=>setShowCreate(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Creating…":"Create role"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/roles" go={go}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>
        {/* Tab bar */}
        <div style={{ display:"flex", alignItems:"center", gap:0, padding:"0 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)" }}>
          {[["roles","Roles & Permissions"],["users","User Assignments"]].map(([t,l])=>(
            <button key={t} onClick={()=>setTab(t)} style={{
              padding:"14px 18px", fontSize:13, fontWeight:700, border:"none", background:"transparent", cursor:"pointer",
              color: tab===t ? "var(--ink)" : "var(--ink-mute)",
              borderBottom: tab===t ? "2px solid var(--coral)" : "2px solid transparent",
              marginBottom:-1,
            }}>{l}</button>
          ))}
          <div style={{ flex:1 }}/>
          {tab === "roles" && session.role === "superadmin" && <button onClick={()=>setShowCreate(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({size:12})} New role</button>}
        </div>

        {tab === "users" ? (
          <div style={{ flex:1, overflow:"auto", padding:22 }}>
            <div style={{ marginBottom:16 }}>
              <div className="display" style={{ fontSize:18 }}>User Assignments</div>
              <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4 }}>Change the role assigned to each user account</div>
            </div>
            {usersLoading ? <Spinner/> : (
              <div className="card-flat" style={{ overflow:"hidden" }}>
                <table style={{ width:"100%", borderCollapse:"collapse" }}>
                  <thead>
                    <tr style={{ background:"var(--paper-deep)" }}>
                      {["Name","Email","Current Role","Change Role"].map(h=>(
                        <th key={h} style={{ padding:"10px 16px", textAlign:"left", fontSize:11, fontWeight:700, color:"var(--ink-mute)", letterSpacing:".06em" }}>{h.toUpperCase()}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {userList.map((u,i)=>{
                      const roleColor = { superadmin:"var(--coral)", admin:"var(--plum)", teacher:"var(--sky)", student:"var(--moss)", parent:"var(--gold)" }[u.role] || "var(--ink-mute)";
                      return (
                        <tr key={u.id} style={{ borderTop: i ? "var(--border-thin)" : "none" }}>
                          <td style={{ padding:"12px 16px" }}>
                            <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                              <Avatar name={(u.name||u.email)[0].toUpperCase()} color={roleColor} size={30}/>
                              <div style={{ fontWeight:700, fontSize:13 }}>{u.name || "—"}</div>
                            </div>
                          </td>
                          <td style={{ padding:"12px 16px", fontSize:12, color:"var(--ink-mute)" }}>{u.email}</td>
                          <td style={{ padding:"12px 16px" }}>
                            <span style={{ padding:"3px 10px", borderRadius:999, fontSize:11, fontWeight:700, background:roleColor, color:"white" }}>{u.role}</span>
                          </td>
                          <td style={{ padding:"12px 16px" }}>
                            <select
                              value={u.role}
                              disabled={changingRole === u.id}
                              onChange={e => changeUserRole(u.id, e.target.value)}
                              style={{ padding:"6px 10px", borderRadius:8, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:12, fontFamily:"var(--font-ui)", color:"var(--ink)", cursor:"pointer", outline:"none" }}
                            >
                              {["student","parent","teacher","admin","superadmin","content_manager"].map(r=>(
                                <option key={r} value={r}>{r.replace("_"," ")}</option>
                              ))}
                            </select>
                            {changingRole === u.id && <span style={{ marginLeft:8, fontSize:11, color:"var(--ink-mute)" }}>Saving…</span>}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}
          </div>
        ) : (

        <div style={{ flex:1, display:"flex", minWidth:0 }}>
        {/* Role list */}
        <div style={{ width:240, borderRight:"var(--border-thin)", display:"flex", flexDirection:"column", background:"var(--paper-card)" }}>
          <div style={{ padding:"12px 16px", borderBottom:"var(--border-thin)", display:"flex", alignItems:"center", gap:8 }}>
            <div className="display" style={{ fontSize:16, flex:1 }}>Roles</div>
          </div>
          <div style={{ flex:1, overflow:"auto", padding:10 }}>
            {list.map(r=>(
              <button key={r.id} onClick={()=>openRole(r)} style={{ display:"flex", alignItems:"center", gap:10, width:"100%", padding:"10px 12px", borderRadius:8, border:"none", marginBottom:4,
                background: selected===r.id?"var(--paper-deep)":"transparent", cursor:"pointer", textAlign:"left" }}>
                <div style={{ flex:1 }}>
                  <div style={{ fontWeight:700, fontSize:13, color:"var(--ink)" }}>{r.name}</div>
                  <div style={{ fontSize:10, color:"var(--ink-mute)", marginTop:1 }}>{(r.permissions||[]).length} permissions{r.is_system?" · system":""}</div>
                </div>
                {r.is_system && <span style={{ fontSize:9, padding:"2px 6px", borderRadius:999, background:"var(--paper-deep)", color:"var(--ink-mute)", fontWeight:600 }}>SYSTEM</span>}
              </button>
            ))}
          </div>
        </div>

        {/* Permissions editor */}
        {role && editing ? (
          <div style={{ flex:1, display:"flex", flexDirection:"column", overflow:"hidden" }}>
            <div style={{ padding:"12px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12 }}>
              <div>
                <div className="display" style={{ fontSize:18 }}>{role.name}</div>
                <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{editing.length} permissions selected</div>
              </div>
              <div style={{ flex:1 }}/>
              {!role.is_system && <button onClick={()=>deleteRole(role.id)} style={{ fontSize:11, padding:"6px 12px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--coral)", cursor:"pointer", fontWeight:600 }}>Delete role</button>}
              <button onClick={savePerms} disabled={saving} className="btn btn-primary" style={{ padding:"6px 16px", fontSize:12 }}>{saving?"Saving…":"Save permissions"}</button>
            </div>
            <div style={{ flex:1, overflow:"auto", padding:22 }}>
              <div style={{ display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(280px,1fr))", gap:10 }}>
                {permList.map(p=>{
                  const active = editing.includes(p.key);
                  return (
                    <button key={p.key} type="button" onClick={()=>!role.is_system && togglePerm(p.key)}
                      title={p.desc || p.key}
                      style={{ display:"flex", alignItems:"center", gap:12, padding:"12px 16px", borderRadius:10, border:`2px solid ${active?"var(--coral)":"var(--rule)"}`,
                        background: active?"rgba(var(--coral-rgb),.07)":"var(--paper-card)",
                        cursor: role.is_system?"default":"pointer", textAlign:"left", width:"100%" }}>
                      <div style={{ width:20, height:20, borderRadius:6, border:`2px solid ${active?"var(--coral)":"var(--rule)"}`, background:active?"var(--coral)":"transparent", flexShrink:0, display:"grid", placeItems:"center" }}>
                        {active && <svg width="10" height="10" viewBox="0 0 12 12"><polyline points="2,6 5,9 10,3" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round"/></svg>}
                      </div>
                      <div style={{ minWidth:0 }}>
                        <div style={{ fontSize:13, fontWeight:700, color:"var(--ink)" }}>{p.label}</div>
                        <div style={{ fontSize:10, color:"var(--ink-mute)", fontFamily:"var(--font-mono)" }}>{p.key}</div>
                      </div>
                    </button>
                  );
                })}
              </div>
            </div>
          </div>
        ) : (
          <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center", color:"var(--ink-mute)", flexDirection:"column", gap:10 }}>
            <div style={{ fontSize:32 }}>🔒</div>
            <div style={{ fontSize:14, fontWeight:600 }}>Select a role to manage permissions</div>
          </div>
        )}
        </div>
        )}
      </div>
    </Themed>
  );
};


// ── Content Manager ────────────────────────────────────────────────────────────
const CM_NAV = [
  ["Courses",  I.book,    "/app/content"],
  ["Upload",   I.rocket,  "/app/content/upload"],
];

const ContentManagerSidebar = ({ active, go, session }) => (
  <div style={{ width:220, background:"var(--paper-card)", borderRight:"var(--border-thin)", display:"flex", flexDirection:"column", height:"100%" }}>
    <div style={{ padding:"18px 16px 12px", borderBottom:"var(--border-thin)" }}>
      <div className="display" style={{ fontSize:16 }}>EpiqMinds<span style={{color:"var(--coral)"}}>/content</span></div>
      <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>{session?.name || "Content Manager"}</div>
    </div>
    <div style={{ flex:1, padding:10 }}>
      {CM_NAV.map(([label, Icon, path]) => {
        const on = active === path;
        return (
          <button key={path} onClick={() => go(path)} style={{
            display:"flex", alignItems:"center", gap:10, width:"100%", padding:"9px 12px",
            borderRadius:8, border:"none", marginBottom:2, cursor:"pointer", textAlign:"left",
            background: on ? "var(--coral)" : "transparent",
            color: on ? "white" : "var(--ink-soft)", fontWeight: on ? 700 : 400, fontSize:13,
          }}>
            {Icon({ size:16 })} {label}
          </button>
        );
      })}
    </div>
  </div>
);

const ALLOWED_TYPES = ["pdf","ppt","pptx","txt","doc","docx"];
const MIME_ICONS = { pdf:"📄", ppt:"📊", pptx:"📊", txt:"📝", doc:"📝", docx:"📝" };

const ContentManagerHome = ({ go, session }) => {
  const route = window.location.hash.slice(1);
  const { data: courses, loading: cLoading } = useApi("/courses");
  const [selectedCourse, setSelectedCourse] = React.useState(null);
  const [cmTab, setCmTab] = React.useState("files");
  const { data: initFiles, loading: fLoading } = useApi(selectedCourse ? `/course-files/${selectedCourse.id}` : null);
  const [files, setFiles] = React.useState(null);
  const fileList = files ?? initFiles;

  // Units state
  const { data: initUnits } = useApi(selectedCourse ? `/content/${selectedCourse.id}` : null);
  const [units, setUnits] = React.useState(null);
  const unitList = units ?? initUnits ?? [];
  const refreshUnits = () => selectedCourse && apiFetch(`/content/${selectedCourse.id}`).then(r=>r.json()).then(setUnits);
  const [unitTitle, setUnitTitle] = React.useState("");
  const [unitSaving, setUnitSaving] = React.useState(false);
  const [unitError, setUnitError] = React.useState("");
  const [lessonForm, setLessonForm] = React.useState({ title:"", unit_id:"", type:"video", youtube_url:"", duration:"" });
  const [lessonSaving, setLessonSaving] = React.useState(false);
  const [lessonError, setLessonError] = React.useState("");
  const [showLessonForm, setShowLessonForm] = React.useState(false);

  const [uploading, setUploading] = React.useState(false);
  const [uploadError, setUploadError] = React.useState("");
  const [dragOver, setDragOver] = React.useState(false);
  const fileInputRef = React.useRef();

  React.useEffect(() => { setFiles(null); setUnits(null); }, [selectedCourse?.id]);

  const refreshFiles = () => {
    if (!selectedCourse) return;
    apiFetch(`/course-files/${selectedCourse.id}`).then(r=>r.json()).then(setFiles);
  };

  const cmSaveUnit = async () => {
    if (!unitTitle.trim()) { setUnitError("Title required"); return; }
    setUnitError(""); setUnitSaving(true);
    const res = await apiFetch(`/courses/${selectedCourse.id}/units`, { method:"POST", body: JSON.stringify({ title: unitTitle.trim() }) });
    if (!res.ok) { const d=await res.json(); setUnitError(d.error||"Failed"); setUnitSaving(false); return; }
    setUnitTitle(""); setUnitSaving(false); refreshUnits();
  };

  const cmSaveLesson = async () => {
    if (!lessonForm.title.trim()) { setLessonError("Title required"); return; }
    if (!lessonForm.unit_id) { setLessonError("Select a unit"); return; }
    setLessonError(""); setLessonSaving(true);
    const res = await apiFetch(`/units/${lessonForm.unit_id}/lessons`, { method:"POST", body: JSON.stringify({ title:lessonForm.title, type:lessonForm.type, youtube_url:lessonForm.youtube_url, duration:lessonForm.duration }) });
    if (!res.ok) { const d=await res.json(); setLessonError(d.error||"Failed"); setLessonSaving(false); return; }
    setLessonForm({ title:"", unit_id:lessonForm.unit_id, type:"video", youtube_url:"", duration:"" });
    setShowLessonForm(false); setLessonSaving(false); refreshUnits();
  };

  const handleFiles = async (rawFiles) => {
    if (!selectedCourse) { setUploadError("Select a course first"); return; }
    setUploadError("");
    setUploading(true);
    for (const file of Array.from(rawFiles)) {
      const ext = file.name.split(".").pop().toLowerCase();
      if (!ALLOWED_TYPES.includes(ext)) { setUploadError(`${file.name}: unsupported type. Allowed: ${ALLOWED_TYPES.join(", ")}`); continue; }
      if (file.size > 20 * 1024 * 1024) { setUploadError(`${file.name}: max 20 MB`); continue; }
      const reader = new FileReader();
      await new Promise(resolve => {
        reader.onload = async (e) => {
          await apiFetch("/course-files", { method:"POST", body: JSON.stringify({ course_id: selectedCourse.id, title: file.name, file_type: ext, file_data: e.target.result }) });
          resolve();
        };
        reader.readAsDataURL(file);
      });
    }
    setUploading(false);
    refreshFiles();
  };

  const deleteFile = async (id) => {
    if (!confirm("Delete this file?")) return;
    await apiFetch(`/course-files/${id}`, { method:"DELETE" });
    refreshFiles();
  };

  const fmtSize = b => b > 1048576 ? `${(b/1048576).toFixed(1)} MB` : `${(b/1024).toFixed(0)} KB`;

  return (
    <div style={{ width:"100%", height:"100%", display:"flex", fontFamily:"var(--font-ui)", background:"var(--paper)" }}>
      <ContentManagerSidebar active={route} go={go} session={session}/>
      <div style={{ flex:1, display:"flex", minWidth:0 }}>

        {/* Course list panel */}
        <div style={{ width:280, borderRight:"var(--border-thin)", display:"flex", flexDirection:"column", background:"var(--paper-card)" }}>
          <div style={{ padding:"12px 16px", borderBottom:"var(--border-thin)" }}>
            <div style={{ fontWeight:700, fontSize:13 }}>Courses</div>
            <div style={{ fontSize:11, color:"var(--ink-mute)" }}>Select to manage files</div>
          </div>
          <div style={{ flex:1, overflow:"auto", padding:10 }}>
            {cLoading ? <Spinner/> : courses.map(c => {
              const on = selectedCourse?.id === c.id;
              return (
                <button key={c.id} onClick={() => setSelectedCourse(c)} style={{
                  display:"flex", alignItems:"center", gap:10, width:"100%", padding:"10px 12px",
                  borderRadius:8, border:`1.5px solid ${on?"var(--coral)":"transparent"}`,
                  background: on ? "rgba(var(--coral-rgb),.07)" : "transparent",
                  cursor:"pointer", textAlign:"left", marginBottom:4,
                }}>
                  <div style={{ width:36, height:36, borderRadius:10, background: on ? "var(--coral)" : "var(--paper-deep)", display:"grid", placeItems:"center", color: on ? "white" : "var(--ink-mute)", flexShrink:0 }}>
                    {I.book({ size:18 })}
                  </div>
                  <div>
                    <div style={{ fontWeight:700, fontSize:13, color:"var(--ink)" }}>{c.name}</div>
                    <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{c.level}</div>
                  </div>
                </button>
              );
            })}
          </div>
        </div>

        {/* File management panel */}
        <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, overflow:"auto" }}>
          {!selectedCourse ? (
            <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center", flexDirection:"column", gap:12, color:"var(--ink-mute)", padding:40 }}>
              <div style={{ fontSize:48 }}>📚</div>
              <div style={{ fontSize:16, fontWeight:700, color:"var(--ink)" }}>Select a course</div>
              <div style={{ fontSize:13 }}>Pick a course from the left to upload and manage its materials</div>
            </div>
          ) : (
            <>
              <div style={{ padding:"14px 22px", borderBottom:"var(--border-thin)", background:"var(--paper-card)", display:"flex", alignItems:"center", gap:12 }}>
                <div>
                  <div className="display" style={{ fontSize:20 }}>{selectedCourse.name}</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)" }}>{selectedCourse.level} · {unitList.length} units · {fileList?.length ?? "—"} files</div>
                </div>
                <div style={{ flex:1 }}/>
                <Tabs items={["Files","Units & Lessons"]} active={cmTab==="files"?"Files":"Units & Lessons"} onChange={v=>setCmTab(v==="Files"?"files":"units")}/>
                {cmTab==="files" && (
                  <button className="btn btn-primary" onClick={() => fileInputRef.current?.click()} style={{ padding:"8px 16px", fontSize:13 }}>
                    {I.plus({ size:14 })} Upload files
                  </button>
                )}
                <input ref={fileInputRef} type="file" multiple accept=".pdf,.ppt,.pptx,.txt,.doc,.docx" style={{ display:"none" }} onChange={e => handleFiles(e.target.files)}/>
              </div>

              <div style={{ padding:22, flex:1, overflow:"auto" }}>
              {cmTab === "units" && (
                <div style={{ display:"flex", flexDirection:"column", gap:16 }}>
                  {/* Add unit */}
                  <div className="card-flat" style={{ padding:16 }}>
                    <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:8, letterSpacing:".06em" }}>ADD UNIT</div>
                    <div style={{ display:"flex", gap:8 }}>
                      <input value={unitTitle} onChange={e=>setUnitTitle(e.target.value)} placeholder="e.g. Unit 1 · Getting Started"
                        style={{ flex:1, padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)", outline:"none" }}
                        onKeyDown={async e => { if(e.key==="Enter"){ e.preventDefault(); await cmSaveUnit(); } }}/>
                      <button disabled={unitSaving} onClick={cmSaveUnit} className="btn btn-primary" style={{ padding:"8px 16px", fontSize:13 }}>{unitSaving?"…":"Add unit"}</button>
                    </div>
                    {unitError && <div style={{ color:"var(--coral)", fontSize:12, marginTop:6 }}>{unitError}</div>}
                  </div>

                  {/* Add lesson */}
                  <div className="card-flat" style={{ padding:16 }}>
                    <div style={{ display:"flex", alignItems:"center", justifyContent:"space-between", marginBottom: showLessonForm?12:0 }}>
                      <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>ADD LESSON</div>
                      <button onClick={()=>setShowLessonForm(v=>!v)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11 }}>{showLessonForm?"Cancel":"+ Add lesson"}</button>
                    </div>
                    {showLessonForm && (
                      <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
                        <input value={lessonForm.title} onChange={e=>setLessonForm(f=>({...f,title:e.target.value}))} placeholder="Lesson title"
                          style={{ width:"100%", padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)", boxSizing:"border-box", outline:"none" }}/>
                        <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:8 }}>
                          <select value={lessonForm.unit_id} onChange={e=>setLessonForm(f=>({...f,unit_id:e.target.value}))}
                            style={{ padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)" }}>
                            <option value="">— select unit —</option>
                            {unitList.map(u=><option key={u.id} value={u.id}>{u.unit}</option>)}
                          </select>
                          <select value={lessonForm.type} onChange={e=>setLessonForm(f=>({...f,type:e.target.value}))}
                            style={{ padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)" }}>
                            {["video","quiz","homework","project"].map(t=><option key={t} value={t}>{t}</option>)}
                          </select>
                        </div>
                        {lessonForm.type==="video" && (
                          <input value={lessonForm.youtube_url} onChange={e=>setLessonForm(f=>({...f,youtube_url:e.target.value}))} placeholder="YouTube URL"
                            style={{ width:"100%", padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)", boxSizing:"border-box", outline:"none" }}/>
                        )}
                        <input value={lessonForm.duration} onChange={e=>setLessonForm(f=>({...f,duration:e.target.value}))} placeholder="Duration (optional, e.g. 8:22)"
                          style={{ width:"100%", padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, color:"var(--ink)", fontFamily:"var(--font-ui)", boxSizing:"border-box", outline:"none" }}/>
                        {lessonError && <div style={{ color:"var(--coral)", fontSize:12 }}>{lessonError}</div>}
                        <button disabled={lessonSaving} onClick={cmSaveLesson} className="btn btn-primary" style={{ padding:"9px 0", fontSize:13 }}>{lessonSaving?"Saving…":"Save lesson"}</button>
                      </div>
                    )}
                  </div>

                  {/* Unit list */}
                  {unitList.length === 0 ? (
                    <div style={{ textAlign:"center", padding:32, color:"var(--ink-mute)", fontSize:13 }}>No units yet — add one above.</div>
                  ) : unitList.map(u=>(
                    <div key={u.id} className="card-flat" style={{ padding:14 }}>
                      <div style={{ fontWeight:700, fontSize:14, marginBottom:8 }}>{u.unit}</div>
                      {(u.lessons||[]).length === 0
                        ? <div style={{ fontSize:12, color:"var(--ink-mute)" }}>No lessons yet.</div>
                        : (u.lessons||[]).map((l,li)=>(
                          <div key={l.id||li} style={{ display:"flex", alignItems:"center", gap:8, padding:"6px 8px", borderRadius:7, marginBottom:3, background:"var(--paper-deep)" }}>
                            <div style={{ width:24, height:24, borderRadius:6, background: l.type==="video"?"var(--coral)":l.type==="quiz"?"var(--sky)":"var(--gold)", color:"white", display:"grid", placeItems:"center", flexShrink:0 }}>
                              {l.type==="video"?I.play({size:10}):l.type==="quiz"?I.puzzle({size:10}):I.book({size:10})}
                            </div>
                            <span style={{ fontSize:12, fontWeight:600, flex:1 }}>{l.title}</span>
                            <span style={{ fontSize:10, color:"var(--ink-mute)" }}>{l.duration||l.type}</span>
                          </div>
                        ))
                      }
                    </div>
                  ))}
                </div>
              )}
              {cmTab === "files" && (<>
                {/* Drop zone */}
                <div
                  onDragOver={e => { e.preventDefault(); setDragOver(true); }}
                  onDragLeave={() => setDragOver(false)}
                  onDrop={e => { e.preventDefault(); setDragOver(false); handleFiles(e.dataTransfer.files); }}
                  onClick={() => fileInputRef.current?.click()}
                  style={{
                    borderRadius:14, border:`2px dashed ${dragOver ? "var(--coral)" : "var(--rule-bold)"}`,
                    background: dragOver ? "rgba(var(--coral-rgb),.06)" : "var(--paper-card)",
                    padding:"32px 22px", textAlign:"center", cursor:"pointer", transition:"border .15s, background .15s",
                    marginBottom:20,
                  }}
                >
                  <div style={{ fontSize:36, marginBottom:8 }}>📂</div>
                  <div style={{ fontWeight:700, fontSize:14, color:"var(--ink)" }}>Drop files here or click to browse</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4 }}>PDF, PPT, PPTX, TXT, DOC, DOCX · Max 20 MB each</div>
                  {uploading && <div style={{ marginTop:10, fontSize:12, color:"var(--coral)", fontWeight:600 }}>Uploading…</div>}
                  {uploadError && <div style={{ marginTop:8, fontSize:12, color:"var(--coral)" }}>{uploadError}</div>}
                </div>

                {/* File list */}
                {fLoading ? <Spinner/> : !fileList?.length ? (
                  <div style={{ textAlign:"center", padding:"24px 0", color:"var(--ink-mute)", fontSize:13 }}>No files yet. Upload the first one above.</div>
                ) : (
                  <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
                    {fileList.map(f => (
                      <div key={f.id} className="card-flat" style={{ padding:"12px 16px", display:"flex", alignItems:"center", gap:14 }}>
                        <div style={{ fontSize:28, flexShrink:0 }}>{MIME_ICONS[f.file_type] || "📁"}</div>
                        <div style={{ flex:1, minWidth:0 }}>
                          <div style={{ fontWeight:700, fontSize:13, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{f.title}</div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>
                            <span style={{ padding:"1px 7px", borderRadius:999, background:"var(--paper-deep)", fontWeight:700, textTransform:"uppercase", fontSize:10, marginRight:6 }}>{f.file_type}</span>
                            {fmtSize(f.size_bytes)} · {new Date(f.created_at).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}
                          </div>
                        </div>
                        <button onClick={() => deleteFile(f.id)} style={{ padding:"5px 12px", borderRadius:6, border:"var(--border-thin)", background:"transparent", color:"var(--coral)", cursor:"pointer", fontSize:12, fontWeight:600, flexShrink:0 }}>Delete</button>
                      </div>
                    ))}
                  </div>
                )}
              </>)}
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { ContentManagerHome });
