/* Eno.Health Console — shared UI primitives. Exposes components on window. */
const { useState, useEffect, useRef, useMemo, createElement: h } = React;

/* ---- Icons (simple stroke set) ------------------------------------------ */
const ICON_PATHS = {
  overview: "M3 3h7v7H3zM14 3h7v4h-7zM14 10h7v11h-7zM3 14h7v7H3z",
  documents: "M6 2h8l4 4v16H6zM14 2v4h4",
  runs: "M3 12h4l3 8 4-16 3 8h4",
  activity: "M3 12h3.5l2-7 4.5 14 2.5-9 1.5 2h4",
  upload: "M12 16V4M7 9l5-5 5 5M5 20h14",
  policies: "M12 2l8 4v6c0 5-3.5 8-8 10-4.5-2-8-5-8-10V6z",
  retention: "M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14",
  webhooks: "M9 7a4 4 0 1 1 5 5M15 17a4 4 0 1 1-5-5M7 12l-3 4M17 12l3 4",
  tenants: "M9 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM3 20c0-3 3-5 6-5s6 2 6 5M17 11a3 3 0 0 0 0-6M21 20c0-2-1.5-3.5-3.5-4.2",
  search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.3-4.3",
  bell: "M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0",
  chevron: "M6 9l6 6 6-6",
  chevronL: "M15 6l-6 6 6 6",
  chevronR: "M9 6l6 6-6 6",
  check: "M20 6L9 17l-5-5",
  x: "M18 6L6 18M6 6l12 12",
  alert: "M12 9v4M12 17h.01M10.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 0z",
  clock: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2",
  dot: "M12 12h.01",
  external: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3",
  refresh: "M21 12a9 9 0 1 1-3-6.7L21 8M21 3v5h-5",
  shield: "M12 2l8 4v6c0 5-3.5 8-8 10-4.5-2-8-5-8-10V6z",
  play: "M5 3l14 9-14 9z",
  pause: "M6 4h4v16H6zM14 4h4v16h-4z",
  filter: "M3 4h18l-7 8v6l-4 2v-8z",
  sort: "M7 4v16M4 7l3-3 3 3M17 20V4M14 17l3 3 3-3",
  copy: "M9 9h11v11H9zM5 15H4V4h11v1",
  arrowRight: "M5 12h14M13 6l6 6-6 6",
  logout: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9",
  trash: "M3 6h18M8 6V4h8v2M6 6l1 14h10l1-14",
  plus: "M12 5v14M5 12h14",
  database: "M12 8c4.4 0 8-1.3 8-3s-3.6-3-8-3-8 1.3-8 3 3.6 3 8 3zM4 5v14c0 1.7 3.6 3 8 3s8-1.3 8-3V5M4 12c0 1.7 3.6 3 8 3s8-1.3 8-3",
  scan: "M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2M3 12h18",
  lock: "M5 11h14v10H5zM8 11V7a4 4 0 1 1 8 0v4",
  spinner: "M12 2v4M12 18v4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M2 12h4M18 12h4M4.9 19.1l2.8-2.8M16.3 7.7l2.8-2.8",
  beaker: "M9 3h6M10 3v6l-5.4 9.3A1.8 1.8 0 0 0 6.2 21h11.6a1.8 1.8 0 0 0 1.6-2.7L14 9V3M8 14h8",
  hash: "M4 9h16M4 15h16M10 3 8 21M16 3l-2 18",
  link: "M9 7a4 4 0 0 1 0 8h-1M15 17a4 4 0 0 1 0-8h1M8 12h8",
  sparkles: "M12 3l1.8 4.8L18.6 9l-4.8 1.2L12 15l-1.8-4.8L5.4 9l4.8-1.2zM19 14l.9 2.4 2.4.9-2.4.9L19 21l-.9-2.8-2.4-.9 2.4-.9z",
  download: "M12 3v12M7 10l5 5 5-5M5 21h14",
  sheet: "M4 3h16v18H4zM4 9h16M4 15h16M10 3v18",
};
function Icon({ name, size = 18, className = "", style = {} }) {
  const d = ICON_PATHS[name] || ICON_PATHS.dot;
  return h("svg", {
    className: "icon " + className, width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round",
    strokeLinejoin: "round", style,
  }, h("path", { d }));
}

/* ---- Status pill --------------------------------------------------------- */
function Pill({ tone = "neutral", children, dot = true, soft = true }) {
  return h("span", { className: `pill pill-${tone}${soft ? " pill-soft" : ""}` },
    dot && h("span", { className: "pill-dot" }), children);
}
function StatusPill({ status }) {
  return h(Pill, { tone: status.tone }, status.label);
}

