/* eslint-disable no-undef */
// Shared UI primitives + tiny inline-SVG icon set.

const { useMemo: _useMemo, useState: _useState, useRef: _useRef, useEffect: _useEffect } = React;

// --------- Icons (24x24, stroke-based) ---------
const Icon = ({ name, size = 16, color = "currentColor", strokeWidth = 1.7, style }) => {
  const paths = {
    pulse:      "M3 12h4l2-7 4 14 2-7h6",
    grid:       "M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z",
    map:        "M3 7v13l6-3 6 3 6-3V4l-6 3-6-3-6 3z M9 4v13 M15 7v13",
    sensor:     "M12 4v3 M12 17v3 M4 12h3 M17 12h3 M6.3 6.3l2.1 2.1 M15.6 15.6l2.1 2.1 M6.3 17.7l2.1-2.1 M15.6 8.4l2.1-2.1 M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z",
    layers:     "M12 3 2 8l10 5 10-5-10-5z M2 14l10 5 10-5 M2 11l10 5 10-5",
    network:    "M12 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M5 14a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M19 14a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M10 8.5l-3 4 M14 8.5l3 4 M8 17h8",
    leaf:       "M5 21c0-8 5-15 16-15 0 11-7 16-15 16-1 0-1 0-1-1z M5 21l8-8",
    droplet:    "M12 3s6 6.5 6 11a6 6 0 1 1-12 0c0-4.5 6-11 6-11z",
    flame:      "M12 21c4 0 7-3 7-7 0-3-2-5-3-7-1 2-3 3-4 1-1-2 1-4 1-6-3 1-7 5-7 11 0 5 3 8 6 8z",
    cloud:      "M7 18a4 4 0 1 1 1-7.9A6 6 0 0 1 19 12a4 4 0 0 1-1 7.9H7z",
    alert:      "M12 3 2 21h20L12 3zM12 10v5 M12 17.5v.5",
    bell:       "M6 9a6 6 0 1 1 12 0c0 6 2 8 2 8H4s2-2 2-8z M10 21a2 2 0 0 0 4 0",
    coin:       "M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z M9 10c0-1 1-2 3-2s3 1 3 2-1 1.5-3 2-3 1-3 2 1 2 3 2 3-1 3-2 M12 6v2 M12 16v2",
    bank:       "M3 10h18 M3 21h18 M5 10v11 M9 10v11 M15 10v11 M19 10v11 M12 3 3 8h18l-9-5z",
    shield:     "M12 3 4 6v6c0 5 4 8 8 9 4-1 8-4 8-9V6l-8-3z M9 12l2 2 4-4",
    chart:      "M3 21V3 M3 21h18 M7 17l4-5 4 3 6-8",
    chartBar:   "M5 21V11 M11 21V5 M17 21v-7",
    market:     "M3 7h18l-1 11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2L3 7z M8 7V5a4 4 0 0 1 8 0v2",
    file:       "M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9l-6-6z M14 3v6h6 M9 13h6 M9 17h6",
    settings:   "M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M19.4 15a2 2 0 0 0 .4 2.2l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a2 2 0 0 0-2.2-.4 2 2 0 0 0-1.2 1.8V22a2 2 0 1 1-4 0v-.1a2 2 0 0 0-1.4-1.8 2 2 0 0 0-2.2.4l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A2 2 0 0 0 4 15a2 2 0 0 0-1.8-1.2H2a2 2 0 1 1 0-4h.1A2 2 0 0 0 4 8.6a2 2 0 0 0-.4-2.2l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a2 2 0 0 0 2.2.4H9a2 2 0 0 0 1.2-1.8V2a2 2 0 1 1 4 0v.1a2 2 0 0 0 1.2 1.8 2 2 0 0 0 2.2-.4l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a2 2 0 0 0-.4 2.2V9a2 2 0 0 0 1.8 1.2H22a2 2 0 1 1 0 4h-.1a2 2 0 0 0-1.8 1.2z",
    search:     "M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14z M21 21l-4.3-4.3",
    plus:       "M12 5v14 M5 12h14",
    chev:       "M9 6l6 6-6 6",
    chevDown:   "M6 9l6 6 6-6",
    arrowUp:    "M12 19V5 M5 12l7-7 7 7",
    arrowDown:  "M12 5v14 M19 12l-7 7-7-7",
    download:   "M12 3v12 M6 11l6 6 6-6 M5 21h14",
    export:     "M12 3v12 M6 11l6-6 6 6 M5 21h14",
    play:       "M6 4l14 8-14 8V4z",
    refresh:    "M3 12a9 9 0 1 0 3-6.7L3 8 M3 3v5h5",
    close:      "M6 6l12 12 M18 6l-12 12",
    dot:        "M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0-6 0",
    wifi:       "M5 13a13 13 0 0 1 14 0 M2 9a18 18 0 0 1 20 0 M8.5 16.5a7 7 0 0 1 7 0 M12 20h.01",
    cpu:        "M5 5h14v14H5z M9 9h6v6H9z M9 1v4 M15 1v4 M9 19v4 M15 19v4 M1 9h4 M1 15h4 M19 9h4 M19 15h4",
    tractor:    "M4 18a3 3 0 1 0 6 0 3 3 0 0 0-6 0z M14 16a2 2 0 1 0 4 0 2 2 0 0 0-4 0z M3 14V8h6l2 4h4l1 3 M9 8V5h7l2 5",
    book:       "M4 4h7v16H4z M13 4h7v16h-7z M4 8h7 M13 8h7",
    users:      "M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M3 21v-1a6 6 0 0 1 12 0v1 M16 3a4 4 0 0 1 0 8 M21 21v-1a6 6 0 0 0-4-5.6",
    crop:       "M6 3v14h14 M3 6h14v14",
    target:     "M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10z M12 11a1 1 0 1 0 0 2 1 1 0 0 0 0-2z",
    gauge:      "M12 13a9 9 0 0 1 9 9H3a9 9 0 0 1 9-9z M12 13l5-5",
    moon:       "M21 13a9 9 0 1 1-10-10 7 7 0 0 0 10 10z",
  };
  const d = paths[name];
  if (!d) return null;
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
         strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, ...style }}>
      <path d={d} />
    </svg>
  );
};

