/* Eno.Health Console — Platform Administrators: manage console operators of the back-end */
const AD = window.ENO;

function adminRoleLabel(id) { return (AD.ADMIN_ROLES.find((r) => r.id === id) || {}).label || id; }
function adminRoleTone(id) { return id === "owner" ? "accent" : id === "admin" ? "purple" : "neutral"; }
function adminStatusPill(s) {
  if (s === "active") return h(Pill, { tone: "ok", soft: true }, "active");
  if (s === "invited") return h(Pill, { tone: "warn", soft: true }, "invited");
  return h(Pill, { tone: "neutral", soft: true }, "disabled");
}

function PlatformAdminsView() {
  const toast = useToast();
  const [admins, setAdmins] = useState(() => AD.PLATFORM_ADMINS.map((a) => ({ ...a })));
  const [q, setQ] = useState("");
  const [roleFilter, setRoleFilter] = useState("all");
  const [editing, setEditing] = useState(null);   // { isNew, ...admin }
  const [removing, setRemoving] = useState(null);

  const ownerCount = admins.filter((a) => a.role === "owner" && a.status !== "disabled").length;
  const activeAdmins = admins.filter((a) => a.status === "active");
  const mfaOn = activeAdmins.filter((a) => a.mfa).length;
  const mfaPct = activeAdmins.length ? Math.round((mfaOn / activeAdmins.length) * 100) : 100;
  const pending = admins.filter((a) => a.status === "invited").length;

  const rows = admins.filter((a) =>
    (roleFilter === "all" || a.role === roleFilter) &&
    (!q.trim() || (a.name + " " + a.email).toLowerCase().includes(q.trim().toLowerCase())));

  const isLastOwner = (a) => a.role === "owner" && ownerCount <= 1;

  const save = (data) => {
    if (data.isNew) {
      const id = "adm_" + (data.email.split("@")[0] || Math.random().toString(16).slice(2, 8)).replace(/[^a-z0-9]+/gi, "_").toLowerCase();
      const initials = data.name.trim().split(/\s+/).map((w) => w[0]).slice(0, 2).join("").toUpperCase() || "?";
      setAdmins((xs) => [...xs, { id, name: data.name.trim(), email: data.email.trim(), role: data.role, cells: data.cells.trim() || "all", status: "invited", mfa: false, lastActive: null, createdMin: 0, initials }]);
      toast("Invitation sent to " + data.email.trim(), "ok");
    } else {
      setAdmins((xs) => xs.map((a) => a.id === data.id ? { ...a, name: data.name.trim(), email: data.email.trim(), role: data.role, cells: data.cells.trim() || "all", mfa: data.mfa } : a));
      toast("“" + data.name.trim() + "” updated", "ok");
    }
    setEditing(null);
  };
  const toggleStatus = (a) => {
    if (a.self) return toast("You can't disable your own account");
    if (a.status === "active" && isLastOwner(a)) return toast("At least one active owner is required");
    setAdmins((xs) => xs.map((x) => x.id === a.id ? { ...x, status: x.status === "disabled" ? "active" : "disabled" } : x));
    toast(a.status === "disabled" ? "“" + a.name + "” re-enabled" : "“" + a.name + "” disabled");
  };
  const resend = (a) => toast("Invitation re-sent to " + a.email, "ok");
  const toggleMfa = (a) => {
    setAdmins((xs) => xs.map((x) => x.id === a.id ? { ...x, mfa: !x.mfa } : x));
    toast(a.mfa ? "2FA disabled for “" + a.name + "”" : "2FA enabled for “" + a.name + "”", a.mfa ? undefined : "ok");
  };
  const remove = (a) => {
    setAdmins((xs) => xs.filter((x) => x.id !== a.id));
    toast("“" + a.name + "” removed from administrators");
    setRemoving(null);
  };

  const head = ["Administrator", "Role", "Cells", "2FA", "Last active", "Status", ""];
  return h("div", { className: "view" },
    h(PageHead, { title: "Platform Administrators",
      sub: "People who can sign in to this management console — not tenant users",
      right: h(Button, { variant: "primary", size: "sm", icon: "plus", onClick: () => setEditing({ isNew: true, name: "", email: "", role: "operator", cells: "all" }) }, "Invite administrator") }),
    h("div", { className: "ref-banner" }, h(Icon, { name: "shield", size: 16, className: "dim" }),
      h("div", null, "Administrators have owner-scoped access to the back-end platform. Grant the ", h("strong", null, "least privilege"), " needed, require 2FA, and keep at least one active ", h("strong", null, "Owner"), ".")),
    h("div", { className: "stat-grid stat-grid-4" },
      h(Card, { pad: false }, h(Stat, { label: "Administrators", value: admins.length, icon: "tenants" })),
      h(Card, { pad: false }, h(Stat, { label: "Owners", value: ownerCount, icon: "key" })),
      h(Card, { pad: false }, h(Stat, { label: "2FA coverage", value: mfaPct, unit: "%", tone: mfaPct === 100 ? "ok" : "warn", icon: "lock" })),
      h(Card, { pad: false }, h(Stat, { label: "Pending invites", value: pending, icon: "clock" }))),
    h(Card, { pad: false, title: "Administrators", subtitle: "Console operators across all regional cells" },
      h("div", { className: "toolbar" },
        h("div", { className: "search" }, h(Icon, { name: "search", size: 16 }),
          h("input", { className: "search-input", placeholder: "Search by name or email…", value: q, onChange: (e) => setQ(e.target.value) })),
        h(Select, { value: roleFilter, onChange: setRoleFilter,
          options: [{ value: "all", label: "All roles" }].concat(AD.ADMIN_ROLES.map((r) => ({ value: r.id, label: r.label }))) }),
        h("span", { className: "toolbar-count" }, rows.length, " of ", admins.length)),
      h("div", { className: "table-wrap flush" },
        h("table", { className: "table" },
          h("thead", null, h("tr", null, head.map((c, i) => h("th", { key: i, className: i === 6 ? "ta-r" : "" }, c)))),
          h("tbody", null,
            rows.map((a) => h("tr", { key: a.id },
              h("td", null, h("div", { className: "user-cell" },
                h(Avatar, { initials: a.initials, size: 30, tone: a.status === "disabled" ? "neutral" : "accent" }),
                h("div", { className: "user-cell-meta" },
                  h("div", { className: "user-cell-name" }, a.name, a.self ? h("span", { className: "self-badge" }, "You") : null),
                  h("div", { className: "dim mono small" }, a.email)))),
              h("td", null, h(Pill, { tone: adminRoleTone(a.role), soft: true }, adminRoleLabel(a.role))),
              h("td", null, a.cells === "all" ? h("span", { className: "tag" }, "All cells") : h("span", { className: "dim mono small" }, a.cells)),
              h("td", null, h("button", { className: "mfa-toggle" + (a.mfa ? " on" : ""), title: a.mfa ? "2FA enabled — click to disable" : "2FA disabled — click to enable", onClick: () => toggleMfa(a) },
                h(Icon, { name: a.mfa ? "lock" : "alert", size: 13 }), a.mfa ? "On" : "Off")),
              h("td", { className: "dim" }, a.lastActive == null ? (a.status === "invited" ? "never" : "—") : fmtAgo(AD.ago(a.lastActive))),
              h("td", null, adminStatusPill(a.status)),
              h("td", { className: "ta-r" },
                h("div", { className: "row-actions" },
                  a.status === "invited" && h("button", { className: "mini-btn", title: "Resend invitation", onClick: () => resend(a) }, h(Icon, { name: "refresh", size: 15 })),
                  h("button", { className: "mini-btn", title: "Edit administrator", onClick: () => setEditing({ isNew: false, ...a }) }, h(Icon, { name: "edit", size: 15 })),
                  h("button", { className: "mini-btn", title: a.self ? "You can't disable yourself" : (a.status === "disabled" ? "Re-enable" : "Disable"), disabled: a.self, onClick: () => toggleStatus(a) },
                    h(Icon, { name: a.status === "disabled" ? "check" : "lock", size: 15 })),
                  h("button", { className: "mini-btn danger", title: a.self ? "You can't remove yourself" : (isLastOwner(a) ? "At least one owner is required" : "Remove"), disabled: a.self || isLastOwner(a), onClick: () => setRemoving(a) }, h(Icon, { name: "trash", size: 15 })))))),
            !rows.length && h("tr", null, h("td", { colSpan: 7 }, h(Empty, { icon: "tenants", title: "No administrators", sub: "Adjust your search or filter." })))))),
      h(RoleLegend, null)),
    h(AdminEditorModal, { data: editing, roles: AD.ADMIN_ROLES, onClose: () => setEditing(null), onSave: save }),
    h(Modal, { open: !!removing, onClose: () => setRemoving(null), title: "Remove administrator", width: 460,
      footer: removing && h(React.Fragment, null,
        h(Button, { variant: "ghost", onClick: () => setRemoving(null) }, "Cancel"),
        h(Button, { variant: "danger", icon: "trash", onClick: () => remove(removing) }, "Remove access")) },
      removing && h("div", { className: "mform" },
        h("p", { style: { margin: 0 } }, "Revoke console access for ", h("strong", null, removing.name), " (", h("span", { className: "mono" }, removing.email), ")? They will be signed out immediately and can only return by re-invitation."),
        h("p", { className: "mform-note" }, h(Icon, { name: "info", size: 14 }), "This does not affect any tenant or patient data."))));
}