/* ---- Buttons ------------------------------------------------------------- */
function Button({ variant = "default", size = "md", icon, iconRight, children, className = "", ...rest }) {
  return h("button", { className: `btn btn-${variant} btn-${size} ${className}`, ...rest },
    icon && h(Icon, { name: icon, size: size === "sm" ? 15 : 16 }),
    children && h("span", null, children),
    iconRight && h(Icon, { name: iconRight, size: size === "sm" ? 15 : 16 }));
}

/* ---- Card ---------------------------------------------------------------- */
function Card({ title, subtitle, actions, children, pad = true, className = "" }) {
  return h("section", { className: "card " + className },
    (title || actions) && h("div", { className: "card-head" },
      h("div", null,
        title && h("h3", { className: "card-title" }, title),
        subtitle && h("p", { className: "card-sub" }, subtitle)),
      actions && h("div", { className: "card-actions" }, actions)),
    h("div", { className: pad ? "card-body" : "" }, children));
}

/* ---- Stat tile ----------------------------------------------------------- */
function Stat({ label, value, unit, delta, tone, spark, icon }) {
  return h("div", { className: "stat" },
    h("div", { className: "stat-top" },
      h("span", { className: "stat-label" }, label),
      icon && h(Icon, { name: icon, size: 16, className: "stat-icon" })),
    h("div", { className: "stat-value" }, value,
      unit && h("span", { className: "stat-unit" }, unit)),
    delta && h("div", { className: `stat-delta ${tone || ""}` }, delta),
    spark && h(Sparkline, { data: spark, tone }));
}

/* ---- Sparkline + bars ---------------------------------------------------- */
function Sparkline({ data, tone = "accent", height = 32, fill = true }) {
  const w = 120, h2 = height, max = Math.max(...data, 1), min = Math.min(...data, 0);
  const rng = max - min || 1;
  const pts = data.map((v, i) => [i / (data.length - 1) * w, h2 - ((v - min) / rng) * (h2 - 4) - 2]);
  const line = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const area = line + ` L${w} ${h2} L0 ${h2} Z`;
  const col = `var(--${tone})`;
  return h("svg", { className: "spark", viewBox: `0 0 ${w} ${h2}`, preserveAspectRatio: "none", width: "100%", height: h2 },
    fill && h("path", { d: area, fill: col, opacity: 0.1 }),
    h("path", { d: line, fill: "none", stroke: col, strokeWidth: 1.8 }));
}
function MiniBars({ data, tone = "accent", height = 36 }) {
  const max = Math.max(...data, 1);
  return h("div", { className: "minibars", style: { height } },
    data.map((v, i) => h("span", {
      key: i, className: "minibar",
      style: { height: `${(v / max) * 100}%`, background: `var(--${tone})` },
    })));
}

/* ---- Progress ------------------------------------------------------------ */
function Bar({ value, max = 100, tone = "accent", height = 7, segments }) {
  if (segments) {
    const total = segments.reduce((a, s) => a + s.value, 0) || 1;
    return h("div", { className: "bar", style: { height } },
      segments.map((s, i) => h("span", {
        key: i, className: "bar-fill",
        style: { width: `${(s.value / total) * 100}%`, background: `var(--${s.tone})` },
        title: `${s.label}: ${s.value}`,
      })));
  }
  return h("div", { className: "bar", style: { height } },
    h("span", { className: "bar-fill", style: { width: `${Math.min(100, (value / max) * 100)}%`, background: `var(--${tone})` } }));
}

/* ---- Tabs ---------------------------------------------------------------- */
function Tabs({ tabs, active, onChange }) {
  return h("div", { className: "tabs" },
    tabs.map((t) => h("button", {
      key: t.key, className: "tab" + (active === t.key ? " tab-on" : ""),
      onClick: () => onChange(t.key),
    }, t.label, t.count != null && h("span", { className: "tab-count" }, t.count))));
}

/* ---- Toggle -------------------------------------------------------------- */
function Toggle({ on, onChange, label }) {
  return h("button", { className: "toggle" + (on ? " toggle-on" : ""), onClick: () => onChange(!on), type: "button", "aria-label": label || "toggle" },
    h("span", { className: "toggle-knob" }));
}

/* ---- Avatar -------------------------------------------------------------- */
function Avatar({ initials, size = 30, tone = "accent" }) {
  return h("span", { className: "avatar", style: { width: size, height: size, fontSize: size * 0.4, background: `var(--${tone}-soft)`, color: `var(--${tone}-ink)` } }, initials);
}

/* ---- Code chip / mono ---------------------------------------------------- */
function Mono({ children, copy, className = "" }) {
  const [done, setDone] = useState(false);
  return h("span", { className: "mono " + className },
    h("span", null, children),
    copy && h("button", {
      className: "mono-copy", title: "Copy",
      onClick: (e) => { e.stopPropagation(); navigator.clipboard?.writeText(String(children)); setDone(true); setTimeout(() => setDone(false), 1000); },
    }, h(Icon, { name: done ? "check" : "copy", size: 12 })));
}

