// ── Admin: Student CRM ────────────────────────────────────────────────────────
// ── Reusable Modal shell ───────────────────────────────────────────────────────
const Modal = ({ title, onClose, children }) => (
  <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.5)", display:"flex", alignItems:"center", justifyContent:"center", zIndex:9999 }}
       onClick={e => e.target === e.currentTarget && onClose()}>
    <div style={{ background:"var(--paper-card)", borderRadius:16, padding:28, width:420, maxWidth:"90vw", boxShadow:"0 24px 60px rgba(0,0,0,.3)" }}>
      <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:20 }}>
        <div className="display" style={{ fontSize:18 }}>{title}</div>
        <button onClick={onClose} style={{ background:"none", border:"none", fontSize:20, cursor:"pointer", color:"var(--ink-mute)", lineHeight:1 }}>×</button>
      </div>
      {children}
    </div>
  </div>
);

const FormField = ({ label, children }) => (
  <div style={{ marginBottom:14 }}>
    <div className="mono" style={{ fontSize:10, fontWeight:700, marginBottom:5, letterSpacing:".06em", color:"var(--ink-mute)" }}>{label}</div>
    {children}
  </div>
);

const inputStyle = { 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" };
const selectStyle = { ...inputStyle };

const AdminStudents = ({ dark = true, go }) => {
  const { data: STUDENTS, loading } = useApi("/students");
  const { data: BATCHES } = useApi("/batches");
  const { data: TEACHERS } = useApi("/teachers");
  const [search, setSearch]     = React.useState("");
  const [selected, setSelected] = React.useState(null);
  const [showAdd, setShowAdd]   = React.useState(false);
  const [editStudent, setEditStudent] = React.useState(null);
  const { data: COURSES } = useApi("/courses/list");
  const [form, setForm]         = React.useState({ name:"", age:"", student_type:"batch", batch_id:"", course_id:"", teacher_id:"", student_email:"", student_password:"", parent_name:"", parent_email:"", parent_password:"" });
  const [editForm, setEditForm] = React.useState({ name:"", age:"", student_type:"batch", batch_id:"", course_id:"", teacher_id:"", status:"" });
  const [saving, setSaving]     = React.useState(false);
  const [error, setError]       = React.useState("");
  const [students, setStudents] = React.useState(null);
  const list = students ?? STUDENTS;

  const filtered = list.filter(s =>
    (s.name||"").toLowerCase().includes(search.toLowerCase()) ||
    (s.course||"").toLowerCase().includes(search.toLowerCase()) ||
    (s.batch||"").toLowerCase().includes(search.toLowerCase())
  );
  const student = selected ? list.find(s => s.id === selected) : null;

  const saveStudent = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/students", { method:"POST", body: JSON.stringify({
      name: form.name, age: parseInt(form.age)||null,
      student_type: form.student_type,
      batch_id: form.student_type === "batch" ? (form.batch_id||null) : null,
      course_id: form.student_type === "individual" ? (form.course_id||null) : null,
      teacher_id: form.teacher_id||null,
      student_email: form.student_email||null, student_password: form.student_password||null,
      parent_name: form.parent_name||null, parent_email: form.parent_email||null, parent_password: form.parent_password||null,
    })});
    const data = await res.json();
    if (!res.ok) { setError(data.error || "Failed"); setSaving(false); return; }
    const fresh = await apiFetch("/students").then(r=>r.json());
    setStudents(fresh);
    setForm({ name:"", age:"", student_type:"batch", batch_id:"", course_id:"", teacher_id:"", student_email:"", student_password:"", parent_name:"", parent_email:"", parent_password:"" });
    setShowAdd(false); setSaving(false);
  };

  const openEdit = s => {
    setEditStudent(s);
    setEditForm({ name: s.name, age: s.age||"", student_type: s.student_type||"batch", batch_id: s.batch_id||"", course_id: "", teacher_id: s.teacher_id||"", status: s.status||"active" });
  };

  const saveEdit = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch(`/students/${editStudent.id}`, { method:"PATCH", body: JSON.stringify({
      name: editForm.name, age: parseInt(editForm.age)||null,
      student_type: editForm.student_type,
      batch_id: editForm.student_type === "batch" ? (editForm.batch_id||null) : null,
      course_id: editForm.student_type === "individual" ? (editForm.course_id||null) : null,
      teacher_id: editForm.teacher_id||null, status: editForm.status||null,
    })});
    const data = await res.json();
    if (!res.ok) { setError(data.error || "Failed"); setSaving(false); return; }
    const fresh = await apiFetch("/students").then(r=>r.json());
    setStudents(fresh); setEditStudent(null); setSaving(false);
  };

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {editStudent && (
        <Modal title="Edit student" onClose={() => setEditStudent(null)}>
          <form onSubmit={saveEdit}>
            <FormField label="FULL NAME">
              <input required style={inputStyle} value={editForm.name} onChange={e=>setEditForm(f=>({...f,name:e.target.value}))}/>
            </FormField>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
              <FormField label="AGE">
                <input type="number" min="5" max="18" style={inputStyle} value={editForm.age} onChange={e=>setEditForm(f=>({...f,age:e.target.value}))}/>
              </FormField>
              <FormField label="STATUS">
                <select style={selectStyle} value={editForm.status} onChange={e=>setEditForm(f=>({...f,status:e.target.value}))}>
                  {["active","at-risk","churning","inactive"].map(s=><option key={s} value={s}>{s}</option>)}
                </select>
              </FormField>
            </div>
            <FormField label="ENROLMENT TYPE">
              <div style={{ display:"flex", gap:8 }}>
                {["batch","individual"].map(t=>(
                  <button key={t} type="button" onClick={()=>setEditForm(f=>({...f,student_type:t}))}
                    style={{ flex:1, padding:"8px 0", borderRadius:8, border:"var(--border-thin)", fontSize:12,
                      background: editForm.student_type===t ? "var(--coral)" : "var(--paper-deep)",
                      color: editForm.student_type===t ? "white" : "var(--ink-soft)", cursor:"pointer", fontWeight:600 }}>
                    {t === "batch" ? "Batch" : "Individual"}
                  </button>
                ))}
              </div>
            </FormField>
            {editForm.student_type === "batch" ? (
              <FormField label="BATCH">
                <select style={selectStyle} value={editForm.batch_id} onChange={e=>setEditForm(f=>({...f,batch_id:e.target.value}))}>
                  <option value="">— no batch —</option>
                  {BATCHES.map(b=><option key={b.id} value={b.id}>{b.name} ({b.course})</option>)}
                </select>
              </FormField>
            ) : (
              <FormField label="COURSE">
                <select style={selectStyle} value={editForm.course_id} onChange={e=>setEditForm(f=>({...f,course_id:e.target.value}))}>
                  <option value="">— select course —</option>
                  {COURSES.map(c=><option key={c.id} value={c.id}>{c.name} · {c.level}</option>)}
                </select>
              </FormField>
            )}
            <FormField label="TEACHER">
              <select style={selectStyle} value={editForm.teacher_id} onChange={e=>setEditForm(f=>({...f,teacher_id:e.target.value}))}>
                <option value="">— no teacher —</option>
                {TEACHERS.map(t=><option key={t.id} value={t.id}>{t.name}</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={()=>setEditStudent(null)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Saving…":"Save changes"}</button>
            </div>
          </form>
        </Modal>
      )}
      {showAdd && (
        <Modal title="Add student" onClose={() => setShowAdd(false)}>
          <form onSubmit={saveStudent} style={{ maxHeight:"75vh", overflowY:"auto", paddingRight:4 }}>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:10, letterSpacing:".06em" }}>STUDENT INFO</div>
            <FormField label="FULL NAME">
              <input required style={inputStyle} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Arya Patel"/>
            </FormField>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
              <FormField label="AGE">
                <input type="number" min="5" max="18" style={inputStyle} value={form.age} onChange={e=>setForm(f=>({...f,age:e.target.value}))} placeholder="e.g. 10"/>
              </FormField>
              <FormField label="ENROLMENT TYPE">
                <select style={selectStyle} value={form.student_type} onChange={e=>setForm(f=>({...f,student_type:e.target.value}))}>
                  <option value="batch">Batch student</option>
                  <option value="individual">Individual student</option>
                </select>
              </FormField>
            </div>
            {form.student_type === "batch" ? (
              <FormField label="BATCH">
                <select style={selectStyle} value={form.batch_id} onChange={e=>setForm(f=>({...f,batch_id:e.target.value}))}>
                  <option value="">— select batch —</option>
                  {BATCHES.map(b=><option key={b.id} value={b.id}>{b.name} ({b.course})</option>)}
                </select>
              </FormField>
            ) : (
              <FormField label="COURSE">
                <select style={selectStyle} value={form.course_id} onChange={e=>setForm(f=>({...f,course_id:e.target.value}))}>
                  <option value="">— select course —</option>
                  {COURSES.map(c=><option key={c.id} value={c.id}>{c.name} · {c.level}</option>)}
                </select>
              </FormField>
            )}
            <FormField label="TEACHER">
              <select style={selectStyle} value={form.teacher_id} onChange={e=>setForm(f=>({...f,teacher_id:e.target.value}))}>
                <option value="">— select teacher —</option>
                {TEACHERS.map(t=><option key={t.id} value={t.id}>{t.name}</option>)}
              </select>
            </FormField>

            <div style={{ height:1, background:"var(--rule)", margin:"14px 0" }}/>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:10, letterSpacing:".06em" }}>STUDENT LOGIN <span style={{ color:"var(--ink-mute)", fontWeight:400 }}>(optional)</span></div>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
              <FormField label="EMAIL">
                <input type="email" style={inputStyle} value={form.student_email} onChange={e=>setForm(f=>({...f,student_email:e.target.value}))} placeholder="arya@gmail.com"/>
              </FormField>
              <FormField label="PASSWORD">
                <input type="password" style={inputStyle} value={form.student_password} onChange={e=>setForm(f=>({...f,student_password:e.target.value}))} placeholder="min 6 chars"/>
              </FormField>
            </div>

            <div style={{ height:1, background:"var(--rule)", margin:"14px 0" }}/>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:10, letterSpacing:".06em" }}>PARENT LOGIN <span style={{ color:"var(--ink-mute)", fontWeight:400 }}>(optional)</span></div>
            <FormField label="PARENT NAME">
              <input style={inputStyle} value={form.parent_name} onChange={e=>setForm(f=>({...f,parent_name:e.target.value}))} placeholder="e.g. Rajesh Patel"/>
            </FormField>
            <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
              <FormField label="EMAIL">
                <input type="email" style={inputStyle} value={form.parent_email} onChange={e=>setForm(f=>({...f,parent_email:e.target.value}))} placeholder="parent@gmail.com"/>
              </FormField>
              <FormField label="PASSWORD">
                <input type="password" style={inputStyle} value={form.parent_password} onChange={e=>setForm(f=>({...f,parent_password:e.target.value}))} placeholder="min 6 chars"/>
              </FormField>
            </div>

            {error && <div style={{ color:"var(--coral)", fontSize:13, margin:"8px 0" }}>{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?"Saving…":"Add student"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/students" 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 }}>Student CRM</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} enrolled · {list.filter(s=>s.status==="at-risk"||s.status==="churning").length} need attention</div>
          </div>
          <div style={{ flex:1 }}/>
          <div className="card-flat" style={{ display:"flex", alignItems:"center", gap:8, padding:"6px 10px", background:"var(--paper-deep)", width:220 }}>
            {I.search({ size:14 })}
            <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="Search students…" style={{ border:"none", outline:"none", background:"transparent", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", width:"100%" }}/>
          </div>
          <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add student</button>
        </div>
        <div style={{ flex:1, display:"flex", overflow:"hidden" }}>
          <div style={{ flex:1, overflow:"auto", padding:22 }}>
            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                  {["Student","Course · Batch","Teacher","Attend.","XP","Status","Kit",""].map(h => (
                    <th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {filtered.map((s, i) => (
                  <tr key={s.id} onClick={() => setSelected(selected === s.id ? null : s.id)} style={{ borderTop: i ? "var(--border-thin)" : "none", cursor:"pointer", background: selected === s.id ? "var(--paper-deep)" : "transparent" }}>
                    <td style={{ padding:"12px 10px" }}>
                      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                        <Avatar name={s.name[0]} color={s.color} size={30}/>
                        <div>
                          <div style={{ fontWeight:700 }}>{s.name}</div>
                          <div style={{ fontSize:11, color:"var(--ink-mute)" }}>Age {s.age}</div>
                        </div>
                      </div>
                    </td>
                    <td style={{ padding:"12px 10px" }}><div style={{ fontWeight:600 }}>{s.course}</div><div style={{ fontSize:11, color:"var(--ink-mute)" }}>{s.batch}</div></td>
                    <td style={{ padding:"12px 10px", color:"var(--ink-soft)" }}>{s.teacher}</td>
                    <td style={{ padding:"12px 10px", fontWeight:700, color: parseInt(s.attend) < 75 ? "var(--coral)" : parseInt(s.attend) >= 90 ? "var(--moss)" : "var(--ink)" }}>{s.attend}</td>
                    <td style={{ padding:"12px 10px", fontFamily:"var(--font-mono)", fontSize:12 }}>{s.xp}</td>
                    <td style={{ padding:"12px 10px" }}>
                      <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: s.status==="active" ? "var(--moss)" : s.status==="at-risk" ? "var(--gold)" : "var(--coral)", color:"white" }}>
                        {s.status}
                      </span>
                    </td>
                    <td style={{ padding:"12px 10px" }}>
                      <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: s.kit==="delivered" ? "var(--paper-deep)" : s.kit==="transit" ? "var(--sky)" : "var(--gold)", color: s.kit==="transit" ? "white" : "var(--ink)" }}>
                        {s.kit}
                      </span>
                    </td>
                    <td style={{ padding:"12px 10px", display:"flex", gap:6 }}>
                      <button onClick={e=>{e.stopPropagation();openEdit(s);}} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11 }}>Edit</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          {student && (
            <div style={{ width:280, borderLeft:"var(--border-thin)", background:"var(--paper-card)", padding:20, overflow:"auto", flexShrink:0 }}>
              <div style={{ display:"flex", alignItems:"center", gap:10, marginBottom:16 }}>
                <Avatar name={student.name[0]} color={student.color} size={48}/>
                <div>
                  <div className="display" style={{ fontSize:18 }}>{student.name}</div>
                  <div style={{ fontSize:12, color:"var(--ink-mute)" }}>Age {student.age} · {student.batch}</div>
                </div>
              </div>
              {[["Course", student.course],["Teacher", student.teacher],["Attendance", student.attend],["XP", student.xp],["Status", student.status],["Kit", student.kit]].map(([k,v]) => (
                <div key={k} style={{ display:"flex", justifyContent:"space-between", padding:"8px 0", borderTop:"var(--border-thin)", fontSize:13 }}>
                  <span style={{ color:"var(--ink-mute)", fontWeight:600 }}>{k}</span>
                  <span style={{ fontWeight:700 }}>{v}</span>
                </div>
              ))}
              <div style={{ marginTop:16, display:"flex", flexDirection:"column", gap:8 }}>
                <button className="btn btn-primary" style={{ fontSize:12, padding:"8px 0", width:"100%" }}>{I.send({ size:14 })} Message parent</button>
                <button className="btn btn-ghost" style={{ fontSize:12, padding:"8px 0", width:"100%" }}>{I.chart({ size:14 })} View progress</button>
                <button className="btn btn-ghost" style={{ fontSize:12, padding:"8px 0", width:"100%" }}>{I.wallet({ size:14 })} Billing history</button>
              </div>
            </div>
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Teachers ───────────────────────────────────────────────────────────
const AdminTeachers = ({ dark = true, go }) => {
  const { data: initTeachers } = useApi("/teachers");
  const [teachers, setTeachers]   = React.useState(null);
  const [showAdd, setShowAdd]     = React.useState(false);
  const [editTeacher, setEditTeacher] = React.useState(null);
  const [form, setForm]           = React.useState({ name:"", email:"", password:"" });
  const [editForm, setEditForm]   = React.useState({ name:"", email:"", password:"" });
  const [saving, setSaving]       = React.useState(false);
  const [error, setError]         = React.useState("");
  const list = teachers ?? initTeachers;

  const refresh = () => apiFetch("/teachers").then(r=>r.json()).then(setTeachers);

  const save = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/teachers", { 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:"", email:"", password:"" }); setShowAdd(false); setSaving(false);
  };

  const openEdit = t => { setEditTeacher(t); setEditForm({ name:t.name, email:t.email, password:"" }); setError(""); };

  const saveEdit = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch(`/teachers/${editTeacher.id}`, { method:"PATCH", body: JSON.stringify({ name: editForm.name, email: editForm.email }) });
    if (!res.ok) { const d=await res.json(); setError(d.error||"Failed"); setSaving(false); return; }
    if (editForm.password) {
      await apiFetch(`/admin/users/${editTeacher.id}/password-by-email`, { method:"PATCH", body: JSON.stringify({ email: editForm.email, password: editForm.password }) });
    }
    await refresh(); setEditTeacher(null); setSaving(false);
  };

  const del = async id => {
    if (!confirm("Remove this teacher?")) return;
    await apiFetch(`/teachers/${id}`, { method:"DELETE" });
    await refresh();
  };

  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showAdd && (
        <Modal title="Add teacher" onClose={()=>setShowAdd(false)}>
          <form onSubmit={save}>
            <FormField label="FULL NAME">
              <input required style={inputStyle} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Ms. Priya Sharma"/>
            </FormField>
            <FormField label="EMAIL (used to log in)">
              <input required type="email" style={inputStyle} value={form.email} onChange={e=>setForm(f=>({...f,email:e.target.value}))} placeholder="priya@epiqminds.com"/>
            </FormField>
            <FormField label="PASSWORD">
              <input required type="password" style={inputStyle} value={form.password} onChange={e=>setForm(f=>({...f,password:e.target.value}))} placeholder="min 6 characters"/>
            </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…":"Add teacher"}</button>
            </div>
          </form>
        </Modal>
      )}
      {editTeacher && (
        <Modal title="Edit teacher" onClose={()=>setEditTeacher(null)}>
          <form onSubmit={saveEdit}>
            <FormField label="FULL NAME">
              <input required style={inputStyle} value={editForm.name} onChange={e=>setEditForm(f=>({...f,name:e.target.value}))}/>
            </FormField>
            <FormField label="EMAIL">
              <input required type="email" style={inputStyle} value={editForm.email} onChange={e=>setEditForm(f=>({...f,email:e.target.value}))}/>
            </FormField>
            <FormField label="NEW PASSWORD (leave blank to keep current)">
              <input type="password" style={inputStyle} value={editForm.password} onChange={e=>setEditForm(f=>({...f,password:e.target.value}))} placeholder="leave blank to keep unchanged"/>
            </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={()=>setEditTeacher(null)} className="btn btn-ghost">Cancel</button>
              <button type="submit" disabled={saving} className="btn btn-primary">{saving?"Saving…":"Save changes"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/teachers" 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 }}>Teachers</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} teachers</div>
          </div>
          <div style={{ flex:1 }}/>
          <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add teacher</button>
        </div>
        <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 teachers yet</div>
              <div style={{ fontSize:13, marginTop:4 }}>Add your first teacher to get started</div>
            </div>
          ) : (
            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                  {["Name","Email",""].map(h=><th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>)}
                </tr>
              </thead>
              <tbody>
                {list.map((t,i) => (
                  <tr key={t.id} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                    <td style={{ padding:"14px 10px", fontWeight:700 }}>{t.name}</td>
                    <td style={{ padding:"14px 10px", color:"var(--ink-soft)" }}>{t.email}</td>
                    <td style={{ padding:"14px 10px" }}>
                      <div style={{ display:"flex", gap:6 }}>
                        <button onClick={()=>openEdit(t)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11 }}>Edit</button>
                        <button onClick={()=>del(t.id)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, color:"var(--coral)" }}>Remove</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Batches ────────────────────────────────────────────────────────────
const AdminBatches = ({ dark = true, go }) => {
  const { data: initBatches }  = useApi("/batches");
  const { data: coursesList }  = useApi("/courses/list");
  const [batches, setBatches]  = React.useState(null);
  const [showAdd, setShowAdd]  = React.useState(false);
  const [form, setForm]        = React.useState({ name:"", course_id:"" });
  const [saving, setSaving]    = React.useState(false);
  const [error, setError]      = React.useState("");
  const list = batches ?? initBatches;

  const refresh = () => apiFetch("/batches").then(r=>r.json()).then(setBatches);

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

  const del = async id => {
    if (!confirm("Remove this batch? Students in it will become unassigned.")) return;
    await apiFetch(`/batches/${id}`, { method:"DELETE" });
    await refresh();
  };

  return (
    <Themed className={dark?"theme-dark":""} style={{ width:"100%", height:"100%", display:"flex" }}>
      {showAdd && (
        <Modal title="Add batch" onClose={()=>setShowAdd(false)}>
          <form onSubmit={save}>
            <FormField label="BATCH NAME">
              <input required style={inputStyle} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="e.g. Batch A"/>
            </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>
                {coursesList.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: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…":"Add batch"}</button>
            </div>
          </form>
        </Modal>
      )}
      <AdminSidebar active="/app/admin/batches" 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 }}>Batches</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} batches</div>
          </div>
          <div style={{ flex:1 }}/>
          <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add batch</button>
        </div>
        <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 batches yet</div>
              <div style={{ fontSize:13, marginTop:4 }}>Create a batch to start enrolling students</div>
            </div>
          ) : (
            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                  {["Batch","Course","Students",""].map(h=><th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>)}
                </tr>
              </thead>
              <tbody>
                {list.map((b,i) => (
                  <tr key={b.id} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                    <td style={{ padding:"14px 10px", fontWeight:700 }}>{b.name}</td>
                    <td style={{ padding:"14px 10px", color:"var(--ink-soft)" }}>{b.course}</td>
                    <td style={{ padding:"14px 10px" }}>{b.students}</td>
                    <td style={{ padding:"14px 10px" }}>
                      <button onClick={()=>del(b.id)} className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, color:"var(--coral)" }}>Remove</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Broadcast / Notifications ─────────────────────────────────────────
const AdminBroadcast = ({ dark = true, go }) => {
  const [msg, setMsg] = React.useState("");
  const [channels, setChannels] = React.useState({ whatsapp:true, email:true, sms:false });
  const [target, setTarget] = React.useState("all");
  const [sent, setSent] = React.useState(false);
  const toggle = k => setChannels(c => ({ ...c, [k]: !c[k] }));
  const { data: history } = useApi("/broadcast/history");
  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/broadcast" 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 }}>Broadcast</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>WhatsApp · Email · SMS — reach all families instantly</div>
          </div>
        </div>
        <div style={{ flex:1, display:"grid", gridTemplateColumns:"1.2fr 1fr", gap:22, padding:22, overflow:"auto" }}>
          <div style={{ display:"flex", flexDirection:"column", gap:16 }}>
            <div className="card-flat" style={{ padding:20 }}>
              <SectionHead eyebrow="COMPOSE" title="New broadcast"/>
              <textarea value={msg} onChange={e=>setMsg(e.target.value)} placeholder="Type your message here…" style={{ width:"100%", minHeight:120, padding:"12px 14px", border:"var(--border-thin)", borderRadius:10, background:"var(--paper-deep)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", resize:"vertical", outline:"none", boxSizing:"border-box" }}/>
              <div style={{ marginTop:14 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:8 }}>CHANNELS</div>
                <div style={{ display:"flex", gap:10 }}>
                  {[["whatsapp","WhatsApp","var(--moss)"],["email","Email","var(--sky)"],["sms","SMS","var(--gold)"]].map(([k,label,c]) => (
                    <button key={k} onClick={() => toggle(k)} style={{ display:"flex", alignItems:"center", gap:6, padding:"6px 14px", borderRadius:999, border:"var(--border-thin)", background: channels[k] ? c : "var(--paper-deep)", color: channels[k] ? "white" : "var(--ink-soft)", fontSize:12, fontWeight:700, cursor:"pointer" }}>
                      {channels[k] ? I.check({ size:12 }) : null} {label}
                    </button>
                  ))}
                </div>
              </div>
              <div style={{ marginTop:14 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginBottom:8 }}>AUDIENCE</div>
                <div style={{ display:"flex", gap:8 }}>
                  {[["all","All families (48)"],["batch","By batch"],["course","By course"]].map(([v,l]) => (
                    <button key={v} onClick={() => setTarget(v)} style={{ padding:"6px 12px", borderRadius:999, border:"var(--border-thin)", background: target===v ? "var(--ink)" : "var(--paper-deep)", color: target===v ? "var(--paper)" : "var(--ink-soft)", fontSize:12, fontWeight:700, cursor:"pointer" }}>{l}</button>
                  ))}
                </div>
                {target === "batch" && (
                  <select style={{ marginTop:8, padding:"6px 12px", borderRadius:8, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:12, color:"var(--ink)", fontFamily:"var(--font-ui)" }}>
                    {["Batch A · Scratch","Batch B · Python","Batch C · Python","Batch D · Web","Batch E · AI"].map(b => <option key={b}>{b}</option>)}
                  </select>
                )}
              </div>
              <div style={{ marginTop:18 }}>
                {sent ? (
                  <div style={{ display:"flex", alignItems:"center", gap:8, color:"var(--moss)", fontWeight:700 }}>{I.check({ size:18 })} Broadcast sent to {target==="all"?48:12} families!</div>
                ) : (
                  <button className="btn btn-primary" onClick={() => { if(msg.trim()) setSent(true); }} style={{ padding:"10px 22px", fontSize:14 }}>{I.send({ size:16 })} Send broadcast</button>
                )}
              </div>
            </div>
            <div className="card-flat" style={{ padding:16 }}>
              <SectionHead eyebrow="INTEGRATIONS" title="Connected channels"/>
              {[
                { name:"WhatsApp Business", handle:"@epiqminds.com", status:"connected", color:"var(--moss)", note:"via Twilio" },
                { name:"Email (SendGrid)", handle:"noreply@epiqminds.com", status:"connected", color:"var(--sky)", note:"1,200 sends/mo" },
                { name:"SMS", handle:"+91 98765 00000", status:"not set up", color:"var(--ink-mute)", note:"Click to configure" },
              ].map((ch, i) => (
                <div key={i} style={{ display:"flex", alignItems:"center", gap:12, padding:"10px 0", borderTop: i ? "var(--border-thin)" : "none" }}>
                  <div style={{ width:8, height:32, borderRadius:4, background: ch.status==="connected" ? "var(--moss)" : "var(--rule)", flexShrink:0 }}/>
                  <div style={{ flex:1 }}>
                    <div style={{ fontWeight:700, fontSize:13 }}>{ch.name}</div>
                    <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{ch.handle} · {ch.note}</div>
                  </div>
                  <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: ch.status==="connected" ? "var(--moss)" : "var(--paper-deep)", color: ch.status==="connected" ? "white" : "var(--ink-mute)" }}>{ch.status}</span>
                </div>
              ))}
            </div>
          </div>
          <div className="card-flat" style={{ padding:18, overflow:"auto" }}>
            <SectionHead eyebrow="HISTORY" title="Recent broadcasts"/>
            {history.map((h, i) => (
              <div key={i} style={{ padding:"12px 0", borderTop: i ? "var(--border-thin)" : "none" }}>
                <div style={{ fontSize:13, fontWeight:600, lineHeight:1.4, marginBottom:6 }}>{h.text}</div>
                <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                  <span className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{h.time}</span>
                  <span style={{ fontSize:11, color:"var(--ink-mute)" }}>· {h.reach} families</span>
                  <div style={{ flex:1 }}/>
                  {h.channels.map(c => <span key={c} className="chip flat" style={{ fontSize:10, padding:"1px 6px" }}>{c}</span>)}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Class Schedule + Google Meet ───────────────────────────────────────
const DAYS = ["Mon","Tue","Wed","Thu","Fri","Sat"];

const fmt12 = t => {
  if (!t) return "";
  const [h,m] = t.split(":").map(Number);
  return `${h%12||12}:${m.toString().padStart(2,"0")} ${h>=12?"PM":"AM"}`;
};

const AdminSchedule = ({ dark = true, go }) => {
  const { data: initSessions, loading } = useApi("/schedule");
  const { data: BATCHES }  = useApi("/batches");
  const { data: TEACHERS } = useApi("/teachers");
  const { data: STUDENTS } = useApi("/students");
  const [view, setView]       = React.useState("week");
  const [showAdd, setShowAdd] = React.useState(false);
  const [sessions, setSessions] = React.useState(null);
  const [sessType, setSessType] = React.useState("batch");
  const [form, setForm] = React.useState({ batch_id:"", student_id:"", teacher_id:"", day:"", time_start:"", time_end:"", meet_link:"" });
  const [saving, setSaving] = React.useState(false);
  const [statusChanging, setStatusChanging] = React.useState(null);
  const list = sessions ?? initSessions;

  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);
  };

  const saveSession = async e => {
    e.preventDefault(); setSaving(true);
    const body = {
      day: form.day,
      time_start: fmt12(form.time_start),
      time_end:   fmt12(form.time_end),
      meet_link:  form.meet_link || null,
      teacher_id: parseInt(form.teacher_id) || null,
      batch_id:   sessType === "batch"      ? (parseInt(form.batch_id)||null)   : null,
      student_id: sessType === "individual" ? (parseInt(form.student_id)||null) : null,
    };
    await apiFetch("/schedule", { method:"POST", body: JSON.stringify(body) });
    const fresh = await apiFetch("/schedule").then(r=>r.json());
    setSessions(fresh);
    setForm({ batch_id:"", student_id:"", teacher_id:"", day:"", time_start:"", time_end:"", meet_link:"" });
    setShowAdd(false); setSaving(false);
  };

  const statusColor = s => s==="live" ? "var(--coral)" : s==="done" ? "var(--ink-mute)" : "var(--moss)";
  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/schedule" 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 }}>Class Schedule</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.length} sessions</div>
          </div>
          <div style={{ flex:1 }}/>
          <Tabs items={["Week","Day","Month"]} active={view==="week"?"Week":view==="day"?"Day":"Month"} onChange={v => setView(v.toLowerCase())}/>
          <button className="btn btn-primary" onClick={() => setShowAdd(true)} style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add session</button>
        </div>
        <div style={{ flex:1, overflow:"auto", padding:22 }}>
          {loading ? <Spinner/> : (() => {
            const sorted = [...list].sort((a,b) => a.day < b.day ? -1 : a.day > b.day ? 1 : 0);
            const groups = [];
            sorted.forEach(s => {
              const last = groups[groups.length-1];
              if (last && last.day === s.day) last.sessions.push(s);
              else groups.push({ day: s.day, sessions: [s] });
            });
            const fmtDate = d => { try { const dt = new Date(d + "T00:00:00"); return dt.toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short"}).toUpperCase(); } catch { return d; } };
            return groups.map(g => (
              <div key={g.day} style={{ marginBottom:18 }}>
                <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)", fontWeight:700, marginBottom:8, letterSpacing:".06em" }}>{fmtDate(g.day)}</div>
                <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
                  {g.sessions.map(s => (
                    <div key={s.id} className="card-flat" style={{ padding:14, display:"grid", gridTemplateColumns:"110px 1fr 1fr auto auto auto auto", alignItems:"center", gap:14, borderLeft:`3px solid ${statusColor(s.status)}` }}>
                      <div>
                        <div style={{ fontWeight:700, fontSize:13 }}>{s.time}</div>
                        <div style={{ fontSize:11, color:"var(--ink-mute)" }}>–{s.end}</div>
                      </div>
                      <div>
                        <div style={{ fontWeight:700, fontSize:13 }}>{s.batch}</div>
                        <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{s.course}</div>
                      </div>
                      <div style={{ fontSize:12, color:"var(--ink-soft)" }}>
                        <div>{s.teacher}</div>
                        <div style={{ color:"var(--ink-mute)" }}>{s.session_type==="individual"?"1-on-1":s.students+" students"}</div>
                      </div>
                      <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: s.session_type==="individual"?"var(--plum)":"var(--sky)", color:"white" }}>{s.session_type==="individual"?"1-on-1":"batch"}</span>
                      <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: statusColor(s.status), color:"white" }}>{s.status}</span>
                      {s.meet ? (
                        <a href={s.meet} target="_blank" rel="noreferrer" className="btn btn-ghost" style={{ padding:"4px 10px", fontSize:11, textDecoration:"none", display:"flex", alignItems:"center", gap:4 }}>
                          <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
                          Meet
                        </a>
                      ) : <span style={{ fontSize:11, color:"var(--ink-mute)", padding:"4px 10px" }}>No link</span>}
                      {/* Status control */}
                      <div style={{ display:"flex", gap:4 }}>
                        {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>
                        )}
                        {s.status === "done" && (
                          <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>
            ));
          })()}
          {!loading && 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 sessions yet</div>
              <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ marginTop:16 }}>{I.plus({size:14})} Add first session</button>
            </div>
          )}
        </div>
        {showAdd && (
          <Modal title="Add session" onClose={()=>setShowAdd(false)}>
            <form onSubmit={saveSession}>
              <div style={{ display:"flex", gap:8, marginBottom:16 }}>
                {[["batch","Batch class"],["individual","1-on-1 student"]].map(([t,l])=>(
                  <button key={t} type="button" onClick={()=>setSessType(t)} style={{ flex:1, padding:"8px 0", borderRadius:8, border:"var(--border-thin)", fontSize:12,
                    background: sessType===t?"var(--coral)":"var(--paper-deep)", color: sessType===t?"white":"var(--ink-soft)", cursor:"pointer", fontWeight:600 }}>{l}</button>
                ))}
              </div>
              {sessType === "batch" ? (
                <FormField label="BATCH">
                  <select required style={selectStyle} value={form.batch_id} onChange={e=>setForm(f=>({...f,batch_id:e.target.value}))}>
                    <option value="">— select batch —</option>
                    {BATCHES.map(b=><option key={b.id} value={b.id}>{b.name} ({b.course})</option>)}
                  </select>
                </FormField>
              ) : (
                <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} · {s.course||s.batch}</option>)}
                  </select>
                </FormField>
              )}
              <FormField label="TEACHER">
                <select style={selectStyle} value={form.teacher_id} onChange={e=>setForm(f=>({...f,teacher_id:e.target.value}))}>
                  <option value="">— no teacher —</option>
                  {TEACHERS.map(t=><option key={t.id} value={t.id}>{t.name}</option>)}
                </select>
              </FormField>
              <FormField label="DATE">
                <input type="date" required style={inputStyle} value={form.day} onChange={e=>setForm(f=>({...f,day:e.target.value}))}/>
              </FormField>
              <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
                <FormField label="START TIME">
                  <input type="time" required style={inputStyle} value={form.time_start} onChange={e=>setForm(f=>({...f,time_start:e.target.value}))}/>
                </FormField>
                <FormField label="END TIME">
                  <input type="time" required style={inputStyle} value={form.time_end} onChange={e=>setForm(f=>({...f,time_end:e.target.value}))}/>
                </FormField>
              </div>
              <FormField label="GOOGLE MEET LINK">
                <input style={inputStyle} value={form.meet_link} onChange={e=>setForm(f=>({...f,meet_link:e.target.value}))} placeholder="https://meet.google.com/xxx-xxxx-xxx"/>
              </FormField>
              <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?"Saving…":"Save session"}</button>
              </div>
            </form>
          </Modal>
        )}
      </div>
    </Themed>
  );
};

// ── Admin: Attendance / Session Reports ───────────────────────────────────────
const AdminAttendance = ({ dark = true, go }) => {
  const { data: ATTENDANCE_DATA, loading } = useApi("/attendance");
  const [expand, setExpand] = React.useState(null);
  const avg = ATTENDANCE_DATA.length
    ? Math.round(ATTENDANCE_DATA.reduce((a,r) => a + parseInt(r.rate), 0) / ATTENDANCE_DATA.length)
    : 0;
  const perfect = ATTENDANCE_DATA.filter(r => parseInt(r.rate) === 100).length;
  const needFollowUp = ATTENDANCE_DATA.filter(r => parseInt(r.rate) < 75).length;
  if (loading) return <Spinner />;
  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/attendance" 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 }}>Session Reports</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{ATTENDANCE_DATA.length} sessions recorded</div>
          </div>
          <div style={{ flex:1 }}/>
          <button className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>{I.upload({ size:14 })} Export CSV</button>
        </div>
        <div style={{ padding:22, overflow:"auto", flex:1 }}>
          <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:14, marginBottom:22 }}>
            {[
              { label:"AVG ATTENDANCE", value: ATTENDANCE_DATA.length ? `${avg}%` : "—", color: avg >= 90 ? "var(--moss)" : avg >= 75 ? "var(--gold)" : "var(--coral)" },
              { label:"TOTAL SESSIONS",  value: ATTENDANCE_DATA.length, color:"var(--sky)" },
              { label:"PERFECT SESSIONS", value: perfect, color:"var(--moss)" },
              { label:"FOLLOW-UPS NEEDED", value: needFollowUp, color: needFollowUp > 0 ? "var(--coral)" : "var(--moss)" },
            ].map(k => (
              <div key={k.label} className="card-flat" style={{ padding:14 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>{k.label}</div>
                <div className="display" style={{ fontSize:28, marginTop:4, color:k.color }}>{k.value}</div>
              </div>
            ))}
          </div>
          {ATTENDANCE_DATA.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 attendance records yet</div>
              <div style={{ fontSize:13, marginTop:4 }}>Attendance is recorded when teachers mark sessions</div>
            </div>
          ) : (
            <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
              <thead>
                <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                  {["Date","Batch · Course","Teacher","Present","Rate","Notes"].map(h => (
                    <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {ATTENDANCE_DATA.map((r,i) => (
                  <tr key={i} style={{ borderTop: i ? "var(--border-thin)" : "none" }}>
                    <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:12 }}>{r.date}</span></td>
                    <td style={{ padding:"12px", fontWeight:700 }}>{r.batch}</td>
                    <td style={{ padding:"12px", color:"var(--ink-soft)" }}>{r.teacher}</td>
                    <td style={{ padding:"12px" }}>{r.present}/{r.total}</td>
                    <td style={{ padding:"12px", fontWeight:700, color: parseInt(r.rate)<75?"var(--coral)":parseInt(r.rate)===100?"var(--moss)":"var(--ink)" }}>{r.rate}</td>
                    <td style={{ padding:"12px", fontSize:12, color:"var(--ink-mute)" }}>{r.notes || "—"}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Accounts & Invoice ─────────────────────────────────────────────────
const AdminBilling = ({ dark = true, go }) => {
  const { data: INVOICES, loading } = useApi("/invoices");
  const total = "₹6.14L";
  const overdue = INVOICES.filter(i=>i.status==="overdue");
  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/billing" 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 }}>Accounts & Invoices</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{INVOICES.length} invoices · {overdue.length} overdue</div>
          </div>
          <div style={{ flex:1 }}/>
          <button onClick={() => go && go("/app/admin/payments")} className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>{I.coin({ size:14 })} Payment gateway</button>
          <button className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} New invoice</button>
        </div>
        <div style={{ flex:1, overflow:"auto", padding:22 }}>
          <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:14, marginBottom:22 }}>
            {[
              { label:"MRR", value:"₹61,400", delta:"+8.1%" },
              { label:"COLLECTED NOV", value:"₹38,200", delta:"+3 invoices" },
              { label:"PENDING", value:"₹3,600", delta:"2 invoices" },
              { label:"OVERDUE", value:"₹3,600", delta:`${overdue.length} invoices` },
            ].map(k => (
              <div key={k.label} className="card-flat" style={{ padding:14 }}>
                <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>{k.label}</div>
                <div className="display" style={{ fontSize:26, marginTop:4 }}>{k.value}</div>
                <div style={{ fontSize:11, color:"var(--ink-mute)", marginTop:2 }}>{k.delta}</div>
              </div>
            ))}
          </div>
          {overdue.length > 0 && (
            <div className="card-flat" style={{ padding:14, marginBottom:16, borderLeft:"3px solid var(--coral)" }}>
              <div style={{ display:"flex", alignItems:"center", gap:8, marginBottom:8 }}>
                {I.bell({ size:14 })}
                <span style={{ fontWeight:700, fontSize:13 }}>Overdue invoices — send reminders</span>
              </div>
              <div style={{ display:"flex", gap:8 }}>
                {overdue.map(inv => (
                  <span key={inv.id} className="chip flat" style={{ fontSize:11 }}>{inv.student} · {inv.amount}</span>
                ))}
                <button className="btn btn-primary" style={{ padding:"4px 12px", fontSize:11, marginLeft:"auto" }}>{I.send({ size:12 })} Send reminders</button>
              </div>
            </div>
          )}
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                {["Invoice","Student","Plan","Amount","Issued","Due","Status",""].map(h => (
                  <th key={h} style={{ padding:"8px 12px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {INVOICES.map((inv,i) => (
                <tr key={inv.id} style={{ borderTop: i ? "var(--border-thin)" : "none" }}>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:12 }}>{inv.id}</span></td>
                  <td style={{ padding:"12px", fontWeight:700 }}>{inv.student}</td>
                  <td style={{ padding:"12px", color:"var(--ink-soft)" }}>{inv.plan}</td>
                  <td style={{ padding:"12px", fontWeight:700 }}>{inv.amount}</td>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{inv.date}</span></td>
                  <td style={{ padding:"12px" }}><span className="mono" style={{ fontSize:11, color: inv.status==="overdue"?"var(--coral)":"var(--ink-mute)" }}>{inv.due}</span></td>
                  <td style={{ padding:"12px" }}>
                    <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: inv.status==="paid"?"var(--moss)":inv.status==="overdue"?"var(--coral)":"var(--gold)", color:"white" }}>
                      {inv.status}
                    </span>
                  </td>
                  <td style={{ padding:"12px", display:"flex", gap:6 }}>
                    <button className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11 }}>View</button>
                    {inv.status !== "paid" && <button className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11, color:"var(--moss)" }}>Mark paid</button>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </Themed>
  );
};

// ── Admin: Payment Gateway ────────────────────────────────────────────────────
const AdminPayments = ({ dark = true, go }) => {
  const { data: TRANSACTIONS } = useApi("/transactions");
  return (
  <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
    <AdminSidebar active="/app/admin/payments" 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 }}>Payment Gateway</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>Razorpay integration · live mode</div>
        </div>
        <div style={{ flex:1 }}/>
        <div style={{ display:"flex", alignItems:"center", gap:6, padding:"4px 12px", background:"var(--moss)", borderRadius:999 }}>
          <div style={{ width:6, height:6, borderRadius:"50%", background:"white" }}/>
          <span style={{ color:"white", fontSize:11, fontWeight:700 }}>Razorpay live</span>
        </div>
        <button className="btn btn-ghost" onClick={() => go && go("/app/admin/billing")} style={{ padding:"6px 12px", fontSize:12 }}>View invoices</button>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22 }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(4,1fr)", gap:14, marginBottom:22 }}>
          {[
            { label:"COLLECTED TODAY", value:"₹20,800", color:"var(--moss)" },
            { label:"SUCCESS RATE", value:"95.2%", color:"var(--moss)" },
            { label:"PENDING", value:"₹4,800", color:"var(--gold)" },
            { label:"FAILED (RETRY)", value:"₹1,800", color:"var(--coral)" },
          ].map(k => (
            <div key={k.label} className="card-flat" style={{ padding:14 }}>
              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>{k.label}</div>
              <div className="display" style={{ fontSize:26, marginTop:4, color:k.color }}>{k.value}</div>
            </div>
          ))}
        </div>
        <div className="card-flat" style={{ padding:18, marginBottom:18 }}>
          <SectionHead eyebrow="PAYMENT METHODS" title="Acceptance breakdown"/>
          <div style={{ display:"flex", gap:14 }}>
            {[["UPI","52%","var(--coral)"],["Card","28%","var(--sky)"],["Net Banking","20%","var(--moss)"]].map(([m,p,c]) => (
              <div key={m} style={{ flex:1, padding:12, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)" }}>
                <div style={{ fontWeight:700, fontSize:14 }}>{m}</div>
                <div className="display" style={{ fontSize:28, color:c, marginTop:4 }}>{p}</div>
                <div className="progress" style={{ marginTop:8, height:6 }}><i style={{ width:p, background:c }}/></div>
              </div>
            ))}
          </div>
        </div>
        <div className="card-flat" style={{ padding:18 }}>
          <SectionHead eyebrow="TRANSACTIONS" title="Recent payments"/>
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                {["Txn ID","Student","Amount","Method","Time","Status",""].map(h => (
                  <th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {TRANSACTIONS.map((t,i) => (
                <tr key={t.id} style={{ borderTop: i ? "var(--border-thin)":"none" }}>
                  <td style={{ padding:"10px" }}><span className="mono" style={{ fontSize:11 }}>{t.id}</span></td>
                  <td style={{ padding:"10px", fontWeight:700 }}>{t.student}</td>
                  <td style={{ padding:"10px", fontWeight:700 }}>{t.amount}</td>
                  <td style={{ padding:"10px", color:"var(--ink-soft)" }}>{t.method}</td>
                  <td style={{ padding:"10px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{t.time}</span></td>
                  <td style={{ padding:"10px" }}>
                    <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: t.status==="success"?"var(--moss)":t.status==="pending"?"var(--gold)":"var(--coral)", color:"white" }}>
                      {t.status}
                    </span>
                  </td>
                  <td style={{ padding:"10px" }}>
                    {t.status === "failed" && <button className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11, color:"var(--coral)" }}>Retry</button>}
                    {t.status !== "failed" && <button className="btn btn-ghost" style={{ padding:"2px 8px", fontSize:11 }}>Receipt</button>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </Themed>
  );
};

// ── Admin: Kit Delivery Tracking ──────────────────────────────────────────────
const AdminKits = ({ dark = true, go }) => {
  const { data: initKits } = useApi("/kits");
  const { data: STUDENTS }  = useApi("/students");
  const [kits, setKits]     = React.useState(null);
  const [showAdd, setShowAdd] = React.useState(false);
  const [form, setForm]       = React.useState({ student_id:"", contents:"", tracking:"" });
  const [saving, setSaving]   = React.useState(false);
  const [error, setError]     = React.useState("");
  const list = kits ?? initKits;

  const refresh = () => apiFetch("/kits").then(r=>r.json()).then(setKits);

  const dispatch = async e => {
    e.preventDefault(); setError(""); setSaving(true);
    const res = await apiFetch("/kits", { 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:"", contents:"", tracking:"" }); setShowAdd(false); setSaving(false);
  };

  const updateStatus = async (id, status) => {
    await apiFetch(`/kits/${id}`, { method:"PATCH", body: JSON.stringify({ status }) });
    await refresh();
  };

  return (
  <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
    {showAdd && (
      <Modal title="Log kit dispatch" onClose={()=>setShowAdd(false)}>
        <form onSubmit={dispatch}>
          <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="KIT CONTENTS">
            <input style={inputStyle} value={form.contents} onChange={e=>setForm(f=>({...f,contents:e.target.value}))} placeholder="e.g. Arduino, USB cable, booklet"/>
          </FormField>
          <FormField label="TRACKING NUMBER (optional)">
            <input style={inputStyle} value={form.tracking} onChange={e=>setForm(f=>({...f,tracking:e.target.value}))} placeholder="e.g. DTDC1234567"/>
          </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…":"Log dispatch"}</button>
          </div>
        </form>
      </Modal>
    )}
    <AdminSidebar active="/app/admin/kits" 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 }}>Kit Delivery Tracking</div>
          <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.filter(k=>k.status==="transit").length} in transit · {list.filter(k=>k.status==="pending").length} pending</div>
        </div>
        <div style={{ flex:1 }}/>
        <button onClick={()=>setShowAdd(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Log dispatch</button>
      </div>
      <div style={{ flex:1, overflow:"auto", padding:22 }}>
        <div style={{ display:"grid", gridTemplateColumns:"repeat(3,1fr)", gap:14, marginBottom:22 }}>
          {[
            { label:"DELIVERED",  value:list.filter(k=>k.status==="delivered").length, color:"var(--moss)" },
            { label:"IN TRANSIT", value:list.filter(k=>k.status==="transit").length,   color:"var(--sky)" },
            { label:"PENDING",    value:list.filter(k=>k.status==="pending").length,    color:"var(--gold)" },
          ].map(k => (
            <div key={k.label} className="card-flat" style={{ padding:14 }}>
              <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em" }}>{k.label}</div>
              <div className="display" style={{ fontSize:32, marginTop:4, color:k.color }}>{k.value}</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 kits logged yet</div>
            <div style={{ fontSize:13, marginTop:4, marginBottom:20 }}>Log your first dispatch to start tracking</div>
            <button onClick={()=>setShowAdd(true)} className="btn btn-primary">{I.plus({ size:14 })} Log dispatch</button>
          </div>
        ) : (
          <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
            <thead>
              <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                {["Kit ID","Student","Course","Contents","Ordered","Status","Tracking",""].map(h => (
                  <th key={h} style={{ padding:"8px 10px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {list.map((k,i) => (
                <tr key={k.id} style={{ borderTop: i?"var(--border-thin)":"none" }}>
                  <td style={{ padding:"12px 10px" }}><span className="mono" style={{ fontSize:11 }}>{k.id}</span></td>
                  <td style={{ padding:"12px 10px", fontWeight:700 }}>{k.student}</td>
                  <td style={{ padding:"12px 10px", color:"var(--ink-soft)", fontSize:12 }}>{k.course}</td>
                  <td style={{ padding:"12px 10px", fontSize:11, color:"var(--ink-mute)", maxWidth:160 }}>{k.contents||"—"}</td>
                  <td style={{ padding:"12px 10px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{k.ordered}</span></td>
                  <td style={{ padding:"12px 10px" }}>
                    <span className="chip flat" style={{ fontSize:10, padding:"2px 8px", background: k.status==="delivered"?"var(--moss)":k.status==="transit"?"var(--sky)":"var(--gold)", color:"white" }}>
                      {k.status}
                    </span>
                  </td>
                  <td style={{ padding:"12px 10px" }}><span className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{k.tracking||"—"}</span></td>
                  <td style={{ padding:"12px 10px" }}>
                    <select value={k.status} onChange={e=>updateStatus(k.id,e.target.value)}
                      style={{ padding:"3px 8px", borderRadius:8, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:11, fontFamily:"var(--font-ui)", color:"var(--ink)", cursor:"pointer" }}>
                      <option value="pending">pending</option>
                      <option value="transit">transit</option>
                      <option value="delivered">delivered</option>
                    </select>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  </Themed>
  );
};

// ── Teacher: Content Management + YouTube Embed ───────────────────────────────
const TeacherContent = ({ dark = false, go, session }) => {
  const tid = session?.teacherId;
  const { data: dash } = useApi(tid ? `/teacher/dashboard/${tid}` : "/teacher/dashboard/0", {});
  const batches = dash.batches || [];
  const [selectedBatch, setSelectedBatch] = React.useState(null);
  const activeBatch = batches.find(b => b.id === selectedBatch) || batches[0] || null;
  const courseId = activeBatch ? (activeBatch.course_id || null) : null;
  const { data: COURSE_CONTENT } = useApi(courseId ? `/content/${courseId}` : "/content/0");
  const [openUnit, setOpenUnit] = React.useState(null);
  const [showAdd, setShowAdd] = React.useState(false);
  const [addForm, setAddForm] = React.useState({ title:"", unit_id:"", type:"video", youtube_url:"", duration:"" });
  const [addSaving, setAddSaving] = React.useState(false);
  const [addError, setAddError] = React.useState("");
  const [showAddUnit, setShowAddUnit] = React.useState(false);
  const [unitTitle, setUnitTitle] = React.useState("");
  const [unitSaving, setUnitSaving] = React.useState(false);
  const [unitError, setUnitError] = React.useState("");
  const [ytInput, setYtInput] = React.useState("");
  const [preview, setPreview] = React.useState(null);
  const [content, setContent] = React.useState(null);
  const CC = content ?? COURSE_CONTENT;
  React.useEffect(() => { if (CC.length && !openUnit) setOpenUnit(CC[0].id); }, [CC.length]);
  const refreshContent = () => courseId && apiFetch(`/content/${courseId}`).then(r=>r.json()).then(setContent);

  const getYtId = url => {
    const m = url.match(/(?:v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
    return m ? m[1] : url.length === 11 ? url : null;
  };

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <TeacherSidebar active="/app/teacher/content" 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 }}>Content Management</div>
            <div className="mono" style={{ fontSize:11, color:"var(--ink-mute)" }}>{activeBatch ? `${activeBatch.name} · ${activeBatch.course}` : "Select a batch"}</div>
          </div>
          <div style={{ flex:1 }}/>
          {batches.length > 1 && <Tabs items={batches.map(b=>b.name)} active={activeBatch?.name||""} onChange={name => { const b = batches.find(x=>x.name===name); if(b) setSelectedBatch(b.id); }}/>}
          <button className="btn btn-ghost" onClick={() => { setShowAddUnit(true); setUnitError(""); }} style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add unit</button>
          <button className="btn btn-primary" onClick={() => setShowAdd(true)} style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} Add lesson</button>
        </div>
        <div style={{ flex:1, display:"grid", gridTemplateColumns:"1fr 1.4fr", overflow:"hidden" }}>
          <div style={{ borderRight:"var(--border-thin)", overflow:"auto", padding:18, background:"var(--paper)" }}>
            {CC.map(unit => (
              <div key={unit.id} style={{ marginBottom:10 }}>
                <button onClick={() => setOpenUnit(openUnit===unit.id?null:unit.id)} style={{ width:"100%", display:"flex", alignItems:"center", justifyContent:"space-between", padding:"10px 12px", borderRadius:10, border:"none", background: openUnit===unit.id ? "var(--paper-deep)" : "transparent", cursor:"pointer", fontFamily:"var(--font-ui)" }}>
                  <span style={{ fontWeight:700, fontSize:13 }}>{unit.unit}</span>
                  <span style={{ fontSize:11, color:"var(--ink-mute)" }}>{unit.lessons.length} lessons</span>
                </button>
                {openUnit === unit.id && (
                  <div style={{ paddingLeft:12, marginTop:4 }}>
                    {unit.lessons.map((l, li) => (
                      <div key={l.id||li} onClick={() => l.youtube && setPreview(l.youtube)} style={{ display:"flex", alignItems:"center", gap:8, padding:"8px 10px", borderRadius:8, cursor: l.youtube ? "pointer" : "default", marginBottom:2 }}>
                        <div style={{ width:28, height:28, borderRadius:8, background: l.type==="video" ? "var(--coral)" : l.type==="quiz" ? "var(--sky)" : l.type==="homework" ? "var(--gold)" : "var(--plum)", color:"white", display:"grid", placeItems:"center", flexShrink:0 }}>
                          {l.type==="video" ? I.play({ size:12 }) : l.type==="quiz" ? I.puzzle({ size:12 }) : I.book({ size:12 })}
                        </div>
                        <div style={{ flex:1, minWidth:0 }}>
                          <div style={{ fontSize:13, fontWeight:600 }}>{l.title}</div>
                          {l.duration && <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{l.duration}</div>}
                        </div>
                        <span className="chip flat" style={{ fontSize:10, padding:"1px 6px", background: l.status==="published" ? "var(--moss)" : "var(--gold)", color:"white" }}>{l.status}</span>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
          <div style={{ overflow:"auto", padding:22, background:"var(--paper-card)", display:"flex", flexDirection:"column", gap:16 }}>
            {preview ? (
              <div>
                <SectionHead eyebrow="YOUTUBE PREVIEW" title="Embedded video"/>
                <div style={{ position:"relative", paddingBottom:"56.25%", height:0, borderRadius:12, overflow:"hidden", border:"var(--border-thin)" }}>
                  <iframe src={`https://www.youtube.com/embed/${getYtId(preview)}`} title="YouTube video"
                    style={{ position:"absolute", top:0, left:0, width:"100%", height:"100%" }}
                    frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen/>
                </div>
                <button className="btn btn-ghost" onClick={() => setPreview(null)} style={{ marginTop:10, fontSize:12 }}>← Back to overview</button>
              </div>
            ) : (
              <>
                <div className="card-flat" style={{ padding:18 }}>
                  <SectionHead eyebrow="YOUTUBE INTEGRATION" title="Add video lesson"/>
                  <div style={{ display:"flex", gap:8, marginBottom:12 }}>
                    <input value={ytInput} onChange={e => setYtInput(e.target.value)} placeholder="Paste YouTube URL or video ID…" style={{ flex:1, padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }}/>
                    <button className="btn btn-primary" onClick={() => { const id = getYtId(ytInput); if(id) setPreview(id); }} style={{ padding:"8px 14px", fontSize:12 }}>Preview</button>
                  </div>
                  {ytInput && getYtId(ytInput) && (
                    <div style={{ borderRadius:10, overflow:"hidden", border:"var(--border-thin)", position:"relative", paddingBottom:"56.25%", height:0 }}>
                      <iframe src={`https://www.youtube.com/embed/${getYtId(ytInput)}`} title="Preview" style={{ position:"absolute", top:0, left:0, width:"100%", height:"100%" }} frameBorder="0" allowFullScreen/>
                    </div>
                  )}
                  {ytInput && !getYtId(ytInput) && <div style={{ fontSize:12, color:"var(--coral)", marginTop:4 }}>Invalid YouTube URL</div>}
                </div>
                <div className="card-flat" style={{ padding:18 }}>
                  <SectionHead eyebrow="OVERVIEW" title="Content stats"/>
                  <div style={{ display:"grid", gridTemplateColumns:"1fr 1fr", gap:10 }}>
                    {[
                      ["Units",    CC.length],
                      ["Lessons",  CC.reduce((a,u)=>a+(u.lessons||[]).length,0)],
                      ["Published",CC.reduce((a,u)=>a+(u.lessons||[]).filter(l=>l.status==="published").length,0)],
                      ["Videos",   CC.reduce((a,u)=>a+(u.lessons||[]).filter(l=>l.type==="video").length,0)],
                    ].map(([l,v]) => (
                      <div key={l} style={{ padding:12, background:"var(--paper-deep)", borderRadius:8, border:"var(--border-thin)" }}>
                        <div style={{ fontSize:11, color:"var(--ink-mute)" }}>{l}</div>
                        <div className="display" style={{ fontSize:24, marginTop:2 }}>{v}</div>
                      </div>
                    ))}
                  </div>
                </div>
              </>
            )}
          </div>
        </div>
      </div>
      {showAddUnit && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.5)", display:"flex", alignItems:"center", justifyContent:"center", zIndex:50 }} onClick={() => { setShowAddUnit(false); setUnitError(""); }}>
          <div className="codeland" onClick={e => e.stopPropagation()} style={{ background:"var(--paper-card)", borderRadius:16, padding:28, width:400, boxShadow:"var(--sh-soft)" }}>
            <div className="display" style={{ fontSize:20, marginBottom:18 }}>Add unit</div>
            {!courseId && (
              <div style={{ color:"var(--coral)", fontSize:13, marginBottom:12 }}>Please select a batch with a course first.</div>
            )}
            <div style={{ marginBottom:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>UNIT TITLE</div>
              <input
                value={unitTitle}
                onChange={e=>setUnitTitle(e.target.value)}
                placeholder="e.g. Unit 1 · Getting Started"
                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>
            {unitError && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:10 }}>{unitError}</div>}
            <div style={{ display:"flex", gap:10, marginTop:4 }}>
              <button className="btn btn-primary" disabled={unitSaving || !courseId} onClick={async () => {
                if (!unitTitle.trim()) { setUnitError("Title required"); return; }
                setUnitError(""); setUnitSaving(true);
                const res = await apiFetch(`/courses/${courseId}/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(""); setShowAddUnit(false); setUnitSaving(false);
                await refreshContent();
              }} style={{ flex:1, padding:"10px 0", fontSize:14 }}>{unitSaving ? "Saving…" : "Add unit"}</button>
              <button className="btn btn-ghost" onClick={() => { setShowAddUnit(false); setUnitError(""); }} style={{ padding:"10px 14px", fontSize:14 }}>Cancel</button>
            </div>
          </div>
        </div>
      )}
      {showAdd && (
        <div style={{ position:"fixed", inset:0, background:"rgba(0,0,0,.5)", display:"flex", alignItems:"center", justifyContent:"center", zIndex:50 }} onClick={() => { setShowAdd(false); setAddError(""); }}>
          <div className="codeland" onClick={e => e.stopPropagation()} style={{ background:"var(--paper-card)", borderRadius:16, padding:28, width:440, boxShadow:"var(--sh-soft)" }}>
            <div className="display" style={{ fontSize:20, marginBottom:18 }}>Add lesson</div>

            <div style={{ marginBottom:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>TITLE</div>
              <input value={addForm.title} onChange={e=>setAddForm(f=>({...f,title:e.target.value}))} placeholder="e.g. Functions intro"
                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>

            <div style={{ marginBottom:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>UNIT</div>
              <select value={addForm.unit_id} onChange={e=>setAddForm(f=>({...f,unit_id:e.target.value}))}
                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)" }}>
                <option value="">— select unit —</option>
                {CC.map(u => <option key={u.id} value={u.id}>{u.unit}</option>)}
              </select>
            </div>

            <div style={{ marginBottom:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>TYPE</div>
              <select value={addForm.type} onChange={e=>setAddForm(f=>({...f,type:e.target.value}))}
                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)" }}>
                {["video","quiz","homework","project"].map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </div>

            {addForm.type === "video" && (
              <div style={{ marginBottom:12 }}>
                <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>YOUTUBE URL</div>
                <input value={addForm.youtube_url} onChange={e=>setAddForm(f=>({...f,youtube_url:e.target.value}))} placeholder="https://youtube.com/watch?v=…"
                  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>
            )}

            <div style={{ marginBottom:12 }}>
              <div style={{ fontSize:11, fontWeight:700, color:"var(--ink-mute)", marginBottom:4, fontFamily:"var(--font-mono)", textTransform:"uppercase" }}>DURATION <span style={{ fontWeight:400 }}>(optional)</span></div>
              <input value={addForm.duration} onChange={e=>setAddForm(f=>({...f,duration:e.target.value}))} placeholder="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" }}/>
            </div>

            {addError && <div style={{ color:"var(--coral)", fontSize:13, marginBottom:10 }}>{addError}</div>}

            <div style={{ display:"flex", gap:10, marginTop:18 }}>
              <button className="btn btn-primary" disabled={addSaving} onClick={async () => {
                setAddError("");
                if (!addForm.title.trim()) { setAddError("Title is required"); return; }
                if (!addForm.unit_id) { setAddError("Please select a unit"); return; }
                setAddSaving(true);
                const res = await apiFetch(`/units/${addForm.unit_id}/lessons`, { method:"POST", body: JSON.stringify({ title:addForm.title, type:addForm.type, youtube_url:addForm.youtube_url, duration:addForm.duration }) });
                if (!res.ok) { const d=await res.json(); setAddError(d.error||"Failed"); setAddSaving(false); return; }
                setAddForm({ title:"", unit_id:"", type:"video", youtube_url:"", duration:"" });
                setShowAdd(false); setAddSaving(false);
                await refreshContent();
              }} style={{ flex:1, padding:"10px 0", fontSize:14 }}>{addSaving ? "Saving…" : "Add lesson"}</button>
              <button className="btn btn-ghost" onClick={() => { setShowAdd(false); setAddError(""); }} style={{ padding:"10px 14px", fontSize:14 }}>Cancel</button>
            </div>
          </div>
        </div>
      )}
    </Themed>
  );
};

// ── Student: Quiz ─────────────────────────────────────────────────────────────
const StudentQuiz = ({ theme = "", go, session }) => {
  const { data: quizList, loading: quizListLoading } = useApi("/quizzes");
  const firstQuiz = quizList[0];
  const { data: QUIZ_QUESTIONS, loading: questionsLoading } = useApi(firstQuiz ? `/quizzes/${firstQuiz.id}/questions` : null);
  const [curr, setCurr] = React.useState(0);
  const [answers, setAnswers] = React.useState({});
  const [submitted, setSubmitted] = React.useState(false);
  const q = QUIZ_QUESTIONS[curr];
  const score = Object.entries(answers).filter(([i,a]) => {
    const qq = QUIZ_QUESTIONS[+i];
    return qq && (qq.type === "mcq" || !qq.type) && qq.ans === a;
  }).length;
  const mcqCount = QUIZ_QUESTIONS.filter(q => !q.type || q.type === "mcq").length;

  if (quizListLoading) return <Spinner/>;
  if (!firstQuiz) return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", display:"flex", alignItems:"center", justifyContent:"center", background:"var(--paper)" }}>
      <div style={{ textAlign:"center", maxWidth:360 }}>
        <div style={{ fontSize:56, marginBottom:16 }}>🧩</div>
        <div className="display" style={{ fontSize:28, marginBottom:8 }}>You're all caught up!</div>
        <div style={{ color:"var(--ink-soft)", fontSize:14 }}>No quizzes assigned yet. Check back after your next class.</div>
      </div>
    </Themed>
  );
  if (questionsLoading) return <Spinner/>;
  if (!q && !submitted) return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", display:"flex", alignItems:"center", justifyContent:"center", background:"var(--paper)" }}>
      <div style={{ textAlign:"center", maxWidth:360 }}>
        <div style={{ fontSize:56, marginBottom:16 }}>🧩</div>
        <div className="display" style={{ fontSize:28, marginBottom:8 }}>No questions yet</div>
        <div style={{ color:"var(--ink-soft)", fontSize:14 }}>This quiz has no questions added yet. Check back later.</div>
      </div>
    </Themed>
  );

  if (submitted) {
    const pct = Math.round((score/Math.max(mcqCount,1))*100);
    return (
      <Themed theme={theme} style={{ width:"100%", height:"100%", display:"flex", alignItems:"center", justifyContent:"center", background:"var(--paper)" }}>
        <div style={{ textAlign:"center", maxWidth:400 }}>
          <div style={{ width:100, height:100, borderRadius:"50%", background: pct>=80?"var(--moss)":"var(--gold)", color:"white", display:"grid", placeItems:"center", margin:"0 auto 18px", border:"var(--border)", boxShadow:"var(--sh-3)" }}>
            <div className="display" style={{ fontSize:36 }}>{pct}%</div>
          </div>
          <div className="display" style={{ fontSize:32, marginBottom:8 }}>{pct>=80 ? "Quiz master!" : pct>=60 ? "Good effort!" : "Keep practising!"}</div>
          <div style={{ color:"var(--ink-soft)", marginBottom:24 }}>{score}/{mcqCount} MCQ correct · +{score*20} XP earned</div>
          <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
            {QUIZ_QUESTIONS.map((q,i) => (
              <div key={i} style={{ display:"flex", alignItems:"center", gap:10, padding:"10px 14px", borderRadius:10, background:"var(--paper-card)", border:"var(--border-thin)", textAlign:"left" }}>
                <span style={{ color: answers[i]===q.ans ? "var(--moss)" : "var(--coral)", flexShrink:0 }}>
                  {answers[i]===q.ans ? I.check({ size:16 }) : I.x({ size:16 })}
                </span>
                <div style={{ flex:1, fontSize:13 }}>{q.q}</div>
              </div>
            ))}
          </div>
          <button className="btn btn-primary" onClick={() => { setSubmitted(false); setCurr(0); setAnswers({}); }} style={{ marginTop:20, padding:"12px 28px", fontSize:14 }}>Retry quiz</button>
        </div>
      </Themed>
    );
  }

  return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", display:"flex", flexDirection:"column", background:"var(--paper)" }}>
      <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 }}>Quiz · {firstQuiz?.title || "Quiz"}</div>
        <div style={{ flex:1 }}/>
        <span className="mono" style={{ fontSize:12, color:"var(--ink-mute)" }}>Q {curr+1} / {QUIZ_QUESTIONS.length}</span>
      </div>
      <div style={{ flex:1, display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", padding:32 }}>
        <div style={{ width:"100%", maxWidth:560 }}>
          <div style={{ display:"flex", gap:4, marginBottom:20 }}>
            {QUIZ_QUESTIONS.map((_,i) => (
              <div key={i} style={{ flex:1, height:4, borderRadius:2, background: i < curr ? "var(--moss)" : i===curr ? "var(--coral)" : "var(--paper-deep)", border:"1px solid var(--rule)" }}/>
            ))}
          </div>
          <div className="card" style={{ padding:28 }}>
            {q.type === "video" && q.video_url && (
              <div style={{ marginBottom:16, borderRadius:12, overflow:"hidden", background:"var(--paper-deep)", border:"var(--border-thin)" }}>
                <iframe
                  src={`https://www.youtube.com/embed/${q.video_url.includes("v=") ? q.video_url.split("v=")[1].split("&")[0] : q.video_url.split("/").pop()}`}
                  style={{ width:"100%", height:200, border:"none", display:"block" }}
                  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope"
                  allowFullScreen/>
              </div>
            )}
            <div className="display" style={{ fontSize:22, lineHeight:1.3, marginBottom:22 }}>{q.q}</div>
            {(!q.type || q.type === "mcq") && (
              <div style={{ display:"flex", flexDirection:"column", gap:10 }}>
                {q.opts.map((opt,oi) => (
                  <button key={oi} onClick={() => setAnswers(a => ({ ...a, [curr]: oi }))} style={{
                    padding:"14px 18px", borderRadius:12, border:"var(--border)", textAlign:"left",
                    background: answers[curr]===oi ? "var(--coral)" : "var(--paper-card)",
                    color: answers[curr]===oi ? "white" : "var(--ink)",
                    fontWeight: answers[curr]===oi ? 700 : 500, fontSize:14, cursor:"pointer",
                  }}>{opt}</button>
                ))}
              </div>
            )}
            {(q.type === "paragraph" || q.type === "video") && (
              <textarea
                value={answers[curr] || ""}
                onChange={e => setAnswers(a => ({ ...a, [curr]: e.target.value }))}
                placeholder="Write your answer here…"
                style={{ width:"100%", minHeight:100, padding:"12px 14px", border:"var(--border-thin)", borderRadius:12, background:"var(--paper-card)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", resize:"vertical", outline:"none", boxSizing:"border-box" }}
              />
            )}
            <div style={{ display:"flex", justifyContent:"space-between", marginTop:22 }}>
              <button className="btn btn-ghost" onClick={() => setCurr(c => Math.max(0,c-1))} disabled={curr===0} style={{ padding:"10px 18px", fontSize:13 }}>← Back</button>
              {curr < QUIZ_QUESTIONS.length-1
                ? <button className="btn btn-primary" onClick={() => setCurr(c => c+1)} disabled={answers[curr]==null || answers[curr]===""} style={{ padding:"10px 22px", fontSize:13 }}>Next →</button>
                : <button className="btn btn-primary" onClick={() => setSubmitted(true)} disabled={answers[curr]==null || answers[curr]===""} style={{ padding:"10px 22px", fontSize:13 }}>Submit quiz</button>}
            </div>
          </div>
        </div>
      </div>
    </Themed>
  );
};

// ── Student: Certificates ─────────────────────────────────────────────────────
const StudentCertificates = ({ theme = "", go, session }) => {
  const sid = session?.studentId;
  const { data: CERTIFICATES } = useApi(sid ? `/certificates/${sid}` : "/certificates/0");
  return (
  <Themed theme={theme} style={{ width:"100%", height:"100%", background:"var(--paper)" }}>
    <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 Certificates</div>
      <div style={{ flex:1 }}/>
      <span style={{ fontSize:12, color:"var(--ink-mute)" }}>{CERTIFICATES.length} earned</span>
    </div>
    <div style={{ padding:28, display:"grid", gridTemplateColumns:"repeat(auto-fit, minmax(300px, 1fr))", gap:20 }}>
      {CERTIFICATES.map((c,i) => (
        <div key={i} className="card" style={{ padding:0, overflow:"hidden", position:"relative" }}>
          <div style={{ background:c.color, padding:"28px 28px 18px", color:"white", position:"relative", overflow:"hidden" }}>
            <div style={{ position:"absolute", top:-30, right:-30, width:120, height:120, borderRadius:"50%", background:"rgba(255,255,255,.1)" }}/>
            <div style={{ position:"absolute", bottom:-20, left:-10, width:80, height:80, borderRadius:"50%", background:"rgba(255,255,255,.08)" }}/>
            <div style={{ position:"relative" }}>
              <div style={{ width:44, height:44, borderRadius:12, background:"rgba(255,255,255,.25)", border:"1.5px solid rgba(255,255,255,.4)", display:"grid", placeItems:"center", marginBottom:12 }}>
                {I.trophy({ size:22 })}
              </div>
              <div className="display" style={{ fontSize:24, lineHeight:1.1 }}>{c.title}</div>
              <div style={{ fontSize:13, opacity:0.9, marginTop:4 }}>{c.course}</div>
            </div>
          </div>
          <div style={{ padding:"16px 28px", display:"flex", alignItems:"center", justifyContent:"space-between" }}>
            <div>
              <div style={{ fontSize:11, color:"var(--ink-mute)", fontFamily:"var(--font-mono)" }}>ISSUED {c.issued}</div>
              <div style={{ fontSize:11, color:"var(--ink-mute)", fontFamily:"var(--font-mono)", marginTop:2 }}>{c.id}</div>
            </div>
            <button className="btn btn-ghost" style={{ padding:"6px 12px", fontSize:12 }}>{I.upload({ size:12 })} Download</button>
          </div>
        </div>
      ))}
      <div className="card" style={{ padding:28, display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", border:"2px dashed var(--rule)", background:"transparent", minHeight:160, gap:12 }}>
        <div style={{ width:44, height:44, borderRadius:12, background:"var(--paper-deep)", display:"grid", placeItems:"center", color:"var(--ink-mute)" }}>{I.lock({ size:22 })}</div>
        <div style={{ textAlign:"center" }}>
          <div style={{ fontWeight:700, fontSize:14 }}>Next: Web Developer</div>
          <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:4 }}>Complete Web · Intermediate to unlock</div>
        </div>
      </div>
    </div>
  </Themed>
  );
};

// ── Student: Discussion Forum ─────────────────────────────────────────────────
const StudentForum = ({ theme = "", go, session }) => {
  const { data: initThreads, loading } = useApi("/forum/threads");
  const [threads, setThreads] = React.useState(null);
  const [active, setActive]   = React.useState(null);
  const [replies, setReplies] = React.useState([]);
  const [replyText, setReplyText] = React.useState("");
  const [sending, setSending] = React.useState(false);
  const [showNew, setShowNew] = React.useState(false);
  const [newTitle, setNewTitle] = React.useState("");
  const [newTag, setNewTag]   = React.useState("question");
  const FORUM_THREADS = threads ?? initThreads;
  const refreshThreads = () => apiFetch("/forum/threads").then(r=>r.json()).then(setThreads).catch(()=>{});
  const loadReplies = (id) => apiFetch(`/forum/threads/${id}/replies`).then(r=>r.json()).then(setReplies).catch(()=>{});
  React.useEffect(() => {
    if (!active) { setReplies([]); return; }
    loadReplies(active);
  }, [active]);
  const sendReply = async () => {
    if (!replyText.trim() || !active || sending) return;
    setSending(true);
    // Author is derived server-side from the session; we only send the text.
    await apiFetch(`/forum/threads/${active}/replies`, { method:"POST", body: JSON.stringify({ text: replyText }) });
    setReplyText("");
    await loadReplies(active);
    await refreshThreads(); // keep reply counts current
    setSending(false);
  };
  const createThread = async e => {
    e.preventDefault();
    if (!newTitle.trim()) return;
    const res = await apiFetch("/forum/threads", { method:"POST", body: JSON.stringify({ title: newTitle, tag: newTag }) });
    const created = await res.json().catch(()=>null);
    setNewTitle(""); setShowNew(false);
    await refreshThreads();
    if (created && created.id) setActive(created.id);
  };
  const thread = active ? FORUM_THREADS.find(t => t.id === active) : null;
  if (loading) return <Spinner/>;
  return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", background:"var(--paper)", display:"flex", flexDirection:"column" }}>
      {showNew && (
        <Modal title="New thread" onClose={()=>setShowNew(false)}>
          <form onSubmit={createThread}>
            <FormField label="TITLE / QUESTION">
              <input required style={inputStyle} value={newTitle} onChange={e=>setNewTitle(e.target.value)} placeholder="e.g. How do I use a for loop?"/>
            </FormField>
            <FormField label="TAG">
              <select style={selectStyle} value={newTag} onChange={e=>setNewTag(e.target.value)}>
                {["question","help","idea","showcase"].map(t=><option key={t} value={t}>{t}</option>)}
              </select>
            </FormField>
            <div style={{ display:"flex", gap:10, justifyContent:"flex-end", marginTop:4 }}>
              <button type="button" onClick={()=>setShowNew(false)} className="btn btn-ghost">Cancel</button>
              <button type="submit" className="btn btn-primary">Post thread</button>
            </div>
          </form>
        </Modal>
      )}
      <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 }}>Community Forum</div>
        <div style={{ flex:1 }}/>
        <button onClick={()=>setShowNew(true)} className="btn btn-primary" style={{ padding:"6px 14px", fontSize:12 }}>{I.plus({ size:14 })} New thread</button>
      </div>
      <div style={{ flex:1, display:"grid", gridTemplateColumns: active ? "1fr 1.4fr" : "1fr", overflow:"hidden" }}>
        <div style={{ overflow:"auto", padding:20, display:"flex", flexDirection:"column", gap:10 }}>
          {FORUM_THREADS.map(t => (
            <div key={t.id} onClick={() => setActive(active===t.id?null:t.id)} className="card" style={{ padding:16, cursor:"pointer", border: active===t.id ? "2px solid var(--coral)" : "var(--border)" }}>
              <div style={{ display:"flex", alignItems:"flex-start", gap:10 }}>
                <Avatar name={(t.author||"?")[0]} color={t.color||"var(--sky)"} size={32}/>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontWeight:700, fontSize:14, lineHeight:1.3 }}>{t.title}</div>
                  <div style={{ display:"flex", gap:8, marginTop:6, alignItems:"center" }}>
                    <span style={{ fontSize:11, color:"var(--ink-mute)" }}>{t.author} · {t.time}</span>
                    <span className="chip flat" style={{ fontSize:10, padding:"1px 6px" }}>{t.tag}</span>
                    {t.solved && <span className="chip flat" style={{ fontSize:10, padding:"1px 6px", background:"var(--moss)", color:"white" }}>solved</span>}
                    <span style={{ marginLeft:"auto", fontSize:11, color:"var(--ink-mute)" }}>{t.replies} replies</span>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
        {thread && (
          <div style={{ borderLeft:"var(--border-thin)", overflow:"auto", padding:20, background:"var(--paper-card)" }}>
            <div style={{ marginBottom:16 }}>
              <div className="display" style={{ fontSize:20, lineHeight:1.3 }}>{thread.title}</div>
              <div style={{ display:"flex", gap:8, marginTop:8, alignItems:"center" }}>
                <Avatar name={(thread.author||"?")[0]} color={thread.color||"var(--sky)"} size={24}/>
                <span style={{ fontSize:12, color:"var(--ink-mute)" }}>{thread.author || "Staff"} · {thread.time} ago</span>
                <span className="chip flat" style={{ fontSize:10, padding:"1px 6px" }}>{thread.tag}</span>
              </div>
            </div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", letterSpacing:".06em", marginBottom:12 }}>
              {replies.length} {replies.length === 1 ? "REPLY" : "REPLIES"}
            </div>
            {replies.length === 0 && (
              <div style={{ padding:14, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)", fontSize:13, color:"var(--ink-mute)", marginBottom:14 }}>
                No replies yet — be the first to help out!
              </div>
            )}
            {replies.map((r,i) => (
              <div key={i} style={{ display:"flex", gap:8, marginBottom:12 }}>
                <Avatar name={(r.author||"?")[0]} color={ r.teacher ? "var(--moss)" : "var(--sky)"} size={28}/>
                <div style={{ flex:1 }}>
                  <div style={{ display:"flex", alignItems:"center", gap:6, marginBottom:4 }}>
                    <span style={{ fontWeight:700, fontSize:13 }}>{r.author}</span>
                    {r.teacher && <span className="chip flat" style={{ fontSize:9, padding:"1px 5px", background:"var(--moss)", color:"white" }}>Teacher</span>}
                  </div>
                  <div style={{ padding:"10px 12px", background:"var(--paper-deep)", borderRadius:10, fontSize:13, lineHeight:1.5 }}>{r.text}</div>
                </div>
              </div>
            ))}
            <div style={{ display:"flex", gap:8, marginTop:8 }}>
              <input value={replyText} onChange={e=>setReplyText(e.target.value)} onKeyDown={e=>e.key==="Enter"&&sendReply()} placeholder="Write a reply…" style={{ flex:1, padding:"8px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-deep)", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none" }}/>
              <button onClick={sendReply} disabled={sending} className="btn btn-primary" style={{ padding:"8px 14px", fontSize:12, opacity: sending ? 0.6 : 1 }}>{I.send({ size:14 })}</button>
            </div>
          </div>
        )}
      </div>
    </Themed>
  );
};

// ── Student: Homework Submission ──────────────────────────────────────────────
const StudentHomework = ({ theme = "", go, session }) => {
  const sid = session?.studentId;
  const { data: initHomework } = useApi(sid ? `/homework?student=${sid}` : "/homework?student=0");
  const [homework, setHomework] = React.useState(null);
  const HOMEWORK = homework ?? initHomework;
  const [active, setActive]     = React.useState(null);
  const [answers, setAnswers]   = React.useState({});   // { [hw_id]: { code, drive_link } }
  const [submitting, setSubmitting] = React.useState(false);

  const submitHw = async hw => {
    if (!sid) return;
    setSubmitting(true);
    const a = answers[hw.id] || {};
    await apiFetch("/hw-submissions", { method:"POST", body: JSON.stringify({
      homework_id: hw.id, student_id: sid,
      code: a.code || null, drive_link: a.drive_link || null,
    })});
    const fresh = await apiFetch(`/homework?student=${sid}`).then(r=>r.json());
    setHomework(fresh);
    setActive(null); setSubmitting(false);
  };

  return (
    <Themed theme={theme} style={{ width:"100%", height:"100%", background:"var(--paper)" }}>
      <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 }}>Homework</div>
        <div style={{ flex:1 }}/>
        <span style={{ fontSize:12, color:"var(--ink-mute)" }}>{HOMEWORK.filter(h=>h.status==="pending").length} pending</span>
      </div>
      <div style={{ padding:22, display:"flex", flexDirection:"column", gap:12 }}>
        {HOMEWORK.length === 0 && (
          <div style={{ textAlign:"center", padding:60, color:"var(--ink-mute)" }}>
            <div style={{ fontSize:56, marginBottom:16 }}>✅</div>
            <div className="display" style={{ fontSize:28, marginBottom:8 }}>You're all caught up!</div>
            <div style={{ fontSize:14 }}>No homework assigned yet. Enjoy your free time!</div>
          </div>
        )}
        {HOMEWORK.map(hw => (
          <div key={hw.id} className="card" style={{ padding:18 }}>
            <div style={{ display:"flex", alignItems:"center", gap:14 }}>
              <div style={{ width:44, height:44, borderRadius:12, background: hw.status==="pending"?"var(--coral)":hw.status==="submitted"?"var(--gold)":"var(--moss)", color:"white", border:"var(--border)", display:"grid", placeItems:"center", flexShrink:0 }}>
                {hw.status==="graded" ? I.check({ size:20 }) : hw.status==="submitted" ? I.clock({ size:20 }) : I.book({ size:20 })}
              </div>
              <div style={{ flex:1 }}>
                <div style={{ display:"flex", alignItems:"center", gap:8 }}>
                  <span style={{ fontWeight:700, fontSize:15 }}>{hw.title}</span>
                  {hw.type && hw.type !== "paragraph" && (
                    <span style={{ fontSize:10, fontWeight:700, padding:"2px 7px", borderRadius:999, background: hw.type==="video"?"var(--sky)":hw.type==="mcq"?"var(--plum)":"var(--moss)", color:"white" }}>{hw.type.toUpperCase()}</span>
                  )}
                </div>
                <div style={{ fontSize:12, color:"var(--ink-mute)", marginTop:2 }}>
                  {hw.course} · Due {hw.due}
                  {hw.score && <span style={{ color:"var(--moss)", fontWeight:700, marginLeft:8 }}>{hw.score}</span>}
                </div>
              </div>
              <span className="chip flat" style={{ fontSize:11, padding:"3px 10px", background: hw.status==="pending"?"var(--coral)":hw.status==="submitted"?"var(--gold)":"var(--moss)", color:"white" }}>{hw.status}</span>
              <span className="chip" style={{ background:"var(--gold)", fontSize:11 }}>{I.bolt({ size:12 })} +{hw.xp} XP</span>
              {hw.status === "pending" && (
                <button className="btn btn-primary" onClick={() => setActive(hw.id)} style={{ padding:"6px 14px", fontSize:12 }}>Submit</button>
              )}
            </div>
            {active === hw.id && (
              <div style={{ marginTop:14, padding:14, background:"var(--paper-deep)", borderRadius:10, border:"var(--border-thin)" }}>
                {hw.description && (
                  <div style={{ fontSize:13, color:"var(--ink-soft)", marginBottom:10, padding:"8px 12px", background:"var(--paper-card)", borderRadius:8, borderLeft:"3px solid var(--coral)" }}>
                    {hw.description}
                  </div>
                )}
                {(!hw.type || hw.type === "paragraph") && (
                  <div style={{ marginBottom:10 }}>
                    <div style={{ fontSize:12, color:"var(--ink-mute)", marginBottom:6 }}>Write your response:</div>
                    <textarea value={(answers[hw.id]||{}).code||""} onChange={e=>setAnswers(a=>({...a,[hw.id]:{...(a[hw.id]||{}),code:e.target.value}}))}
                      placeholder="Type your answer here…" style={{ width:"100%", minHeight:100, padding:"10px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-card)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", resize:"vertical", outline:"none", boxSizing:"border-box" }}/>
                  </div>
                )}
                {hw.type === "video" && hw.video_url && (
                  <div style={{ marginBottom:10, borderRadius:10, overflow:"hidden" }}>
                    <iframe src={`https://www.youtube.com/embed/${hw.video_url.includes("v=") ? hw.video_url.split("v=")[1].split("&")[0] : hw.video_url.split("/").pop()}`}
                      style={{ width:"100%", height:180, border:"none", display:"block" }} allowFullScreen/>
                    <textarea value={(answers[hw.id]||{}).code||""} onChange={e=>setAnswers(a=>({...a,[hw.id]:{...(a[hw.id]||{}),code:e.target.value}}))}
                      placeholder="Your response after watching…" style={{ width:"100%", minHeight:80, padding:"10px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-card)", fontSize:14, fontFamily:"var(--font-ui)", color:"var(--ink)", resize:"vertical", outline:"none", boxSizing:"border-box", marginTop:8 }}/>
                  </div>
                )}
                {hw.type === "mcq" && (
                  <div style={{ padding:"12px 14px", background:"var(--paper-card)", borderRadius:8, fontSize:13, color:"var(--ink-mute)", marginBottom:10 }}>
                    📋 Your teacher will provide MCQ questions during class. Submit to confirm you've seen this assignment.
                  </div>
                )}
                <div style={{ marginBottom:10 }}>
                  <div style={{ fontSize:12, color:"var(--ink-mute)", marginBottom:6 }}>Google Drive link <span style={{ color:"var(--ink-mute)", fontWeight:400 }}>(optional — for files, code, projects)</span></div>
                  <input value={(answers[hw.id]||{}).drive_link||""} onChange={e=>setAnswers(a=>({...a,[hw.id]:{...(a[hw.id]||{}),drive_link:e.target.value}}))}
                    placeholder="https://drive.google.com/file/…"
                    style={{ width:"100%", padding:"9px 12px", border:"var(--border-thin)", borderRadius:8, background:"var(--paper-card)", fontSize:13, fontFamily:"var(--font-ui)", color:"var(--ink)", outline:"none", boxSizing:"border-box" }}/>
                </div>
                <div style={{ display:"flex", gap:8, marginTop:12 }}>
                  <button className="btn btn-primary" disabled={submitting} onClick={() => submitHw(hw)} style={{ padding:"8px 18px", fontSize:12 }}>{submitting?"Submitting…":"Submit"}</button>
                  <button className="btn btn-ghost" onClick={() => setActive(null)} style={{ padding:"8px 14px", fontSize:12 }}>Cancel</button>
                </div>
              </div>
            )}
          </div>
        ))}
      </div>
    </Themed>
  );
};

// ── Floating Chatbot Widget ───────────────────────────────────────────────────
const ChatbotWidget = () => {
  const [open, setOpen] = React.useState(false);
  const [msgs, setMsgs] = React.useState([{ from:"bot", text:"Hi! I'm Cody 🤖 How can I help you today?" }]);
  const [input, setInput] = React.useState("");
  const RESPONSES = ["That's a great question! Your teacher Ms. Priya can help with that in your next class.","I see! Try checking the Library section for related videos.","Your next class is today at 7:00 PM. Don't forget to join the Google Meet link!","You can reach support at support@epiqminds.com — they typically respond within 2 hours."];
  const send = () => {
    if (!input.trim()) return;
    const userMsg = input;
    setMsgs(m => [...m, { from:"user", text:userMsg }]);
    setInput("");
    setTimeout(() => setMsgs(m => [...m, { from:"bot", text:RESPONSES[Math.floor(Math.random()*RESPONSES.length)] }]), 700);
  };
  return (
    <div style={{ position:"fixed", bottom:20, right:20, zIndex:999, fontFamily:"var(--font-ui)" }}>
      {open && (
        <div style={{ position:"absolute", bottom:60, right:0, width:300, background:"white", borderRadius:16, boxShadow:"0 8px 32px rgba(0,0,0,.18)", border:"1px solid rgba(0,0,0,.08)", overflow:"hidden" }}>
          <div style={{ padding:"12px 16px", background:"var(--coral)", color:"white", display:"flex", alignItems:"center", gap:8 }}>
            <div style={{ width:28, height:28, borderRadius:"50%", background:"rgba(255,255,255,.25)", display:"grid", placeItems:"center", fontSize:16 }}>🤖</div>
            <div>
              <div style={{ fontWeight:700, fontSize:13 }}>Cody · Support</div>
              <div style={{ fontSize:10, opacity:.85 }}>Always here to help</div>
            </div>
            <button onClick={() => setOpen(false)} style={{ marginLeft:"auto", border:"none", background:"transparent", color:"white", fontSize:18, cursor:"pointer", lineHeight:1 }}>×</button>
          </div>
          <div style={{ height:200, overflow:"auto", padding:12, display:"flex", flexDirection:"column", gap:8 }}>
            {msgs.map((m,i) => (
              <div key={i} style={{ display:"flex", justifyContent: m.from==="user" ? "flex-end" : "flex-start" }}>
                <div style={{ maxWidth:"80%", padding:"8px 12px", borderRadius:12, background: m.from==="user" ? "var(--coral)" : "#f0f0f0", color: m.from==="user" ? "white" : "#222", fontSize:13, lineHeight:1.4 }}>{m.text}</div>
              </div>
            ))}
          </div>
          <div style={{ padding:"8px 12px", borderTop:"1px solid #eee", display:"flex", gap:8 }}>
            <input value={input} onChange={e => setInput(e.target.value)} onKeyDown={e => e.key==="Enter" && send()} placeholder="Ask anything…" style={{ flex:1, padding:"6px 10px", border:"1px solid #ddd", borderRadius:8, fontSize:13, outline:"none" }}/>
            <button onClick={send} style={{ padding:"6px 12px", background:"var(--coral)", color:"white", border:"none", borderRadius:8, fontSize:13, cursor:"pointer", fontWeight:700 }}>→</button>
          </div>
        </div>
      )}
      <button onClick={() => setOpen(o => !o)} style={{ width:48, height:48, borderRadius:"50%", background:"var(--coral)", color:"white", border:"2px solid white", boxShadow:"0 4px 16px rgba(0,0,0,.2)", fontSize:22, cursor:"pointer", display:"grid", placeItems:"center" }}>
        {open ? "×" : "💬"}
      </button>
    </div>
  );
};

// ── Admin: XP / Points Criteria ───────────────────────────────────────────────
const CATEGORY_ORDER = ["Engagement","Completion","Assessment","Difficulty","Bonus"];
const CATEGORY_COLOR = {
  Engagement: "var(--sky)", Completion: "var(--moss)", Assessment: "var(--gold)",
  Difficulty: "var(--coral)", Bonus: "var(--plum)",
};

const AdminXPCriteria = ({ dark = true, go }) => {
  const { data: initCriteria, loading: loadC } = useApi("/admin/xp-criteria");
  const { data: initAwards,   loading: loadA } = useApi("/admin/xp-awards");
  const { data: STUDENTS } = useApi("/students");

  const [criteria, setCriteria]   = React.useState(null);
  const [awards, setAwards]       = React.useState(null);
  const [editId, setEditId]       = React.useState(null);
  const [editPts, setEditPts]     = React.useState("");
  const [saving, setSaving]       = React.useState(false);

  // Award form state
  const [awardForm, setAwardForm] = React.useState({ student_id:"", mode:"criteria", criteria_id:"", custom_reason:"", custom_pts:"" });
  const [awarding, setAwarding]   = React.useState(false);
  const [awardMsg, setAwardMsg]   = React.useState("");

  const list     = criteria ?? initCriteria;
  const awardLog = awards   ?? initAwards;

  const refresh = () => {
    apiFetch("/admin/xp-criteria").then(r=>r.json()).then(setCriteria);
    apiFetch("/admin/xp-awards").then(r=>r.json()).then(setAwards);
  };

  const startEdit = (row) => { setEditId(row.id); setEditPts(String(row.points)); };

  const saveEdit = async (row) => {
    setSaving(true);
    await apiFetch(`/admin/xp-criteria/${row.id}`, { method:"PATCH", body: JSON.stringify({ points: parseInt(editPts) }) });
    setEditId(null); setSaving(false);
    refresh();
  };

  const toggleEnabled = async (row) => {
    await apiFetch(`/admin/xp-criteria/${row.id}`, { method:"PATCH", body: JSON.stringify({ enabled: !row.enabled }) });
    refresh();
  };

  const submitAward = async e => {
    e.preventDefault();
    setAwardMsg(""); setAwarding(true);
    const isCustom = awardForm.mode === "custom";
    const crit = !isCustom && awardForm.criteria_id ? list.find(c => c.id === parseInt(awardForm.criteria_id)) : null;
    const points = isCustom ? parseInt(awardForm.custom_pts) : (crit ? crit.points : 0);
    const reason = isCustom ? awardForm.custom_reason : (crit ? crit.label : "");
    if (!awardForm.student_id || !points || !reason) { setAwardMsg("Please fill all fields."); setAwarding(false); return; }
    const res = await apiFetch("/admin/xp-award", { method:"POST", body: JSON.stringify({
      student_id: parseInt(awardForm.student_id), points, reason,
      criteria_id: !isCustom && crit ? crit.id : null,
    })});
    if (!res.ok) { const d=await res.json(); setAwardMsg(d.error||"Failed"); setAwarding(false); return; }
    setAwardMsg(`+${points} XP awarded!`);
    setAwardForm({ student_id:"", mode:"criteria", criteria_id:"", custom_reason:"", custom_pts:"" });
    setAwarding(false);
    refresh();
  };

  const grouped = CATEGORY_ORDER.map(cat => ({
    cat, rows: list.filter(r => r.category === cat),
  })).filter(g => g.rows.length > 0);

  const selectedCrit = awardForm.criteria_id ? list.find(c => c.id === parseInt(awardForm.criteria_id)) : null;

  const fmtTime = ts => {
    try { return new Date(ts).toLocaleDateString("en-GB",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}); }
    catch { return ts; }
  };

  if (loadC) return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/xp-criteria" go={go}/>
      <div style={{ flex:1, display:"flex", alignItems:"center", justifyContent:"center" }}><Spinner/></div>
    </Themed>
  );

  return (
    <Themed className={dark ? "theme-dark" : ""} style={{ width:"100%", height:"100%", display:"flex" }}>
      <AdminSidebar active="/app/admin/xp-criteria" go={go}/>
      <div style={{ flex:1, display:"flex", flexDirection:"column", minWidth:0, background:"var(--paper)" }}>

        {/* 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:20 }}>XP Criteria</div>
            <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)" }}>{list.filter(r=>r.enabled).length} active rules · award points manually or via criteria</div>
          </div>
        </div>

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

          {/* Left: criteria table */}
          <div style={{ display:"flex", flexDirection:"column", gap:16 }}>
            {grouped.map(({ cat, rows }) => (
              <div key={cat} className="card-flat" style={{ padding:0, overflow:"hidden" }}>
                <div style={{ padding:"10px 16px", background: CATEGORY_COLOR[cat] + "22", borderBottom:"var(--border-thin)", display:"flex", alignItems:"center", gap:8 }}>
                  <div style={{ width:8, height:8, borderRadius:"50%", background: CATEGORY_COLOR[cat] }}/>
                  <span className="mono" style={{ fontSize:11, fontWeight:700, letterSpacing:".06em", color:"var(--ink)" }}>{cat.toUpperCase()}</span>
                  {cat === "Difficulty" && (
                    <span style={{ fontSize:11, color:"var(--ink-mute)", marginLeft:4 }}>— bonus XP added on top of completion points</span>
                  )}
                </div>
                <table style={{ width:"100%", borderCollapse:"collapse", fontSize:13 }}>
                  <thead>
                    <tr style={{ textAlign:"left", color:"var(--ink-mute)" }}>
                      {["Criteria","Points","Enabled",""].map(h => (
                        <th key={h} style={{ padding:"8px 14px", fontWeight:600, fontSize:11, borderBottom:"var(--border-thin)" }}>{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {rows.map((row, i) => (
                      <tr key={row.id} style={{ borderTop: i ? "var(--border-thin)" : "none", opacity: row.enabled ? 1 : 0.45 }}>
                        <td style={{ padding:"11px 14px", fontWeight:600 }}>{row.label}</td>
                        <td style={{ padding:"11px 14px", fontFamily:"var(--font-mono)" }}>
                          {editId === row.id ? (
                            <div style={{ display:"flex", gap:6, alignItems:"center" }}>
                              <input
                                type="number" min="1" max="500"
                                value={editPts}
                                onChange={e => setEditPts(e.target.value)}
                                style={{ width:72, padding:"4px 8px", borderRadius:6, border:"var(--border-thin)", background:"var(--paper-deep)", fontSize:13, fontFamily:"var(--font-mono)", color:"var(--ink)", outline:"none" }}
                                autoFocus
                              />
                              <span style={{ color:"var(--ink-mute)", fontSize:12 }}>XP</span>
                              <button onClick={() => saveEdit(row)} disabled={saving} className="btn btn-primary" style={{ padding:"3px 10px", fontSize:11 }}>{saving?"…":"Save"}</button>
                              <button onClick={() => setEditId(null)} className="btn btn-ghost" style={{ padding:"3px 8px", fontSize:11 }}>Cancel</button>
                            </div>
                          ) : (
                            <span style={{ color: CATEGORY_COLOR[cat], fontWeight:700 }}>+{row.points} XP</span>
                          )}
                        </td>
                        <td style={{ padding:"11px 14px" }}>
                          <button
                            onClick={() => toggleEnabled(row)}
                            style={{ width:36, height:20, borderRadius:10, border:"none", cursor:"pointer", position:"relative", padding:0,
                              background: row.enabled ? "var(--moss)" : "var(--rule-bold)", transition:"background .2s" }}>
                            <span style={{ position:"absolute", top:2, left: row.enabled ? 18 : 2, width:16, height:16, borderRadius:"50%", background:"white", transition:"left .2s" }}/>
                          </button>
                        </td>
                        <td style={{ padding:"11px 14px" }}>
                          {editId !== row.id && (
                            <button onClick={() => startEdit(row)} className="btn btn-ghost" style={{ padding:"3px 10px", fontSize:11 }}>Edit pts</button>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            ))}
          </div>

          {/* Right: Award panel + log */}
          <div style={{ display:"flex", flexDirection:"column", gap:16 }}>

            {/* Award form */}
            <div className="card-flat" style={{ padding:20 }}>
              <SectionHead eyebrow="AWARD XP" title="Give points"/>
              <form onSubmit={submitAward}>
                <FormField label="STUDENT">
                  <select required style={selectStyle} value={awardForm.student_id} onChange={e=>setAwardForm(f=>({...f,student_id:e.target.value}))}>
                    <option value="">— select student —</option>
                    {STUDENTS.map(s => <option key={s.id} value={s.id}>{s.name} · {s.xp} XP</option>)}
                  </select>
                </FormField>

                <FormField label="METHOD">
                  <div style={{ display:"flex", gap:8 }}>
                    {[["criteria","From criteria"],["custom","Custom"]].map(([v,l]) => (
                      <button key={v} type="button" onClick={() => setAwardForm(f=>({...f,mode:v,criteria_id:"",custom_reason:"",custom_pts:""}))}
                        style={{ flex:1, padding:"7px 0", borderRadius:8, border:"var(--border-thin)", fontSize:12,
                          background: awardForm.mode===v ? "var(--coral)" : "var(--paper-deep)",
                          color: awardForm.mode===v ? "white" : "var(--ink-soft)", cursor:"pointer", fontWeight:600 }}>
                        {l}
                      </button>
                    ))}
                  </div>
                </FormField>

                {awardForm.mode === "criteria" ? (
                  <>
                    <FormField label="CRITERIA">
                      <select required style={selectStyle} value={awardForm.criteria_id} onChange={e=>setAwardForm(f=>({...f,criteria_id:e.target.value}))}>
                        <option value="">— select criteria —</option>
                        {CATEGORY_ORDER.map(cat => {
                          const rows = list.filter(r => r.category === cat && r.enabled);
                          if (!rows.length) return null;
                          return (
                            <optgroup key={cat} label={cat}>
                              {rows.map(r => <option key={r.id} value={r.id}>{r.label}</option>)}
                            </optgroup>
                          );
                        })}
                      </select>
                    </FormField>
                    {selectedCrit && (
                      <div style={{ padding:"8px 12px", borderRadius:8, background:"var(--paper-deep)", marginBottom:12, display:"flex", alignItems:"center", gap:8 }}>
                        <span style={{ fontWeight:700, color:"var(--moss)", fontFamily:"var(--font-mono)" }}>+{selectedCrit.points} XP</span>
                        <span style={{ fontSize:12, color:"var(--ink-mute)" }}>will be awarded</span>
                      </div>
                    )}
                  </>
                ) : (
                  <>
                    <FormField label="REASON">
                      <input required style={inputStyle} value={awardForm.custom_reason} onChange={e=>setAwardForm(f=>({...f,custom_reason:e.target.value}))} placeholder="e.g. Exceptional effort in class"/>
                    </FormField>
                    <FormField label="POINTS">
                      <input required type="number" min="1" max="500" style={inputStyle} value={awardForm.custom_pts} onChange={e=>setAwardForm(f=>({...f,custom_pts:e.target.value}))} placeholder="e.g. 20"/>
                    </FormField>
                  </>
                )}

                {awardMsg && (
                  <div style={{ color: awardMsg.startsWith("+") ? "var(--moss)" : "var(--coral)", fontSize:13, marginBottom:10, fontWeight:700 }}>{awardMsg}</div>
                )}
                <button type="submit" disabled={awarding} className="btn btn-primary" style={{ width:"100%", padding:"10px 0", fontSize:13 }}>
                  {awarding ? "Awarding…" : "Award XP"}
                </button>
              </form>
            </div>

            {/* Award log */}
            <div className="card-flat" style={{ padding:18 }}>
              <SectionHead eyebrow="RECENT" title="Award log"/>
              {loadA ? <Spinner/> : awardLog.length === 0 ? (
                <div style={{ fontSize:12, color:"var(--ink-mute)", padding:"8px 0" }}>No awards yet.</div>
              ) : (
                <div style={{ display:"flex", flexDirection:"column" }}>
                  {awardLog.slice(0,15).map((a,i) => (
                    <div key={a.id} style={{ display:"flex", alignItems:"flex-start", gap:10, padding:"9px 0", borderTop: i ? "var(--border-thin)" : "none" }}>
                      <div style={{ width:34, height:34, borderRadius:8, background:"var(--moss)", display:"grid", placeItems:"center", flexShrink:0 }}>
                        <span style={{ color:"white", fontSize:11, fontWeight:800, fontFamily:"var(--font-mono)" }}>+{a.points}</span>
                      </div>
                      <div style={{ flex:1, minWidth:0 }}>
                        <div style={{ fontWeight:700, fontSize:13, overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{a.student}</div>
                        <div style={{ fontSize:11, color:"var(--ink-mute)", overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap" }}>{a.reason}</div>
                        <div className="mono" style={{ fontSize:10, color:"var(--ink-mute)", marginTop:2 }}>{fmtTime(a.awarded_at)} · by {a.awarded_by || "system"}</div>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </Themed>
  );
};

window.AdminXPCriteria = AdminXPCriteria;

