/* ============================================================
   HALO SMS — shared UI primitives  (exported to window)
   ============================================================ */
const { useState, useEffect, useRef, createElement: h } = React;

/* ---------------- icons (Lucide-style line glyphs) ---------------- */
const ICONS = {
  dashboard: '<rect width="7" height="9" x="3" y="3" rx="1.5"/><rect width="7" height="5" x="14" y="3" rx="1.5"/><rect width="7" height="9" x="14" y="12" rx="1.5"/><rect width="7" height="5" x="3" y="16" rx="1.5"/>',
  students: '<path d="M22 10v6"/><path d="M2 10l10-5 10 5-10 5z"/><path d="M6 12v5c0 1.7 2.7 3 6 3s6-1.3 6-3v-5"/>',
  staff: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
  users: '<path d="M18 21a6 6 0 0 0-12 0"/><circle cx="12" cy="8" r="4"/>',
  building: '<rect width="16" height="20" x="4" y="2" rx="2"/><path d="M9 22v-4h6v4"/><path d="M8 6h.01M16 6h.01M8 10h.01M16 10h.01M8 14h.01M16 14h.01"/>',
  filetext: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M16 13H8M16 17H8M10 9H8"/>',
  card: '<rect width="20" height="14" x="2" y="5" rx="2.5"/><path d="M2 10h20"/>',
  settings: '<path d="M20 7h-9M14 17H5"/><circle cx="17" cy="17" r="3"/><circle cx="7" cy="7" r="3"/>',
  plug: '<path d="M12 22v-5M9 8V2M15 8V2M18 8H6v4a6 6 0 0 0 12 0z"/>',
  database: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/>',
  shieldcheck: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>',
  clipboard: '<rect width="8" height="4" x="8" y="2" rx="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 11h4M12 16h4M8 11h.01M8 16h.01"/>',
  star: '<path d="M11.5 2.6a.5.5 0 0 1 .9 0l2.5 5 5.5.8a.5.5 0 0 1 .3.85l-4 3.9.95 5.5a.5.5 0 0 1-.73.53L12 17.5l-4.92 2.6a.5.5 0 0 1-.73-.53l.95-5.5-4-3.9a.5.5 0 0 1 .3-.85l5.5-.8z"/>',
  pencil: '<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.4 2.6a2 2 0 0 1 3 3L12 15l-4 1 1-4z"/>',
  calendar: '<path d="M8 2v4M16 2v4"/><rect width="18" height="18" x="3" y="4" rx="2.5"/><path d="M3 10h18"/>',
  bell: '<path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/><path d="M21 16H3s2-1.5 2-7a7 7 0 0 1 14 0c0 5.5 2 7 2 7"/>',
  tag: '<path d="M12.6 2.6A2 2 0 0 0 11.2 2H4a2 2 0 0 0-2 2v7.2a2 2 0 0 0 .6 1.4l8.8 8.8a2 2 0 0 0 2.8 0l6.4-6.4a2 2 0 0 0 0-2.8z"/><circle cx="7.5" cy="7.5" r="1.3"/>',
  chart: '<path d="M3 3v16a2 2 0 0 0 2 2h16"/><path d="M7 15l3-4 3 2 4-6"/>',
  check: '<path d="M20 6 9 17l-5-5"/>',
  search: '<circle cx="11" cy="11" r="7.5"/><path d="m21 21-4.3-4.3"/>',
  plus: '<path d="M5 12h14M12 5v14"/>',
  chevdown: '<path d="m6 9 6 6 6-6"/>',
  chevright: '<path d="m9 18 6-6-6-6"/>',
  chevleft: '<path d="m15 18-6-6 6-6"/>',
  arrowleft: '<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>',
  sun: '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/>',
  moon: '<path d="M12 3a6.5 6.5 0 0 0 9 9 9 9 0 1 1-9-9Z"/>',
  logout: '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/>',
  printer: '<path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 9V2h12v7"/><rect width="12" height="8" x="6" y="14" rx="1"/>',
  filter: '<path d="M3 4h18l-7 8v6l-4 2v-8z"/>',
  x: '<path d="M18 6 6 18M6 6l12 12"/>',
  lock: '<rect width="18" height="11" x="3" y="11" rx="2.5"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
  mail: '<rect width="20" height="16" x="2" y="4" rx="2.5"/><path d="m2 7 10 6 10-6"/>',
  phone: '<path d="M14 2a8 8 0 0 1 8 8M14 6a4 4 0 0 1 4 4M4 4h4l2 5-3 2a13 13 0 0 0 6 6l2-3 5 2v4a2 2 0 0 1-2 2A18 18 0 0 1 2 6a2 2 0 0 1 2-2"/>',
  alert: '<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0"/><path d="M12 9v4M12 17h.01"/>',
  info: '<circle cx="12" cy="12" r="9.5"/><path d="M12 16v-4M12 8h.01"/>',
  upload: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m17 8-5-5-5 5"/><path d="M12 3v12"/>',
  camera: '<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3z"/><circle cx="12" cy="13" r="3.5"/>',
  more: '<circle cx="12" cy="12" r="1.4"/><circle cx="19" cy="12" r="1.4"/><circle cx="5" cy="12" r="1.4"/>',
  trash: '<path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>',
  google: '<path d="M21.5 12.2c0-.7-.06-1.4-.18-2H12v3.8h5.34a4.6 4.6 0 0 1-2 3v2.5h3.24c1.9-1.75 2.92-4.33 2.92-7.3" fill="%234285F4" stroke="none"/>',
  inbox: '<path d="M22 12h-6l-2 3h-4l-2-3H2"/><path d="M5.45 5.1 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.9A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.1"/>',
  graduation: '<path d="M22 9 12 5 2 9l10 4z"/><path d="M6 11v5c0 1 2.7 2.5 6 2.5s6-1.5 6-2.5v-5"/><path d="M22 9v6"/>',
  home: '<path d="m3 10 9-7 9 7v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M9 21v-7h6v7"/>',
  wallet: '<path d="M19 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0 0 4h14a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5"/><path d="M17 13h.01"/>',
  receipt: '<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1z"/><path d="M8 7h8M8 11h8M8 15h5"/>',
  key: '<circle cx="7.5" cy="15.5" r="4.5"/><path d="m21 2-9.6 9.6M15.5 7.5 18 10l3-3-2.5-2.5z"/>',
  shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
  swap: '<path d="m16 3 4 4-4 4"/><path d="M20 7H4"/><path d="m8 21-4-4 4-4"/><path d="M4 17h16"/>',
};
function Icon({ name, style }) {
  const p = ICONS[name] || ICONS.info;
  return h("span", { className: "ic", style },
    h("span", { dangerouslySetInnerHTML: { __html: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${p}</svg>` } }));
}

/* ---------------- primitives ---------------- */
function Avatar({ name, size = 36, variant, src }) {
  const init = (name || "?").split(" ").filter(Boolean).slice(-2).map((w) => w[0]).join("").toUpperCase();
  return h("span", { className: "avatar" + (variant ? " " + variant : ""), style: { width: size, height: size, fontSize: size * 0.4 } }, init);
}

function Button({ kind = "ghost", size, icon, iconRight, children, ...rest }) {
  const cls = `btn btn-${kind}` + (size ? ` btn-${size}` : "") + (rest.block ? " btn-block" : "");
  delete rest.block;
  return h("button", { className: cls, ...rest },
    icon && h(Icon, { name: icon }),
    children != null && h("span", null, children),
    iconRight && h(Icon, { name: iconRight }));
}

const STATE_META = {
  paid: ["chip-ok", "Paid"], partial: ["chip-warn", "Part-paid"], owing: ["chip-bad", "Owing"],
  published: ["chip-ok", "Published"], draft: ["chip-warn", "Draft"], none: ["chip-neutral", "No result"],
  active: ["chip-ok", "Active"], suspended: ["chip-warn", "Suspended"], graduated: ["chip-info", "Graduated"],
  incomplete: ["chip-warn", "Incomplete"],
};
function StatusChip({ state, label, icon }) {
  const [cls, txt] = STATE_META[state] || ["chip-neutral", label || state];
  return h("span", { className: "chip " + cls }, h("span", { className: "d" }), label || txt);
}

function Field({ label, required, hint, error, children, full, span }) {
  return h("div", { className: "field" + (full ? " full" : ""), style: span ? { gridColumn: `span ${span}` } : null },
    label && h("label", null, label, required && h("span", { className: "req" }, " *")),
    children,
    error ? h("div", { className: "errmsg" }, h(Icon, { name: "alert" }), error)
      : hint ? h("div", { className: "hint" }, hint) : null);
}
function Input({ error, lead, ...p }) {
  const inp = h("input", { className: "input" + (error ? " err" : ""), ...p });
  if (lead) return h("div", { className: "inputwrap" }, h("span", { className: "lead" }, lead), inp);
  return inp;
}
function Select({ error, children, ...p }) {
  return h("select", { className: "select" + (error ? " err" : ""), ...p }, children);
}
function Textarea({ error, ...p }) { return h("textarea", { className: "textarea" + (error ? " err" : ""), ...p }); }

function Segmented({ value, onChange, options }) {
  return h("div", { className: "seg" }, options.map((o) =>
    h("button", { key: o.value, className: value === o.value ? "on" : "", onClick: () => onChange(o.value) }, o.label)));
}
function Checkbox({ checked, onChange, label }) {
  return h("label", { className: "checkrow", onClick: (e) => { e.preventDefault(); onChange(!checked); } },
    h("span", { className: "checkbox" + (checked ? " on" : "") }, h(Icon, { name: "check" })),
    label && h("span", { style: { fontSize: 14 } }, label));
}
function Toggle({ on, onChange }) {
  return h("button", { className: "toggle" + (on ? " on" : ""), onClick: () => onChange(!on), "aria-pressed": on, type: "button" }, h("span", { className: "kn" }));
}

/* ---------------- overlays ---------------- */
function Menu({ anchorClass = "", children, onClose, dark, style }) {
  const ref = useRef();
  useEffect(() => {
    const fn = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    const k = (e) => e.key === "Escape" && onClose();
    setTimeout(() => document.addEventListener("mousedown", fn), 0);
    document.addEventListener("keydown", k);
    return () => { document.removeEventListener("mousedown", fn); document.removeEventListener("keydown", k); };
  }, []);
  return h("div", { ref, className: "menu " + anchorClass + (dark ? " dark-on-demo" : ""), style }, children);
}
function MenuItem({ icon, label, sub, selected, onClick }) {
  return h("button", { className: "mitem" + (selected ? " sel" : ""), onClick },
    icon && h(Icon, { name: icon }),
    h("span", { style: { flex: 1 } }, label, sub && h("span", { className: "sub" }, sub)),
    selected && h("span", { className: "tick" }, h(Icon, { name: "check" })));
}

function Modal({ icon, iconTone, title, children, footer, onClose, lg }) {
  useEffect(() => { const k = (e) => e.key === "Escape" && onClose(); document.addEventListener("keydown", k); return () => document.removeEventListener("keydown", k); }, []);
  const tones = { ok: ["var(--ok-bg)", "var(--ok-fg)"], bad: ["var(--bad-bg)", "var(--bad-fg)"], warn: ["var(--warn-bg)", "var(--warn-fg)"], brand: ["var(--brand-soft)", "var(--brand-strong)"] };
  const t = tones[iconTone] || tones.brand;
  return h("div", { className: "scrim", onMouseDown: (e) => e.target === e.currentTarget && onClose() },
    h("div", { className: "modal" + (lg ? " lg" : "") },
      h("div", { className: "mhead" },
        icon && h("div", { className: "micon", style: { background: t[0], color: t[1] } }, h(Icon, { name: icon })),
        h("h2", null, title)),
      children && h("div", { className: "mbody" }, children),
      footer && h("div", { className: "mfoot" }, footer)));
}

function EmptyState({ icon = "inbox", title, children, action, error }) {
  return h("div", { className: "emptystate" + (error ? " errorstate" : "") },
    h("div", { className: "glyph" }, h(Icon, { name: icon })),
    h("h3", null, title),
    children && h("p", null, children),
    action);
}
function Skeleton({ w, h: ht = 14, r, style }) {
  return h("div", { className: "skel", style: { width: w || "100%", height: ht, borderRadius: r, ...style } });
}

/* ---------------- toast host ---------------- */
let _toastFn = null;
function toast(msg, tone = "ok") { _toastFn && _toastFn(msg, tone); }
function ToastHost() {
  const [items, setItems] = useState([]);
  useEffect(() => { _toastFn = (msg, tone) => { const id = Math.random(); setItems((x) => [...x, { id, msg, tone }]); setTimeout(() => setItems((x) => x.filter((i) => i.id !== id)), 3200); }; }, []);
  return h("div", { className: "toaststack" }, items.map((it) =>
    h("div", { key: it.id, className: "toast" },
      h("span", { className: "ic " + (it.tone === "bad" ? "bad" : "ok") }, h(Icon, { name: it.tone === "bad" ? "alert" : "check" })),
      it.msg)));
}

Object.assign(window, {
  Icon, Avatar, Button, StatusChip, Field, Input, Select, Textarea, Segmented, Checkbox, Toggle,
  Menu, MenuItem, Modal, EmptyState, Skeleton, ToastHost, toast,
  HReact: { useState, useEffect, useRef, h },
});