function RoleLegend() {
  return h("div", { className: "role-legend" },
    AD.ADMIN_ROLES.map((r) => h("div", { className: "role-legend-item", key: r.id },
      h(Pill, { tone: adminRoleTone(r.id), soft: true }, r.label),
      h("span", { className: "dim small" }, r.desc))));
}

function AdminEditorModal({ data, roles, onClose, onSave }) {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [role, setRole] = useState("operator");
  const [cells, setCells] = useState("all");
  const [mfa, setMfa] = useState(false);
  useEffect(() => { if (data) { setName(data.name || ""); setEmail(data.email || ""); setRole(data.role || "operator"); setCells(data.cells || "all"); setMfa(!!data.mfa); } }, [data]);
  if (!data) return null;
  const badEmail = !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email.trim());
  const valid = name.trim() && !badEmail;
  const roleDesc = (roles.find((r) => r.id === role) || {}).desc;
  const submit = () => { if (valid) onSave({ isNew: data.isNew, id: data.id, name, email, role, cells, mfa }); };
  return h(Modal, { open: true, onClose, title: data.isNew ? "Invite administrator" : "Edit administrator", width: 520,
    footer: h(React.Fragment, null,
      h(Button, { variant: "ghost", onClick: onClose }, "Cancel"),
      h(Button, { variant: "primary", icon: data.isNew ? "plus" : "check", disabled: !valid, onClick: submit }, data.isNew ? "Send invitation" : "Save changes")) },
    h("div", { className: "mform" },
      h("div", { className: "mform-2" },
        h(Field, { label: "Full name" },
          h("input", { className: "input", autoFocus: true, value: name, placeholder: "e.g. Lukas Vermeulen", onChange: (e) => setName(e.target.value) })),
        h(Field, { label: "Work email", hint: badEmail && email ? "Enter a valid email address." : "" },
          h("input", { className: "input mono", type: "email", value: email, placeholder: "name@eno.health", onChange: (e) => setEmail(e.target.value) }))),
      h(Field, { label: "Role", hint: roleDesc },
        h(Select, { value: role, onChange: setRole, options: roles.map((r) => ({ value: r.id, label: r.label })) })),
      h(Field, { label: "Cell access", hint: "Which regional cells this administrator can operate (e.g. eu-be, eu-nl) — or all cells" },
        h("input", { className: "input", value: cells, placeholder: "all", onChange: (e) => setCells(e.target.value) })),
      !data.isNew && h(Field, { label: "Two-factor authentication", hint: mfa ? "Required at every sign-in for this administrator." : "Not enforced — this account can sign in with a password alone." },
        h("div", { className: "mfa-field" },
          h(Toggle, { on: mfa, onChange: setMfa, label: "Two-factor authentication" }),
          h("span", { className: "mfa-field-state" + (mfa ? " on" : "") }, mfa ? "Enabled" : "Disabled"))),
      data.isNew && h("p", { className: "mform-note" }, h(Icon, { name: "lock", size: 14 }), "The administrator sets a password and enables 2FA when they accept the invitation.")));
}