// --------- Stat card ---------
function Stat({ label, value, unit, delta, deltaSuffix = "", sparkline, color = "var(--text)", spark_color = "var(--primary)" }) {
  const positive = delta != null && delta >= 0;
  return (
    <div className="card" style={{ padding: "var(--space-4) var(--space-5)", display: "flex", flexDirection: "column", gap: 6, minWidth: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 8 }}>
        <div className="dim" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em", fontWeight: 500 }}>{label}</div>
        {sparkline && <Sparkline data={sparkline} color={spark_color} w={64} h={22} strokeWidth={1.4} />}
      </div>
      <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
        <div className="mono tnum" style={{ fontSize: 26, fontWeight: 600, color, letterSpacing: "-0.02em" }}>{value}</div>
        {unit && <div className="dim mono" style={{ fontSize: 12 }}>{unit}</div>}
      </div>
      {delta != null && (
        <div style={{ display: "flex", alignItems: "center", gap: 4, fontSize: 11 }}>
          <span style={{ color: positive ? "var(--green)" : "var(--rose)", display: "inline-flex", alignItems: "center", gap: 2 }}>
            <Icon name={positive ? "arrowUp" : "arrowDown"} size={11} strokeWidth={2.2} />
            {Math.abs(delta)}%{deltaSuffix}
          </span>
          <span className="faint">vs last period</span>
        </div>
      )}
    </div>
  );
}

