/* ============================================================
   HALO SMS — Academic structure (57) + Assessment settings (58)
   + Bulk promote (15, carry-over)
   ============================================================ */
(function () {
  const { useState, h } = window.HReact;
  const D = window.HALO;

  /* ---------------- ACADEMIC STRUCTURE ---------------- */
  function AcademicStructure({ navigate }) {
    const [levels, setLevels] = useState(() => D.STRUCTURE.levels.map((l) => ({ ...l, arms: l.arms.slice() })));
    const [depts, setDepts] = useState(D.STRUCTURE.departments.slice());
    const addArm = (li) => setLevels((p) => p.map((l, i) => i === li ? { ...l, arms: [...l.arms, l.name + " " + String.fromCharCode(65 + l.arms.length)] } : l));
    const rmArm = (li, ai) => setLevels((p) => p.map((l, i) => i === li ? { ...l, arms: l.arms.filter((_, j) => j !== ai) } : l));

    return h(window.DesktopScreen, { title: "Academic structure" },
      h("div", { className: "page-pad wide" },
        h(window.PageHead, { eyebrow: "Settings · " + D.STRUCTURE.session, title: "Academic structure", sub: "Pre-filled with Nigerian defaults — edit anything.",
          actions: h(Button, { kind: "primary", icon: "check", onClick: () => toast("Academic structure saved") }, "Save changes") }),
        h("div", { className: "grid-3", style: { marginBottom: 16 } },
          infoTile("Session", D.STRUCTURE.session, "calendar"),
          infoTile("Active term", D.STRUCTURE.activeTerm + " of 3", "filetext"),
          infoTile("Class levels", levels.length + " levels", "building")),
        h("div", { className: "card", style: { marginBottom: 16 } },
          h("div", { className: "card-h" }, h("h3", null, "Terms"), h("span", { className: "muted", style: { fontSize: 12.5 } }, "Three per session")),
          h("div", { className: "card-pad", style: { display: "flex", gap: 10, flexWrap: "wrap" } }, D.STRUCTURE.terms.map((t) =>
            h("div", { key: t, className: "row", style: { gap: 8, padding: "8px 14px", borderRadius: 10, border: "1px solid " + (t === D.STRUCTURE.activeTerm ? "var(--brand)" : "var(--line)"), background: t === D.STRUCTURE.activeTerm ? "var(--brand-soft)" : "var(--surface)" } },
              h("span", { style: { fontWeight: 600, fontSize: 13.5, color: t === D.STRUCTURE.activeTerm ? "var(--brand-strong)" : "inherit" } }, t),
              t === D.STRUCTURE.activeTerm && h("span", { className: "chip chip-ok" }, "Active"))))),
        h("div", { className: "card", style: { marginBottom: 16 } },
          h("div", { className: "card-h" }, h("h3", null, "Class levels & arms"), h(Button, { kind: "ghost", size: "sm", icon: "plus", onClick: () => toast("Add level — pick section") }, "Add level")),
          h("div", null, levels.map((l, li) => h("div", { key: l.id, style: { display: "flex", alignItems: "center", gap: 14, padding: "14px 18px", borderTop: li ? "1px solid var(--line-soft)" : "none", flexWrap: "wrap" } },
            h("div", { style: { width: 150 } }, h("div", { style: { fontWeight: 600, fontSize: 14 } }, l.name), h("div", { className: "muted", style: { fontSize: 11.5 } }, l.section)),
            h("div", { className: "row", style: { gap: 7, flexWrap: "wrap", flex: 1 } }, l.arms.map((a, ai) =>
              h("span", { key: a, className: "row", style: { gap: 6, padding: "5px 6px 5px 11px", borderRadius: 8, background: "var(--surface-2)", border: "1px solid var(--line)", fontSize: 12.5, fontWeight: 500 } }, a,
                h("button", { onClick: () => rmArm(li, ai), className: "iconbtn", style: { width: 20, height: 20, fontSize: 12 } }, h(Icon, { name: "x" })))),
              h("button", { onClick: () => addArm(li), className: "btn btn-quiet btn-sm" }, h(Icon, { name: "plus" }), "Arm")),
            l.dept && h("span", { className: "chip chip-info" }, "Departments")))),
        h("div", { className: "card" },
          h("div", { className: "card-h" }, h("h3", null, "Departments"), h("span", { className: "muted", style: { fontSize: 12.5 } }, "Senior secondary")),
          h("div", { className: "card-pad", style: { display: "flex", gap: 10, flexWrap: "wrap" } }, depts.map((d, i) =>
            h("span", { key: d, className: "row", style: { gap: 6, padding: "7px 7px 7px 13px", borderRadius: 9, background: "var(--surface-2)", border: "1px solid var(--line)", fontSize: 13, fontWeight: 500 } }, d,
              h("button", { onClick: () => setDepts(depts.filter((x) => x !== d)), className: "iconbtn", style: { width: 22, height: 22, fontSize: 12 } }, h(Icon, { name: "x" })))),
            h("button", { onClick: () => toast("Add department"), className: "btn btn-quiet btn-sm" }, h(Icon, { name: "plus" }), "Add"))))));
  }
  function infoTile(label, value, icon) {
    return h("div", { className: "stat" }, h("div", { className: "l" }, h(Icon, { name: icon }), label), h("div", { className: "v", style: { fontSize: 22 } }, value));
  }

  /* ---------------- ASSESSMENT SETTINGS ---------------- */
  function AssessmentSettings({ assess, setAssess }) {
    const a = assess || D.ASSESSMENT;
    const [comps, setComps] = useState(a.components.map((c) => ({ ...c })));
    const [ranking, setRanking] = useState(a.ranking);
    const [threshold, setThreshold] = useState(a.promotionThreshold);
    const sum = comps.reduce((t, c) => t + Number(c.max || 0), 0);
    const setMax = (i, v) => setComps((p) => p.map((c, j) => j === i ? { ...c, max: Number(v.replace(/[^0-9]/g, "") || 0) } : c));

    function save() {
      if (sum !== 100) { toast("Component weights must total 100", "bad"); return; }
      setAssess && setAssess({ ...a, components: comps, ranking, promotionThreshold: threshold });
      toast("Assessment settings saved");
    }
    return h(window.DesktopScreen, { title: "Assessment settings" },
      h("div", { className: "page-pad", style: { maxWidth: 880 } },
        h(window.PageHead, { eyebrow: "Settings", title: "Assessment rules", sub: "How scores combine into grades — applies to new entries.",
          actions: h(Button, { kind: "primary", icon: "check", onClick: save }, "Save settings") }),
        h("div", { className: "card", style: { marginBottom: 16 } },
          h("div", { className: "card-h" }, h("div", null, h("h3", null, "Continuous assessment & exam"), h("div", { className: "sub" }, "Weights must total 100")),
            h("span", { className: "chip " + (sum === 100 ? "chip-ok" : "chip-bad") }, "Total " + sum)),
          h("div", { className: "card-pad", style: { display: "flex", gap: 16, flexWrap: "wrap" } }, comps.map((c, i) =>
            h("div", { key: c.id, className: "field", style: { width: 150 } }, h("label", null, c.name + " max"),
              h(Input, { value: String(c.max), onChange: (e) => setMax(i, e.target.value), error: sum !== 100 }))))),
        h("div", { className: "card", style: { marginBottom: 16 } },
          h("div", { className: "card-h" }, h("h3", null, "Grade bands"), h("span", { className: "muted", style: { fontSize: 12.5 } }, "WAEC-style")),
          h("div", { className: "tablewrap" }, h("table", { className: "data" },
            h("thead", null, h("tr", null, h("th", null, "Grade"), h("th", { className: "num" }, "From (min %)"), h("th", null, "Remark"))),
            h("tbody", null, a.gradeBands.map((b, i) => h("tr", { key: b.grade, style: { cursor: "default" } },
              h("td", null, h("span", { style: { fontWeight: 700, fontFamily: "var(--fs-display)" } }, b.grade)),
              h("td", { className: "num" }, h(Input, { value: String(b.min), style: { width: 80, display: "inline-block" } })),
              h("td", null, b.remark)))))),
        h("div", { className: "grid-2" },
          h("div", { className: "card", style: { padding: 18 } },
            h("div", { className: "row", style: { justifyContent: "space-between" } },
              h("div", null, h("div", { style: { fontWeight: 600, fontSize: 14.5 } }, "Competition ranking"), h("div", { className: "muted", style: { fontSize: 12.5, marginTop: 3 } }, "Show class positions on report sheets")),
              h(Toggle, { on: ranking, onChange: setRanking }))),
          h("div", { className: "card", style: { padding: 18 } },
            h("div", { style: { fontWeight: 600, fontSize: 14.5 } }, "Promotion threshold"),
            h("div", { className: "muted", style: { fontSize: 12.5, margin: "3px 0 12px" } }, "Cumulative average to be promoted"),
            h("div", { className: "row", style: { gap: 12 } },
              h("input", { type: "range", min: 30, max: 70, value: threshold, onChange: (e) => setThreshold(Number(e.target.value)), style: { flex: 1 } }),
              h("span", { style: { fontFamily: "var(--fs-display)", fontWeight: 800, fontSize: 22, width: 48, className: "tnum" } }, threshold + "%")))))));
  }

  /* ---------------- BULK PROMOTE ---------------- */
  const NEXT = { "Primary 4": "Primary 5", "JSS 1A": "JSS 2A", "JSS 2B": "JSS 3B", "SS2 Science": "SS3 Science", "SS3 Arts": "Graduated" };
  function BulkPromote({ navigate, students, assess, upsertStudent }) {
    const threshold = (assess || D.ASSESSMENT).promotionThreshold;
    const [arm, setArm] = useState("JSS 1A");
    const roster = D.rosterForArm(arm, students);
    const [decisions, setDecisions] = useState({});
    const [confirm, setConfirm] = useState(false);
    const rec = (s) => s.avg == null ? "review" : s.avg >= threshold ? "promote" : "repeat";
    const decision = (s) => decisions[s.id] || rec(s);
    const next = NEXT[arm] || "Next class";
    const promoting = roster.filter((s) => decision(s) === "promote").length;

    return h(window.DesktopScreen, { title: "Bulk promote" },
      h("div", { className: "page-pad wide" },
        h(window.PageHead, { eyebrow: "End of session", title: "Bulk promotion", sub: "System recommends from cumulative average vs " + threshold + "% — override per student.",
          actions: h(Button, { kind: "primary", icon: "graduation", onClick: () => setConfirm(true) }, "Apply promotions") }),
        h("div", { className: "card", style: { padding: 16, marginBottom: 14, display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap" } },
          h("div", { className: "field", style: { gap: 4 } }, h("label", { style: { fontSize: 12 } }, "Promote from"),
            h("select", { className: "select", style: { width: 180, height: 40 }, value: arm, onChange: (e) => setArm(e.target.value) }, Object.keys(NEXT).map((a) => h("option", { key: a }, a)))),
          h(Icon, { name: "chevright", style: { color: "var(--ink-400)" } }),
          h("div", { style: { padding: "8px 14px", borderRadius: 10, background: "var(--brand-soft)", color: "var(--brand-strong)", fontWeight: 600, fontSize: 14 } }, next),
          h("div", { style: { flex: 1 } }),
          h("div", { className: "muted", style: { fontSize: 13 } }, h("b", { style: { color: "var(--ok-fg)" } }, promoting), " of " + roster.length + " promoting")),
        h("div", { className: "card" },
          h("div", { className: "tablewrap" }, h("table", { className: "data" },
            h("thead", null, h("tr", null, h("th", null, "Student"), h("th", { className: "num" }, "Cumulative avg"), h("th", null, "Recommendation"), h("th", null, "Decision"))),
            h("tbody", null, roster.map((s) => h("tr", { key: s.id, style: { cursor: "default" } },
              h("td", null, h("div", { className: "cellname" }, h(Avatar, { name: s.first + " " + s.surname, size: 30 }), h("div", null, h("div", { className: "nm", style: { fontSize: 13.5 } }, s.surname + ", " + s.first)))),
              h("td", { className: "num", style: { fontWeight: 600 } }, s.avg != null ? s.avg.toFixed(1) : "—"),
              h("td", null, recChip(rec(s))),
              h("td", null, h(Segmented, { value: decision(s), onChange: (v) => setDecisions((p) => ({ ...p, [s.id]: v })), options: [{ value: "promote", label: "Promote" }, { value: "repeat", label: "Repeat" }] }))))))),
        confirm && h(window.ConfirmModal, { icon: "graduation", tone: "warn", title: "Apply promotions for " + arm,
          body: promoting + " students will move to " + next + " and " + (roster.length - promoting) + " will repeat " + arm + ". This is audit-logged and reversible by an admin.",
          confirmLabel: "Apply promotions", onClose: () => setConfirm(false),
          onConfirm: () => { toast(promoting + " students promoted to " + next); setConfirm(false); } }))));
  }
  function recChip(r) {
    if (r === "promote") return h("span", { className: "chip chip-ok" }, h(Icon, { name: "check" }), "Promote");
    if (r === "repeat") return h("span", { className: "chip chip-warn" }, h("span", { className: "d" }), "Repeat");
    return h("span", { className: "chip chip-neutral" }, h("span", { className: "d" }), "Review");
  }

  window.AcademicStructure = AcademicStructure;
  window.AssessmentSettings = AssessmentSettings;
  window.BulkPromote = BulkPromote;
})();