Object.assign(window, { PlatformAdminsView, SettingsView });

/* ======================================================================== */
/* SETTINGS — platform configuration (LLM, …)                                */
/* ======================================================================== */
const SETTINGS_LS = "eno_settings";
function loadSettings() {
  try { return JSON.parse(localStorage.getItem(SETTINGS_LS)) || {}; } catch { return {}; }
}
function saveSettings(s) {
  try { localStorage.setItem(SETTINGS_LS, JSON.stringify(s)); } catch {}
}
const SETTINGS_DEFAULTS = { bmLoincMinConfidence: 85 };

function SettingsView() {
  const [tab, setTab] = useState("llm");
  const tabs = [{ key: "llm", label: "LLM" }];
  return h("div", { className: "view" },
    h(PageHead, { title: "Settings", sub: "Platform configuration" }),
    h(Tabs, { tabs, active: tab, onChange: setTab }),
    h("div", { className: "tabbody" },
      tab === "llm" ? h(LlmSettings, null) : null));
}

function LlmSettings() {
  const toast = useToast();
  const [stored, setStored] = useState(() => ({ ...SETTINGS_DEFAULTS, ...loadSettings() }));
  const [minConf, setMinConf] = useState(stored.bmLoincMinConfidence);
  const dirty = minConf !== stored.bmLoincMinConfidence;

  const clamp = (v) => Math.max(50, Math.min(100, Math.round(v) || 0));
  const setVal = (v) => setMinConf(clamp(v));

  const belowCount = AD.BIOMARKERS.filter((b) => (b.confidence ?? 100) < minConf).length;
  const total = AD.BIOMARKERS.length;

  const save = () => {
    const next = { ...stored, bmLoincMinConfidence: minConf };
    saveSettings(next); setStored(next);
    toast("Minimum confidence saved · " + minConf + "%", "ok");
  };
  const reset = () => setMinConf(stored.bmLoincMinConfidence);

  return h(React.Fragment, null,
    h("div", { className: "ref-banner" }, h(Icon, { name: "sparkles", size: 16, className: "dim" }),
      h("div", null, "Thresholds that govern how the extraction model maps observations onto the knowledge base. ",
        "Mappings at or above the threshold are accepted automatically; anything below is routed to manual review.")),
    h(Card, { pad: false, title: "Biomarker → LOINC mapping", subtitle: "Minimum confidence the model must reach to auto-accept a mapping" },
      h("div", { className: "set-block" },
        h("div", { className: "set-row" },
          h("div", { className: "set-row-label" },
            h("div", { className: "set-row-title" }, "Minimum confidence score"),
            h("div", { className: "set-row-desc" }, "When the model links an extracted biomarker to a LOINC code with confidence below this value, the mapping is held for an administrator to confirm.")),
          h("div", { className: "set-conf" },
            h("input", { className: "set-range", type: "range", min: 50, max: 100, step: 1, value: minConf, onChange: (e) => setVal(e.target.value) }),
            h("div", { className: "set-conf-val" },
              h("input", { className: "input set-num", type: "number", min: 50, max: 100, value: minConf, onChange: (e) => setVal(e.target.value) }),
              h("span", { className: "set-conf-pct" }, "%")))),
        h("div", { className: "set-scale" },
          h("span", null, "50% · permissive"),
          h("span", null, "100% · strict")),
        h("div", { className: "set-impact" }, h(Icon, { name: "info", size: 14 }),
          h("div", null, "At ", h("strong", null, minConf + "%"), ", ", h("strong", null, belowCount),
            " of ", total, " current biomarkers would fall below the threshold and route to review.")),
        h("div", { className: "set-actions" },
          h(Button, { variant: "ghost", disabled: !dirty, onClick: reset }, "Reset"),
          h(Button, { variant: "primary", icon: "check", disabled: !dirty, onClick: save }, "Save changes")))));
}