// --------- Page header ---------
function PageHeader({ eyebrow, title, sub, actions }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, padding: "var(--space-6) var(--space-6) var(--space-4)" }}>
      <div style={{ minWidth: 0 }}>
        {eyebrow && <div className="section-title" style={{ marginBottom: 6 }}><span style={{ color: "var(--primary)" }}>{eyebrow}</span></div>}
        <h1 style={{ margin: 0, fontSize: 28, fontWeight: 600, letterSpacing: "-0.02em" }}>{title}</h1>
        {sub && <div className="dim" style={{ marginTop: 6, fontSize: 13, maxWidth: 720 }}>{sub}</div>}
      </div>
      {actions && <div style={{ display: "flex", gap: 8, flexShrink: 0 }}>{actions}</div>}
    </div>
  );
}

// --------- Tabs ---------
function Tabs({ tabs, active, onChange, variant = "underline" }) {
  if (variant === "pill") {
    return (
      <div style={{ display: "inline-flex", padding: 3, background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 8, gap: 2 }}>
        {tabs.map((t) => (
          <button key={t.id} onClick={() => onChange(t.id)}
            style={{
              border: 0, font: "inherit", fontSize: 12, fontWeight: 500,
              padding: "6px 12px", borderRadius: 6, cursor: "pointer",
              background: active === t.id ? "var(--bg)" : "transparent",
              color: active === t.id ? "var(--text)" : "var(--text-dim)",
              transition: "background .15s",
            }}>
            {t.label}
          </button>
        ))}
      </div>
    );
  }
  return (
    <div style={{ display: "flex", gap: 0, borderBottom: "1px solid var(--border)", overflowX: "auto" }}>
      {tabs.map((t) => (
        <button key={t.id} onClick={() => onChange(t.id)}
          style={{
            border: 0, font: "inherit", fontSize: 13,
            padding: "10px 16px", cursor: "pointer", background: "transparent",
            color: active === t.id ? "var(--text)" : "var(--text-dim)",
            borderBottom: `2px solid ${active === t.id ? "var(--primary)" : "transparent"}`,
            marginBottom: "-1px", fontWeight: active === t.id ? 600 : 500,
            display: "inline-flex", alignItems: "center", gap: 6,
            whiteSpace: "nowrap",
          }}>
          {t.icon && <Icon name={t.icon} size={14} />}
          {t.label}
          {t.badge != null && <span className="tag" style={{ padding: "1px 6px", fontSize: 10 }}>{t.badge}</span>}
        </button>
      ))}
    </div>
  );
}

// --------- Severity chip ---------
function Severity({ level }) {
  const map = { high: { c: "bad",  l: "High" }, med: { c: "warn", l: "Med" }, low: { c: "info", l: "Low" } };
  const m = map[level] || map.low;
  return <span className={"tag " + m.c}>{m.l}</span>;
}

// --------- Status dot ---------
function StatusDot({ status }) {
  const c = status === "online" || status === "active" ? "var(--green)"
          : status === "warning" ? "var(--amber)"
          : status === "maintenance" ? "var(--cyan)"
          : "var(--rose)";
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--text-2)", textTransform: "capitalize" }}>
      <span style={{ width: 7, height: 7, borderRadius: 999, background: c, boxShadow: `0 0 8px ${c}` }} />
      {status}
    </span>
  );
}

// --------- Battery glyph ---------
function Battery({ pct }) {
  const c = pct > 50 ? "var(--green)" : pct > 20 ? "var(--amber)" : "var(--rose)";
  return (
    <div style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <svg width="22" height="11" viewBox="0 0 22 11">
        <rect x="0.5" y="0.5" width="18" height="10" rx="2" fill="none" stroke="var(--border-strong)" />
        <rect x="19" y="3" width="2.5" height="5" rx="1" fill="var(--border-strong)" />
        <rect x="2" y="2" width={14 * (pct / 100)} height="7" rx="1" fill={c} />
      </svg>
      <span className="mono tnum" style={{ fontSize: 11, color: "var(--text-dim)" }}>{pct}%</span>
    </div>
  );
}