/* ---- Empty state --------------------------------------------------------- */
function Empty({ icon = "search", title, sub }) {
  return h("div", { className: "empty" },
    h(Icon, { name: icon, size: 28 }),
    h("p", { className: "empty-title" }, title),
    sub && h("p", { className: "empty-sub" }, sub));
}

/* ---- Modal / Drawer ------------------------------------------------------ */
function Drawer({ open, onClose, title, sub, children, width = 720, footer }) {
  useEffect(() => {
    const f = (e) => e.key === "Escape" && onClose();
    if (open) window.addEventListener("keydown", f);
    return () => window.removeEventListener("keydown", f);
  }, [open]);
  if (!open) return null;
  return h("div", { className: "drawer-scrim", onClick: onClose },
    h("div", { className: "drawer", style: { width }, onClick: (e) => e.stopPropagation() },
      h("div", { className: "drawer-head" },
        h("div", null,
          h("h2", { className: "drawer-title" }, title),
          sub && h("div", { className: "drawer-sub" }, sub)),
        h("button", { className: "icon-btn", onClick: onClose }, h(Icon, { name: "x", size: 18 }))),
      h("div", { className: "drawer-body" }, children),
      footer && h("div", { className: "drawer-foot" }, footer)));
}
function Modal({ open, onClose, title, children, footer, width = 480 }) {
  if (!open) return null;
  return h("div", { className: "modal-scrim", onClick: onClose },
    h("div", { className: "modal", style: { width }, onClick: (e) => e.stopPropagation() },
      h("div", { className: "modal-head" },
        h("h2", { className: "modal-title" }, title),
        h("button", { className: "icon-btn", onClick: onClose }, h(Icon, { name: "x", size: 18 }))),
      h("div", { className: "modal-body" }, children),
      footer && h("div", { className: "modal-foot" }, footer)));
}

/* ---- Field --------------------------------------------------------------- */
function Field({ label, hint, children }) {
  return h("label", { className: "field" },
    label && h("span", { className: "field-label" }, label),
    children,
    hint && h("span", { className: "field-hint" }, hint));
}
function Select({ value, onChange, options, ...rest }) {
  return h("select", { className: "input", value, onChange: (e) => onChange(e.target.value), ...rest },
    options.map((o) => h("option", { key: o.value ?? o, value: o.value ?? o }, o.label ?? o)));
}

/* ---- Toast host ---------------------------------------------------------- */
const ToastCtx = React.createContext(() => {});
function ToastHost({ children }) {
  const [items, setItems] = useState([]);
  const push = (msg, tone = "ok") => {
    const id = Math.random().toString(36).slice(2);
    setItems((x) => [...x, { id, msg, tone }]);
    setTimeout(() => setItems((x) => x.filter((t) => t.id !== id)), 3200);
  };
  return h(ToastCtx.Provider, { value: push },
    children,
    h("div", { className: "toast-host" },
      items.map((t) => h("div", { key: t.id, className: `toast toast-${t.tone}` },
        h(Icon, { name: t.tone === "bad" ? "alert" : "check", size: 16 }),
        h("span", null, t.msg)))));
}
const useToast = () => React.useContext(ToastCtx);

/* ---- Helpers ------------------------------------------------------------- */
function fmtBytes(n) {
  if (n < 1024) return n + " B";
  if (n < 1048576) return (n / 1024).toFixed(0) + " KB";
  if (n < 1073741824) return (n / 1048576).toFixed(1) + " MB";
  return (n / 1073741824).toFixed(2) + " GB";
}
function fmtAgo(date) {
  const s = Math.round((window.ENO.NOW - date.getTime()) / 1000);
  if (s < 60) return s + "s ago";
  if (s < 3600) return Math.round(s / 60) + "m ago";
  if (s < 86400) return Math.round(s / 3600) + "h ago";
  return Math.round(s / 86400) + "d ago";
}
function fmtTime(date) {
  return date.toISOString().slice(11, 19) + " UTC";
}
function fmtDate(date) {
  return date.toISOString().slice(0, 10);
}
function fmtNum(n) { return n.toLocaleString("en-US"); }

Object.assign(window, {
  Icon, Pill, StatusPill, Button, Card, Stat, Sparkline, MiniBars, Bar, Tabs, Toggle,
  Avatar, Mono, Empty, Drawer, Modal, Field, Select, ToastHost, useToast,
  fmtBytes, fmtAgo, fmtTime, fmtDate, fmtNum,
});
