/* ============================================================
   HALO SMS — Student vertical slice
   list -> admit -> detail -> edit  (report sheet in report.jsx)
   ============================================================ */
(function () {
  const { useState, useEffect, h } = window.HReact;
  const D = window.HALO;

  /* ---------------- LIST ---------------- */
  function StudentsList({ navigate, roster, canEdit }) {
    const [q, setQ] = useState("");
    const [cls, setCls] = useState("all");
    const [view, setView] = useState("data"); // data | loading | empty | error
    const [booting, setBooting] = useState(true);
    useEffect(() => { const t = setTimeout(() => setBooting(false), 750); return () => clearTimeout(t); }, []);

    const filtered = roster.filter((s) =>
      (cls === "all" || s.cls === cls) &&
      (q === "" || (s.first + " " + s.surname + " " + s.adm).toLowerCase().includes(q.toLowerCase())));

    const showLoading = booting || view === "loading";
    const showError = view === "error";
    const showEmpty = !showLoading && !showError && filtered.length === 0;

    return h("div", { className: "page-pad wide" },
      h("div", { style: { display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, marginBottom: 20, flexWrap: "wrap" } },
        h("div", null,
          h("div", { className: "eyebrow", style: { marginBottom: 7 } }, "People · " + D.session),
          h("h1", { style: { fontSize: 27 } }, "Students"),
          h("div", { className: "muted", style: { fontSize: 13.5, marginTop: 4 } }, roster.length + " enrolled across " + D.CLASSES.length + " classes")),
        canEdit && h("div", { className: "wrap-actions" },
          h(Button, { kind: "ghost", icon: "upload", onClick: () => navigate("students:import") }, "Bulk import"),
          h(Button, { kind: "primary", icon: "plus", onClick: () => navigate("students:new") }, "Admit student"))),

      h("div", { className: "card" },
        h("div", { style: { display: "flex", alignItems: "center", gap: 12, padding: "14px 16px", borderBottom: "1px solid var(--line)", flexWrap: "wrap" } },
          h("div", { className: "searchbox", style: { flex: 1, minWidth: 200, maxWidth: 340 } },
            h(Icon, { name: "search" }),
            h("input", { placeholder: "Search name or admission no.", value: q, onChange: (e) => setQ(e.target.value) })),
          h("select", { className: "select", style: { width: "auto", height: 38 }, value: cls, onChange: (e) => setCls(e.target.value) },
            h("option", { value: "all" }, "All classes"),
            D.CLASSES.map((c) => h("option", { key: c, value: c }, c))),
          h("div", { style: { flex: 1 } }),
          h("div", { className: "row", style: { gap: 8 } },
            h("span", { className: "eyebrow noprint", title: "Prototype control" }, "Preview state"),
            h("select", { className: "select noprint", style: { width: "auto", height: 34, fontSize: 12.5 }, value: view, onChange: (e) => setView(e.target.value) },
              h("option", { value: "data" }, "Data"), h("option", { value: "loading" }, "Loading"),
              h("option", { value: "empty" }, "Empty"), h("option", { value: "error" }, "Error")))),

        showLoading ? h(LoadingRows)
        : showError ? h("div", { style: { padding: 8 } }, h(EmptyState, { error: true, icon: "alert", title: "Couldn't load students",
            action: h(Button, { kind: "ghost", icon: "swap", onClick: () => setView("data") }, "Try again") },
            "The server didn't respond. Check your connection and try again — your filters are still applied."))
        : (showEmpty || view === "empty") ? h("div", { style: { padding: 8 } }, h(EmptyState, { icon: "students", title: q || cls !== "all" ? "No students match" : "No students yet",
            action: q || cls !== "all"
              ? h(Button, { kind: "ghost", onClick: () => { setQ(""); setCls("all"); setView("data"); } }, "Clear filters")
              : canEdit && h(Button, { kind: "primary", icon: "plus", onClick: () => navigate("students:new") }, "Admit your first student") },
            q || cls !== "all" ? "Try a different name, admission number, or class." : "Admitted students will appear here. Start by admitting one, or bulk-import a class list."))
        : h("div", { className: "tablewrap" },
            h("table", { className: "data" },
              h("thead", null, h("tr", null,
                h("th", null, "Student"), h("th", null, "Class"), h("th", null, "Admission no."),
                h("th", null, "Fees"), h("th", null, "Result"), h("th", null, "Status"))),
              h("tbody", null, filtered.map((s) =>
                h("tr", { key: s.id, onClick: () => navigate("students:detail:" + s.id) },
                  h("td", null, h("div", { className: "cellname" },
                    h(Avatar, { name: s.first + " " + s.surname, size: 34 }),
                    h("div", null, h("div", { className: "nm" }, s.surname + ", " + s.first),
                      h("div", { className: "sub" }, s.gender + " · " + s.state)))),
                  h("td", null, s.cls + (s.department !== "—" ? "" : "")),
                  h("td", null, h("span", { className: "mono", style: { fontSize: 12.5 } }, s.adm)),
                  h("td", null, h(FeeMini, { s })),
                  h("td", null, h(StatusChip, { state: s.results })),
                  h("td", null, h(StatusChip, { state: s.lifecycle.toLowerCase() })))))))));
  }

  function FeeMini({ s }) {
    const st = D.feeStatus(s); const pct = Math.round(s.fee.paid / s.fee.total * 100);
    return h("div", { style: { display: "flex", alignItems: "center", gap: 9, minWidth: 130 } },
      h("div", { className: "bar", style: { width: 56 } }, h("i", { className: st === "paid" ? "paid" : "part", style: { width: pct + "%" } })),
      h(StatusChip, { state: st }));
  }
  function LoadingRows() {
    return h("div", { style: { padding: "6px 0" } },
      [0,1,2,3,4,5].map((i) => h("div", { key: i, style: { display: "flex", alignItems: "center", gap: 14, padding: "13px 16px", borderBottom: "1px solid var(--line-soft)" } },
        h(Skeleton, { w: 34, h: 34, r: 99 }),
        h("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: 7 } }, h(Skeleton, { w: "32%", h: 12 }), h(Skeleton, { w: "20%", h: 10 })),
        h(Skeleton, { w: 80, h: 12 }), h(Skeleton, { w: 90, h: 22, r: 99 }), h(Skeleton, { w: 70, h: 22, r: 99 }))));
  }

  /* ---------------- DETAIL ---------------- */
  function KV({ k, v }) { return h("div", { className: "kv" }, h("span", { className: "k" }, k), h("span", { className: "v" }, v || "—")); }
  function Block({ title, action, cols = 3, children }) {
    return h("div", { className: "card", style: { marginBottom: 16 } },
      h("div", { className: "card-h" }, h("h3", null, title), action),
      h("div", { className: "card-pad", style: { display: "grid", gridTemplateColumns: `repeat(${cols},1fr)`, gap: 18 } }, children));
  }

  function StudentDetail({ student, navigate, canEdit, onLifecycle }) {
    const [menu, setMenu] = useState(false);
    const g = D.guardians[student.guardian];
    const st = D.feeStatus(student);
    const pct = Math.round(student.fee.paid / student.fee.total * 100);
    const full = [student.surname, student.first, student.middle].filter(Boolean).join(" ");

    return h("div", { className: "page-pad" },
      h(Button, { kind: "quiet", icon: "arrowleft", onClick: () => navigate("students"), style: { marginBottom: 16 } }, "All students"),
      // header
      h("div", { className: "card", style: { marginBottom: 16, overflow: "visible" } },
        h("div", { style: { display: "flex", gap: 20, padding: 22, alignItems: "flex-start", flexWrap: "wrap" } },
          h(Avatar, { name: student.first + " " + student.surname, size: 72 }),
          h("div", { style: { flex: 1, minWidth: 200 } },
            h("h1", { style: { fontSize: 26 } }, full),
            h("div", { className: "muted", style: { fontSize: 13.5, marginTop: 5, display: "flex", gap: 10, flexWrap: "wrap", alignItems: "center" } },
              h("span", { className: "mono" }, student.adm), h("span", null, "·"), student.cls,
              student.department !== "—" && h("span", null, "· " + student.department)),
            h("div", { className: "row", style: { gap: 8, marginTop: 12, flexWrap: "wrap" } },
              h(StatusChip, { state: student.lifecycle.toLowerCase() }),
              h(StatusChip, { state: st }),
              h(StatusChip, { state: student.results }))),
          h("div", { className: "row", style: { gap: 8, position: "relative" } },
            h(Button, { kind: "ghost", icon: "filetext", onClick: () => navigate("students:report:" + student.id) }, "Report sheet"),
            canEdit && h(Button, { kind: "primary", icon: "pencil", onClick: () => navigate("students:edit:" + student.id) }, "Edit"),
            canEdit && h(Button, { kind: "ghost", icon: "more", onClick: () => setMenu(!menu) }),
            menu && h(Menu, { anchorClass: "", style: { right: 0, top: 46 }, onClose: () => setMenu(false) },
              h("div", { className: "mlabel" }, "Lifecycle actions"),
              h(MenuItem, { icon: "lock", label: "Suspend student", onClick: () => { setMenu(false); onLifecycle("Suspend", student); } }),
              h(MenuItem, { icon: "graduation", label: "Mark graduated", onClick: () => { setMenu(false); onLifecycle("Graduate", student); } }),
              h(MenuItem, { icon: "swap", label: "Transfer out", onClick: () => { setMenu(false); onLifecycle("Transfer", student); } }),
              h("div", { className: "mdiv" }),
              h(MenuItem, { icon: "alert", label: "Expel / withdraw", onClick: () => { setMenu(false); onLifecycle("Expel", student); } })))),
        h("div", { className: "divider" }),
        h("div", { style: { padding: "10px 22px", fontSize: 12, color: "var(--ink-500)", display: "flex", gap: 7, alignItems: "center" } },
          h(Icon, { name: "shield", style: { fontSize: 13 } }), "Last updated by ", h("b", { style: { fontWeight: 600, color: "var(--ink-700)" } }, "Mrs. Folake Adebayo"), " · 2 days ago")),

      h("div", { style: { display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 16, alignItems: "start" }, className: "det-cols" },
        h("div", null,
          h(Block, { title: "Bio & identity" },
            h(KV, { k: "Surname", v: student.surname }), h(KV, { k: "First name", v: student.first }), h(KV, { k: "Middle name", v: student.middle }),
            h(KV, { k: "Preferred name", v: student.preferred }), h(KV, { k: "Gender", v: student.gender }), h(KV, { k: "Date of birth", v: fmtDate(student.dob) }),
            h(KV, { k: "Nationality", v: student.nationality }), h(KV, { k: "Religion", v: student.religion }), h(KV, { k: "State / LGA", v: student.state + " · " + student.lga })),
          h(Block, { title: "Academic placement" },
            h(KV, { k: "Class · arm", v: student.cls }), h(KV, { k: "Department", v: student.department }), h(KV, { k: "Admission type", v: student.admType || student.admissionType }),
            h(KV, { k: "Admission date", v: fmtDate(student.admDate) }), h(KV, { k: "Admission no.", v: h("span", { className: "mono", style: { fontSize: 13 } }, student.adm) }), h(KV, { k: "Lifecycle", v: student.lifecycle })),
          h(Block, { title: "Contact & medical" },
            h(KV, { k: "Home address", v: student.address }), h(KV, { k: "Blood group", v: student.bloodGroup }), h(KV, { k: "Genotype", v: student.genotype }),
            h(KV, { k: "Allergies", v: "None recorded" }), h(KV, { k: "Special needs", v: "None" }), h(KV, { k: "Emergency", v: g ? g.phone : "—" })),
          h(Block, { title: "Guardians", cols: 1 },
            g ? h("div", { style: { display: "flex", alignItems: "center", gap: 13 } },
              h(Avatar, { name: g.name, size: 42, variant: "accent" }),
              h("div", { style: { flex: 1 } }, h("div", { style: { fontWeight: 600, fontSize: 14.5 } }, g.name),
                h("div", { className: "muted", style: { fontSize: 12.5 } }, g.rel + " · " + g.phone + " · " + g.email)),
              student.primary && h("span", { className: "chip chip-info" }, h(Icon, { name: "wallet" }), "Primary payer"))
              : h("span", { className: "muted" }, "No guardian linked"))),
        h("div", null,
          h("div", { className: "card", style: { marginBottom: 16 } },
            h("div", { className: "card-h" }, h("h3", null, "Fees"), h(StatusChip, { state: st })),
            h("div", { className: "card-pad" },
              h("div", { style: { display: "flex", alignItems: "baseline", gap: 8, marginBottom: 4 } },
                h("span", { className: "naira", style: { fontFamily: "var(--fs-display)", fontWeight: 800, fontSize: 28 } }, D.fmt(student.fee.total - student.fee.paid)),
                h("span", { className: "muted", style: { fontSize: 13 } }, "outstanding")),
              h("div", { className: "muted", style: { fontSize: 13, marginBottom: 14 } }, D.fmt(student.fee.paid) + " paid of " + D.fmt(student.fee.total)),
              h("div", { className: "bar" }, h("i", { className: st === "paid" ? "paid" : "part", style: { width: pct + "%" } })),
              h("div", { style: { marginTop: 16, display: "flex", flexDirection: "column", gap: 9 } },
                ["Tuition","Development levy","Books & materials"].map((it, i) =>
                  h("div", { key: it, style: { display: "flex", justifyContent: "space-between", fontSize: 13.5 } },
                    h("span", { className: "muted" }, it), h("span", { className: "naira" }, D.fmt([110000,45000,30000][i] || 0))))))),
          h("div", { className: "card" },
            h("div", { className: "card-h" }, h("h3", null, D.term + " result"), h(StatusChip, { state: student.results })),
            h("div", { className: "card-pad" },
              student.results === "none"
                ? h("div", { className: "muted", style: { fontSize: 13.5, lineHeight: 1.5 } }, "No result has been recorded for this term yet.")
                : h("div", null,
                    h("div", { style: { display: "flex", gap: 22, marginBottom: 14 } },
                      h("div", { className: "kv" }, h("span", { className: "k" }, "Term avg"), h("span", { style: { fontFamily: "var(--fs-display)", fontWeight: 800, fontSize: 24 }, className: "tnum" }, student.avg != null ? student.avg.toFixed(1) : "—")),
                      h("div", { className: "kv" }, h("span", { className: "k" }, "Position"), h("span", { style: { fontFamily: "var(--fs-display)", fontWeight: 800, fontSize: 24 }, className: "tnum" }, student.position ? student.position + "/" + student.ofN : "—"))),
                    h(Button, { kind: "ghost", block: true, icon: "filetext", onClick: () => navigate("students:report:" + student.id) }, "Open report sheet")))))));
  }

  /* ---------------- FORM (admit / edit) ---------------- */
  const blank = () => ({ surname: "", first: "", middle: "", preferred: "", gender: "Female", dob: "", nationality: "Nigerian",
    religion: "Christianity", cls: "JSS 1A", department: "—", admissionType: "New", admDate: new Date().toISOString().slice(0,10),
    state: "Lagos", lga: "", address: "", phone: "", bloodGroup: "O+", genotype: "AA", allergies: "", special: "",
    prevSchool: "", lastClass: "", reason: "", gName: "", gRel: "Mother", gPhone: "", gEmail: "", primary: true });

  function StudentForm({ existing, navigate, onSave }) {
    const isEdit = !!existing;
    const [d, setD] = useState(() => existing ? { ...blank(), ...existing, gName: (D.guardians[existing.guardian]||{}).name || "" } : blank());
    const [err, setErr] = useState({});
    const set = (k) => (e) => setD({ ...d, [k]: e && e.target ? e.target.value : e });
    const senior = d.cls.startsWith("SS");

    function submit() {
      const e = {};
      ["surname","first"].forEach((k) => { if (!d[k].trim()) e[k] = "Required"; });
      if (!d.dob) e.dob = "Enter date of birth";
      if (!d.state) e.state = "Select a state";
      if (d.admissionType === "Transfer" && !d.prevSchool.trim()) e.prevSchool = "Required for transfers";
      setErr(e);
      if (Object.keys(e).length) { toast("Please fix the highlighted fields", "bad"); return; }
      onSave(d, isEdit);
    }

    return h("div", { className: "page-pad", style: { maxWidth: 920 } },
      h(Button, { kind: "quiet", icon: "arrowleft", onClick: () => navigate(isEdit ? "students:detail:" + existing.id : "students"), style: { marginBottom: 14 } }, isEdit ? "Cancel edit" : "Back to students"),
      h("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-end", gap: 16, marginBottom: 8, flexWrap: "wrap" } },
        h("div", null,
          h("div", { className: "eyebrow", style: { marginBottom: 7 } }, isEdit ? "Edit record" : "New admission"),
          h("h1", { style: { fontSize: 27 } }, isEdit ? d.first + " " + d.surname : "Admit a student")),
        h("div", { className: "row noprint" }, h(Button, { kind: "ghost", onClick: () => navigate(isEdit ? "students:detail:" + existing.id : "students") }, "Cancel"),
          h(Button, { kind: "primary", icon: "check", onClick: submit }, isEdit ? "Save changes" : "Admit student"))),

      h("div", { className: "card", style: { marginTop: 18, padding: "4px 24px" } },
        sec("01", "Bio & identity", "The student's legal name and personal details.",
          h("div", { className: "formgrid" },
            fld("Surname", true, err.surname, h(Input, { value: d.surname, onChange: set("surname"), error: err.surname, placeholder: "Adebayo" })),
            fld("First name", true, err.first, h(Input, { value: d.first, onChange: set("first"), error: err.first, placeholder: "Chidinma" })),
            fld("Middle name", false, null, h(Input, { value: d.middle, onChange: set("middle") })),
            fld("Preferred name", false, "Optional — used in greetings", h(Input, { value: d.preferred, onChange: set("preferred") })),
            fld("Gender", true, null, h(Segmented, { value: d.gender, onChange: set("gender"), options: [{ value: "Female", label: "Female" }, { value: "Male", label: "Male" }] })),
            fld("Date of birth", true, err.dob, h(Input, { type: "date", value: d.dob, onChange: set("dob"), error: err.dob })),
            fld("Nationality", false, null, h(Input, { value: d.nationality, onChange: set("nationality") })),
            fld("Religion", false, null, h(Select, { value: d.religion, onChange: set("religion") }, ["Christianity","Islam","Traditional","Other"].map((o) => h("option", { key: o }, o)))))),

        sec("02", "Academic placement", "Where the student sits in the school structure. Admission number is generated automatically.",
          h("div", { className: "formgrid" },
            fld("Class & arm", true, null, h(Select, { value: d.cls, onChange: set("cls") }, D.CLASSES.map((c) => h("option", { key: c }, c)))),
            senior && fld("Department", false, null, h(Select, { value: d.department === "—" ? "Science" : d.department, onChange: set("department") }, ["Science","Arts","Commercial"].map((o) => h("option", { key: o }, o)))),
            fld("Admission type", false, null, h(Segmented, { value: d.admissionType, onChange: set("admissionType"), options: [{ value: "New", label: "New" }, { value: "Transfer", label: "Transfer" }] })),
            fld("Admission date", false, null, h(Input, { type: "date", value: d.admDate, onChange: set("admDate") })),
            fld("Admission number", false, "Auto-generated from settings", h(Input, { value: isEdit ? d.adm : "BFA/2025/02" + Math.floor(10 + Math.random() * 89), disabled: true })))),

        sec("03", "Contact & origin", "Address and the Nigerian-specific fields schools report on.",
          h("div", { className: "formgrid" },
            fld("State of origin", true, err.state, h(Select, { value: d.state, onChange: set("state"), error: err.state }, D.STATES.map((o) => h("option", { key: o }, o)))),
            fld("L.G.A.", false, null, h(Input, { value: d.lga, onChange: set("lga"), placeholder: "Ikeja" })),
            fld("Home address", false, null, h(Input, { value: d.address, onChange: set("address"), placeholder: "14 Adeniyi Jones Ave, Ikeja" }), "full"),
            fld("Phone (optional)", false, null, h(Input, { value: d.phone, onChange: set("phone"), lead: "+234", placeholder: "803 000 0000" })))),

        sec("04", "Medical", "Kept private — visible to admins and the school nurse only.",
          h("div", { className: "formgrid" },
            fld("Blood group", false, null, h(Select, { value: d.bloodGroup, onChange: set("bloodGroup") }, ["O+","O-","A+","A-","B+","B-","AB+","AB-"].map((o) => h("option", { key: o }, o)))),
            fld("Genotype", false, null, h(Select, { value: d.genotype, onChange: set("genotype") }, ["AA","AS","SS","AC"].map((o) => h("option", { key: o }, o)))),
            fld("Allergies / conditions", false, null, h(Input, { value: d.allergies, onChange: set("allergies"), placeholder: "None" }), "full"),
            fld("Disabilities / special needs", false, null, h(Input, { value: d.special, onChange: set("special"), placeholder: "None" }), "full"))),

        d.admissionType === "Transfer" && sec("05", "Prior school", "Required because this is a transfer admission.",
          h("div", { className: "formgrid" },
            fld("Previous school", true, err.prevSchool, h(Input, { value: d.prevSchool, onChange: set("prevSchool"), error: err.prevSchool })),
            fld("Last class completed", false, null, h(Input, { value: d.lastClass, onChange: set("lastClass"), placeholder: "JSS 1" })),
            fld("Reason for transfer", false, null, h(Textarea, { value: d.reason, onChange: set("reason") }), "full"))),

        sec(d.admissionType === "Transfer" ? "06" : "05", "Guardian link", "Attach a parent or guardian. One contact is the primary payer.",
          h("div", { className: "formgrid" },
            fld("Guardian full name", false, null, h(Input, { value: d.gName, onChange: set("gName"), placeholder: "Mrs. Folake Adebayo" })),
            fld("Relationship", false, null, h(Select, { value: d.gRel, onChange: set("gRel") }, ["Mother","Father","Uncle","Aunt","Grandparent","Legal guardian"].map((o) => h("option", { key: o }, o)))),
            fld("Phone", false, null, h(Input, { value: d.gPhone, onChange: set("gPhone"), lead: "+234" })),
            fld("Email", false, null, h(Input, { value: d.gEmail, onChange: set("gEmail"), type: "email" })),
            h("div", { className: "field full" }, h(Checkbox, { checked: d.primary, onChange: set("primary"), label: "Primary contact & default payer — receives SMS and appears first in the child switcher" })))),

        sec(d.admissionType === "Transfer" ? "07" : "06", "Documents", "Upload supporting files. You can also add these later.",
          h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 14 }, className: "formgrid" },
            ["Birth certificate","Passport photo","Previous results"].map((doc) => h(Dropzone, { key: doc, label: doc })))),

        h("div", { style: { display: "flex", justifyContent: "flex-end", gap: 10, padding: "20px 0" }, className: "noprint" },
          h(Button, { kind: "ghost", onClick: () => navigate(isEdit ? "students:detail:" + existing.id : "students") }, "Cancel"),
          h(Button, { kind: "primary", icon: "check", onClick: submit }, isEdit ? "Save changes" : "Admit student"))));
  }

  function sec(step, title, desc, body) {
    return h("div", { className: "formsec" },
      h("div", { className: "secinfo" }, h("div", { className: "step" }, "STEP " + step), h("h3", { style: { marginTop: 4 } }, title), h("p", null, desc)),
      h("div", null, body));
  }
  function fld(label, req, error, control, mod) {
    return h(Field, { label, required: req, error: typeof error === "string" ? error : null, hint: typeof error === "string" ? null : error, full: mod === "full" }, control);
  }
  function Dropzone({ label }) {
    const [done, setDone] = useState(false);
    return h("button", { type: "button", onClick: () => { setDone(true); toast(label + " attached"); },
      style: { border: "1.5px dashed var(--line)", borderRadius: 12, background: done ? "var(--ok-bg)" : "var(--surface-2)", padding: "20px 14px",
        display: "flex", flexDirection: "column", alignItems: "center", gap: 8, color: done ? "var(--ok-fg)" : "var(--ink-500)", textAlign: "center" } },
      h(Icon, { name: done ? "check" : "upload", style: { fontSize: 20 } }),
      h("span", { style: { fontSize: 13, fontWeight: 600 } }, label),
      h("span", { style: { fontSize: 11.5 } }, done ? "Attached" : "Click to upload"));
  }

  function fmtDate(d) { if (!d) return "—"; return new Date(d).toLocaleDateString("en-NG", { day: "numeric", month: "short", year: "numeric" }); }

  /* ---------------- ROUTER ---------------- */
  function Students({ params, navigate, roster, upsertStudent, canEdit }) {
    const [lc, setLc] = useState(null); // lifecycle modal {action, student}
    const onLifecycle = (action, student) => setLc({ action, student });
    const [p0, p1] = params;
    if (p0 === "import") return h(window.BulkImport, { entity: "students", navigate, onDone: () => navigate("students") });

    let view;
    if (p0 === "new") view = h(StudentForm, { navigate, onSave: (d, isEdit) => { const s = commit(d, isEdit, upsertStudent); toast("Student admitted"); navigate("students:detail:" + s.id); } });
    else if (p0 === "edit") { const s = D.studentById(p1) || roster.find((x) => x.id === p1); view = h(StudentForm, { existing: s, navigate, onSave: (d, isEdit) => { commit(d, isEdit, upsertStudent); toast("Changes saved"); navigate("students:detail:" + s.id); } }); }
    else if (p0 === "detail") { const s = roster.find((x) => x.id === p1); view = s ? h(StudentDetail, { student: s, navigate, canEdit, onLifecycle }) : h("div", { className: "page-pad" }, h(EmptyState, { icon: "alert", title: "Student not found", action: h(Button, { kind: "ghost", onClick: () => navigate("students") }, "Back to list") })); }
    else if (p0 === "report") { const s = roster.find((x) => x.id === p1); view = s ? h(window.ReportSheet, { student: s, role: "staff", onBack: () => navigate("students:detail:" + s.id) }) : null; }
    else view = h(StudentsList, { navigate, roster, canEdit });

    return h("div", null, view,
      lc && h(LifecycleModal, { ...lc, onClose: () => setLc(null), onConfirm: (reason) => {
        upsertStudent({ ...lc.student, lifecycle: lc.action === "Suspend" ? "Suspended" : lc.action === "Graduate" ? "Graduated" : lc.action === "Transfer" ? "Transferred" : "Expelled" });
        toast(lc.student.first + " " + lc.student.surname + " — " + lc.action.toLowerCase() + (lc.action.endsWith("e") ? "d" : "ed")); setLc(null); } }));
  }

  function commit(d, isEdit, upsert) {
    const id = isEdit ? d.id : "st-" + Math.floor(1000 + Math.random() * 8999);
    const adm = isEdit ? d.adm : "BFA/2025/02" + Math.floor(10 + Math.random() * 89);
    const s = Object.assign({}, d, { id, adm, fee: d.fee || { total: 185000, paid: 0 }, results: d.results || "none",
      lifecycle: d.lifecycle || "Active", ofN: d.ofN || 30, guardian: d.guardian || null, admType: d.admissionType });
    if (d.gName && !s.guardian) { const gid = "g-" + id; D.guardians[gid] = { id: gid, name: d.gName, rel: d.gRel, phone: d.gPhone, email: d.gEmail, occupation: "", address: d.address, children: [id] }; s.guardian = gid; s.primary = d.primary; }
    upsert(s); return s;
  }

  function LifecycleModal({ action, student, onClose, onConfirm }) {
    const [reason, setReason] = useState("");
    const danger = action === "Expel";
    return h(Modal, { icon: danger ? "alert" : "swap", iconTone: danger ? "bad" : "warn", title: action + " " + student.first + " " + student.surname,
      onClose,
      footer: h(React.Fragment, null,
        h(Button, { kind: "ghost", onClick: onClose }, "Cancel"),
        h(Button, { kind: danger ? "danger" : "primary", disabled: !reason.trim(), onClick: () => onConfirm(reason) }, "Confirm " + action.toLowerCase())) },
      h("p", { style: { fontSize: 14, color: "var(--ink-600)", marginBottom: 14, lineHeight: 1.55 } },
        "This changes the student's lifecycle state to ", h("b", null, action === "Suspend" ? "Suspended" : action === "Graduate" ? "Graduated" : action === "Transfer" ? "Transferred" : "Expelled"),
        ". It's audit-logged and reversible by an admin."),
      h(Field, { label: "Reason", required: true, hint: "Recorded against this action in the audit log" },
        h(Textarea, { value: reason, onChange: (e) => setReason(e.target.value), placeholder: "e.g. Relocated to another state" })));
  }

  window.Students = Students;
})();