// --------- Data table (compact) ---------
function DataTable({ columns, rows, onRowClick, selectedId, idKey = "id", emptyText = "No rows" }) {
  if (!rows.length) {
    return <div className="dim" style={{ padding: 24, textAlign: "center", fontSize: 13 }}>{emptyText}</div>;
  }
  return (
    <div style={{ overflow: "auto", borderRadius: "var(--r-3)" }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13 }}>
        <thead>
          <tr>
            {columns.map((c) => (
              <th key={c.key} style={{
                textAlign: c.align || "left", padding: "10px 12px",
                fontWeight: 500, fontSize: 11, textTransform: "uppercase", letterSpacing: "0.06em",
                color: "var(--text-faint)", background: "var(--bg-elev)",
                borderBottom: "1px solid var(--border)", position: "sticky", top: 0,
                width: c.width,
              }}>{c.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((r, i) => {
            const sel = selectedId != null && r[idKey] === selectedId;
            return (
              <tr key={r[idKey] ?? i}
                  onClick={onRowClick ? () => onRowClick(r) : undefined}
                  style={{
                    background: sel ? "color-mix(in oklch, var(--primary) 10%, transparent)" : i % 2 ? "transparent" : "var(--bg-elev)",
                    cursor: onRowClick ? "pointer" : "default",
                  }}>
                {columns.map((c) => (
                  <td key={c.key} style={{
                    padding: "8px 12px", textAlign: c.align || "left",
                    borderBottom: "1px solid var(--border-faint)",
                    fontFamily: c.mono ? "var(--font-mono)" : undefined,
                    fontVariantNumeric: c.mono ? "tabular-nums" : undefined,
                    color: c.dim ? "var(--text-dim)" : "var(--text)",
                    whiteSpace: c.wrap ? "normal" : "nowrap",
                  }}>{c.render ? c.render(r) : r[c.key]}</td>
                ))}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// --------- Empty / Placeholder ---------
function Empty({ icon = "sensor", title, body }) {
  return (
    <div style={{ padding: 40, textAlign: "center", color: "var(--text-dim)" }}>
      <div style={{ display: "inline-flex", padding: 14, borderRadius: 999, background: "var(--surface-2)", marginBottom: 12 }}>
        <Icon name={icon} size={20} color="var(--text-faint)" />
      </div>
      <div style={{ color: "var(--text)", fontWeight: 500, marginBottom: 4 }}>{title}</div>
      {body && <div style={{ fontSize: 13, maxWidth: 320, margin: "0 auto" }}>{body}</div>}
    </div>
  );
}

// --------- Image slot placeholder (striped) ---------
function ImageSlot({ label, h = 160, style = {} }) {
  return (
    <div className="placeholder-stripes" style={{ height: h, borderRadius: "var(--r-3)", ...style }}>
      {label}
    </div>
  );
}

// --------- Number animator ---------
function useAnimNumber(target, duration = 600) {
  const [v, setV] = _useState(target);
  const ref = _useRef(target);
  _useEffect(() => {
    const start = performance.now();
    const from = ref.current;
    const to = target;
    let raf;
    const step = (t) => {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      const cur = from + (to - from) * eased;
      setV(cur);
      ref.current = cur;
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target, duration]);
  return v;
}

// --------- Money formatter ---------
function fmtMoney(v, digits = 0) {
  if (v == null) return "—";
  if (Math.abs(v) >= 1e6) return "$" + (v / 1e6).toFixed(2) + "M";
  if (Math.abs(v) >= 1e3) return "$" + (v / 1e3).toFixed(1) + "k";
  return "$" + v.toLocaleString(undefined, { maximumFractionDigits: digits });
}
function fmtNum(v, digits = 0) {
  if (v == null) return "—";
  if (Math.abs(v) >= 1e6) return (v / 1e6).toFixed(2) + "M";
  if (Math.abs(v) >= 1e3) return (v / 1e3).toFixed(1) + "k";
  return v.toLocaleString(undefined, { maximumFractionDigits: digits });
}
function fmtPct(v, digits = 1) { return (v * 100).toFixed(digits) + "%"; }

Object.assign(window, {
  Icon, Stat, PageHeader, Tabs, Severity, StatusDot, Battery,
  DataTable, Empty, ImageSlot, useAnimNumber, fmtMoney, fmtNum, fmtPct,
});
