/* ============================================================
   HALO SMS — Roles & access + custom role builder (Batch 1)
   ============================================================ */
(function () {
  const { useState, h } = window.HReact;
  const D = window.HALO;

  const countStaff = (roleId, staffList) => (staffList || []).filter((s) => s.roles.includes(roleId)).length;

  /* ---------------- LIST ---------------- */
  function RolesList({ navigate, roles, staffList }) {
    return h("div", { className: "page-pad wide" },
      h(PageHead, { eyebrow: "Access control", title: "Roles & access", sub: roles.length + " roles · permissions from a fixed catalog",
        actions: h(Button, { kind: "primary", icon: "plus", onClick: () => navigate("roles:new") }, "Create custom role") }),
      h("div", { className: "grid-3" }, roles.map((r) =>
        h("button", { key: r.id, onClick: () => navigate("roles:detail:" + r.id), style: { textAlign: "left", padding: 0, border: "none", background: "none" } },
          h("div", { className: "card", style: { padding: 18, height: "100%", display: "flex", flexDirection: "column", gap: 10 } },
            h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" } },
              h("div", { style: { width: 38, height: 38, borderRadius: 10, background: "var(--brand-soft)", color: "var(--brand-strong)", display: "grid", placeItems: "center" } }, h(Icon, { name: r.predefined ? "shield" : "key" })),
              r.predefined ? h("span", { className: "tag" }, "Predefined") : h("span", { className: "chip chip-info" }, "Custom")),
            h("div", null, h("div", { style: { fontFamily: "var(--fs-display)", fontWeight: 700, fontSize: 17 } }, r.name),
              h("div", { className: "muted", style: { fontSize: 13, marginTop: 4, lineHeight: 1.45 } }, r.desc)),
            h("div", { style: { flex: 1 } }),
            h("div", { className: "row", style: { justifyContent: "space-between", borderTop: "1px solid var(--line-soft)", paddingTop: 11 } },
              h("span", { className: "muted", style: { fontSize: 12.5 } }, r.perms.length + " permissions"),
              h("span", { className: "muted", style: { fontSize: 12.5 } }, countStaff(r.id, staffList) + " staff"))))) ));
  }

  /* ---------------- DETAIL ---------------- */
  function RoleDetail({ role: r, navigate, staffList }) {
    const assigned = (staffList || []).filter((s) => s.roles.includes(r.id));
    return h("div", { className: "page-pad" },
      h(Button, { kind: "quiet", icon: "arrowleft", onClick: () => navigate("roles"), style: { marginBottom: 16 } }, "All roles"),
      h("div", { className: "card", style: { marginBottom: 16 } },
        h("div", { style: { display: "flex", gap: 18, padding: 22, alignItems: "flex-start", flexWrap: "wrap" } },
          h("div", { style: { width: 56, height: 56, borderRadius: 14, background: "var(--brand-soft)", color: "var(--brand-strong)", display: "grid", placeItems: "center", fontSize: 24 } }, h(Icon, { name: r.predefined ? "shield" : "key" })),
          h("div", { style: { flex: 1, minWidth: 200 } },
            h("h1", { style: { fontSize: 25 } }, r.name),
            h("div", { className: "muted", style: { fontSize: 14, marginTop: 5, maxWidth: 520, lineHeight: 1.5 } }, r.desc),
            h("div", { className: "row", style: { gap: 8, marginTop: 12 } }, r.predefined ? h("span", { className: "tag" }, "Predefined") : h("span", { className: "chip chip-info" }, "Custom role"),
              h("span", { className: "chip chip-neutral" }, r.perms.length + " permissions"), h("span", { className: "chip chip-neutral" }, assigned.length + " staff"))),
          r.predefined
            ? h(Button, { kind: "ghost", icon: "plus", onClick: () => navigate("roles:clone:" + r.id) }, "Duplicate to customise")
            : h(Button, { kind: "primary", icon: "pencil", onClick: () => navigate("roles:edit:" + r.id) }, "Edit role"))),
      h("div", { style: { display: "grid", gridTemplateColumns: "1.6fr 1fr", gap: 16, alignItems: "start" }, className: "det-cols" },
        h("div", { className: "card" },
          h("div", { className: "card-h" }, h("h3", null, "Permissions"), h("span", { className: "muted", style: { fontSize: 12.5 } }, r.perms.length + " of " + D.ALL_PERMS.length)),
          h("div", { className: "card-pad", style: { display: "flex", flexDirection: "column", gap: 16 } },
            Object.keys(D.PERMISSIONS).map((grp) => { const granted = D.PERMISSIONS[grp].filter((p) => r.perms.includes(p[0])); if (!granted.length) return null;
              return h("div", { key: grp },
                h("div", { className: "eyebrow", style: { marginBottom: 8 } }, grp),
                h("div", { className: "row", style: { gap: 7, flexWrap: "wrap" } }, granted.map((p) => h("span", { key: p[0], className: "chip chip-ok" }, h(Icon, { name: "check" }), p[1])))); }))),
        h("div", { className: "card" },
          h("div", { className: "card-h" }, h("h3", null, "Assigned staff"), h("span", { className: "muted", style: { fontSize: 12.5 } }, "Scoped to data they own")),
          h("div", null, assigned.length === 0
            ? h("div", { className: "card-pad" }, h("span", { className: "muted", style: { fontSize: 13.5 } }, "No staff currently hold this role."))
            : assigned.map((s, i) => h("div", { key: s.id, onClick: () => navigate("staff:detail:" + s.id), style: { display: "flex", alignItems: "center", gap: 11, padding: "12px 18px", borderTop: i ? "1px solid var(--line-soft)" : "none", cursor: "pointer" } },
                h(Avatar, { name: s.first + " " + s.surname, size: 32 }),
                h("div", { style: { flex: 1 } }, h("div", { style: { fontWeight: 600, fontSize: 13.5 } }, s.first + " " + s.surname), h("div", { className: "muted", style: { fontSize: 12 } }, s.classTeacherOf || s.title)),
                h(Icon, { name: "chevright", style: { color: "var(--ink-400)" } })))))));
  }

  /* ---------------- BUILDER ---------------- */
  function RoleBuilder({ existing, clone, navigate, onSave }) {
    const seed = existing || clone;
    const [name, setName] = useState(seed ? (clone ? seed.name + " (copy)" : seed.name) : "");
    const [desc, setDesc] = useState(seed ? seed.desc : "");
    const [perms, setPerms] = useState(() => new Set(seed ? seed.perms : []));
    const [err, setErr] = useState("");
    const isEdit = !!existing;
    const has = (k) => perms.has(k);
    const toggle = (k) => { const n = new Set(perms); n.has(k) ? n.delete(k) : n.add(k); setPerms(n); };
    const toggleGroup = (grp, on) => { const n = new Set(perms); D.PERMISSIONS[grp].forEach((p) => on ? n.add(p[0]) : n.delete(p[0])); setPerms(n); };
    function submit() { if (!name.trim()) { setErr("Give the role a name"); return; } if (perms.size === 0) { toast("Select at least one permission", "bad"); return; } onSave({ id: isEdit ? existing.id : "role-" + Date.now().toString(36), name, desc, predefined: false, perms: [...perms] }); }

    return h("div", { className: "page-pad", style: { maxWidth: 920 } },
      h(PageHead, { back: { label: "Back to roles", onClick: () => navigate("roles") },
        eyebrow: isEdit ? "Edit role" : "Custom role builder", title: isEdit ? "Edit " + existing.name : "Create a custom role",
        actions: h(React.Fragment, null, h(Button, { kind: "ghost", onClick: () => navigate("roles") }, "Cancel"), h(Button, { kind: "primary", icon: "check", onClick: submit }, isEdit ? "Save role" : "Create role")) }),
      h("div", { className: "card", style: { marginBottom: 16, padding: 22 } },
        h("div", { className: "formgrid" },
          Fld("Role name", { req: true, error: err }, h(Input, { value: name, onChange: (e) => { setName(e.target.value); setErr(""); }, error: !!err, placeholder: "e.g. Exam officer" })),
          Fld("Short description", {}, h(Input, { value: desc, onChange: (e) => setDesc(e.target.value), placeholder: "What this role is for" })))),
      h("div", { className: "card" },
        h("div", { className: "card-h" }, h("div", null, h("h3", null, "Permissions"), h("div", { className: "sub" }, "Pick from the permission catalog — grouped by domain")),
          h("span", { className: "chip chip-info" }, perms.size + " selected")),
        h("div", { className: "card-pad", style: { display: "flex", flexDirection: "column", gap: 6 } },
          Object.keys(D.PERMISSIONS).map((grp) => { const items = D.PERMISSIONS[grp]; const all = items.every((p) => has(p[0])); const some = items.some((p) => has(p[0]));
            return h("div", { key: grp, style: { borderBottom: "1px solid var(--line-soft)", padding: "12px 0" } },
              h("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 10 } },
                h("div", { className: "eyebrow", style: { color: some ? "var(--brand-strong)" : "var(--ink-500)" } }, grp),
                h("button", { onClick: () => toggleGroup(grp, !all), style: { border: "none", background: "none", color: "var(--brand)", fontSize: 12.5, fontWeight: 600 } }, all ? "Clear all" : "Select all")),
              h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, className: "perm-grid" }, items.map((p) =>
                h("label", { key: p[0], className: "checkrow", style: { padding: "7px 9px", borderRadius: 9, border: "1px solid " + (has(p[0]) ? "var(--brand)" : "var(--line)"), background: has(p[0]) ? "var(--brand-soft)" : "var(--surface)" }, onClick: (e) => { e.preventDefault(); toggle(p[0]); } },
                  h("span", { className: "checkbox" + (has(p[0]) ? " on" : "") }, h(Icon, { name: "check" })),
                  h("span", { style: { fontSize: 13, fontWeight: 500, flex: 1 } }, p[1]),
                  h("span", { className: "mono", style: { fontSize: 10.5, color: "var(--ink-400)" } }, p[0]))))); }))),
      h("div", { style: { display: "flex", justifyContent: "flex-end", gap: 10, padding: "20px 0" } },
        h(Button, { kind: "ghost", onClick: () => navigate("roles") }, "Cancel"),
        h(Button, { kind: "primary", icon: "check", onClick: submit }, isEdit ? "Save role" : "Create role")));
  }

  /* ---------------- ROUTER ---------------- */
  function Roles({ params, navigate, roles, upsertRole, staffList }) {
    const [p0, p1] = params;
    let view;
    if (p0 === "new") view = h(RoleBuilder, { navigate, onSave: (r) => { upsertRole(r); toast("Role created"); navigate("roles:detail:" + r.id); } });
    else if (p0 === "edit") { const r = roles.find((x) => x.id === p1); view = h(RoleBuilder, { existing: r, navigate, onSave: (rr) => { upsertRole(rr); toast("Role saved"); navigate("roles:detail:" + rr.id); } }); }
    else if (p0 === "clone") { const r = roles.find((x) => x.id === p1); view = h(RoleBuilder, { clone: r, navigate, onSave: (rr) => { upsertRole(rr); toast("Custom role created"); navigate("roles:detail:" + rr.id); } }); }
    else if (p0 === "detail") { const r = roles.find((x) => x.id === p1); view = r ? h(RoleDetail, { role: r, navigate, staffList }) : h("div", { className: "page-pad" }, h(EmptyState, { icon: "alert", title: "Role not found", action: h(Button, { kind: "ghost", onClick: () => navigate("roles") }, "Back") })); }
    else view = h(RolesList, { navigate, roles, staffList });
    return h(window.DesktopScreen, { title: "Roles & access" }, view);
  }

  window.Roles = Roles;
})();
