/* Shared UI primitives */
// Make React hooks available globally across all Babel script files
window.useState = React.useState;
window.useEffect = React.useEffect;
window.useMemo = React.useMemo;
window.useRef = React.useRef;
window.useCallback = React.useCallback;
const { useState, useEffect, useMemo, useRef, useCallback } = React;

// ───── Brand mark ─────
function BrandMark({ size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
      <circle cx="6" cy="7" r="2.6" fill="#c97a16"/>
      <circle cx="18" cy="8.5" r="2.6" fill="#ffffff" stroke="#ffffff" strokeWidth="0.5"/>
      <circle cx="12" cy="18" r="2.6" fill="#3b82c4"/>
      <line x1="6" y1="7" x2="18" y2="8.5" stroke="#ffffff" strokeOpacity="0.5" strokeWidth="1"/>
      <line x1="6" y1="7" x2="12" y2="18" stroke="#ffffff" strokeOpacity="0.5" strokeWidth="1"/>
      <line x1="18" y1="8.5" x2="12" y2="18" stroke="#ffffff" strokeOpacity="0.5" strokeWidth="1"/>
    </svg>
  );
}

// ───── Icons (inline SVG, 1.5px stroke) ─────
const Icon = ({ name, size = 16 }) => {
  const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    home: <><path d="M3 12 12 4l9 8"/><path d="M5 10v10h14V10"/></>,
    users: <><circle cx="9" cy="8" r="3.5"/><path d="M3 20c0-3 2.5-5 6-5s6 2 6 5"/><circle cx="17" cy="9" r="2.5"/><path d="M15 20c0-2 1.5-3.5 4-3.5"/></>,
    clipboard: <><rect x="6" y="4" width="12" height="17" rx="1.5"/><path d="M9 4v-1h6v1"/><path d="M9 10h6M9 14h6M9 18h3"/></>,
    network: <><circle cx="12" cy="5" r="2"/><circle cx="5" cy="14" r="2"/><circle cx="19" cy="14" r="2"/><circle cx="12" cy="20" r="2"/><path d="M12 7v11M6.5 15l4 4M17.5 15l-4 4M7 13l4-7M17 13l-4-7"/></>,
    chart: <><path d="M4 20V8M10 20V4M16 20v-8M22 20H2"/></>,
    bank: <><rect x="4" y="9" width="16" height="11" rx="1"/><path d="M4 9 12 4l8 5"/><path d="M8 13v4M12 13v4M16 13v4"/></>,
    calendar: <><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></>,
    book: <><path d="M4 4h12a2 2 0 012 2v14H6a2 2 0 01-2-2V4z"/><path d="M4 4v14"/></>,
    shield: <><path d="M12 3 4 6v6c0 4 3 7 8 9 5-2 8-5 8-9V6l-8-3z"/></>,
    download: <><path d="M12 3v12M7 10l5 5 5-5M4 21h16"/></>,
    plus: <><path d="M12 5v14M5 12h14"/></>,
    search: <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
    filter: <><path d="M4 5h16l-6 8v6l-4-2v-4z"/></>,
    bell: <><path d="M6 9a6 6 0 1112 0c0 5 2 6 2 6H4s2-1 2-6z"/><path d="M10 19a2 2 0 004 0"/></>,
    check: <><path d="M4 12l5 5L20 6"/></>,
    x: <><path d="M6 6l12 12M18 6L6 18"/></>,
    chev_r: <><path d="m9 6 6 6-6 6"/></>,
    chev_d: <><path d="m6 9 6 6 6-6"/></>,
    info: <><circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 8v.5"/></>,
    spark: <><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2 2M16.4 16.4l2 2M5.6 18.4l2-2M16.4 7.6l2-2"/></>,
    eye: <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="2.5"/></>,
    edit: <><path d="M4 20h4l10-10-4-4L4 16v4z"/><path d="m14 6 4 4"/></>,
    upload: <><path d="M12 21V9M7 14l5-5 5 5M4 5h16"/></>,
    map: <><path d="M3 6v15l6-3 6 3 6-3V3l-6 3-6-3-6 3z"/><path d="M9 3v15M15 6v15"/></>,
    activity: <><path d="M3 12h4l3-8 4 16 3-8h4"/></>,
    msg: <><path d="M21 12c0 4-4 7-9 7-1.4 0-2.7-.2-3.9-.6L3 20l1.2-4.2C3.4 14.6 3 13.3 3 12c0-4 4-7 9-7s9 3 9 7z"/></>,
  };
  return <svg {...props}>{paths[name] || null}</svg>;
};

// ───── Type swatch ─────
function Swatch({ tipo, size = 28 }) {
  const t = window.TIPOS_ACTOR.find(x => x.id === tipo);
  if (!t) return null;
  return (
    <div className="swatch" style={{ background: t.color, width: size, height: size, fontSize: size * 0.4 }}>
      {t.label.split(" ")[0].substring(0, 2).toUpperCase()}
    </div>
  );
}

// ───── Modal ─────
function Modal({ open, onClose, title, children, width = 720 }) {
  if (!open) return null;
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "rgba(12,31,61,0.45)",
      display: "flex", alignItems: "center", justifyContent: "center",
      zIndex: 1000, backdropFilter: "blur(2px)"
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        background: "#fff", borderRadius: 10, width, maxWidth: "92vw",
        maxHeight: "90vh", overflow: "hidden", display: "flex", flexDirection: "column",
        boxShadow: "0 20px 50px rgba(0,0,0,0.25)"
      }}>
        <div style={{ padding: "14px 18px", borderBottom: "1px solid var(--c-line)", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <div style={{ fontWeight: 600, fontSize: 14 }}>{title}</div>
          <button className="btn-ghost btn" onClick={onClose} style={{ padding: 4 }}><Icon name="x" size={16}/></button>
        </div>
        <div style={{ overflowY: "auto", padding: 18 }}>{children}</div>
      </div>
    </div>
  );
}

// ───── Toast ─────
const ToastCtx = React.createContext({ push: () => {} });
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg, kind = "info") => {
    const id = Math.random();
    setToasts(t => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 3000);
  }, []);
  return (
    <ToastCtx.Provider value={{ push }}>
      {children}
      <div style={{ position: "fixed", bottom: 20, right: 20, display: "flex", flexDirection: "column", gap: 8, zIndex: 2000 }}>
        {toasts.map(t => (
          <div key={t.id} style={{
            background: "var(--c-primary-900)", color: "#fff", padding: "10px 14px",
            borderRadius: 8, fontSize: 12, display: "flex", alignItems: "center", gap: 8,
            boxShadow: "0 8px 24px rgba(0,0,0,0.25)", minWidth: 240
          }}>
            <Icon name={t.kind === "success" ? "check" : "info"} size={14}/>
            {t.msg}
          </div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
}
const useToast = () => React.useContext(ToastCtx);

// ───── Tiny sparkline ─────
function Sparkline({ values, color = "var(--c-primary)", width = 80, height = 22 }) {
  const max = Math.max(...values), min = Math.min(...values);
  const span = max - min || 1;
  const pts = values.map((v, i) => {
    const x = (i / (values.length - 1)) * width;
    const y = height - ((v - min) / span) * height;
    return `${x},${y}`;
  }).join(" ");
  return (
    <svg width={width} height={height}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5"/>
    </svg>
  );
}

// ───── Bar chart (horizontal) ─────
function HBarChart({ data, color = "var(--c-primary)", maxVal, format = v => v }) {
  const max = maxVal || Math.max(...data.map(d => d.value));
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
      {data.map((d, i) => (
        <div key={i} style={{ display: "grid", gridTemplateColumns: "150px 1fr 60px", alignItems: "center", gap: 10, fontSize: 12 }}>
          <span style={{ color: "var(--c-ink-2)" }}>{d.label}</span>
          <div className="bar"><div className="fill" style={{ width: `${(d.value / max) * 100}%`, background: d.color || color }}/></div>
          <span className="mono" style={{ textAlign: "right", color: "var(--c-ink-3)", fontSize: 11 }}>{format(d.value)}</span>
        </div>
      ))}
    </div>
  );
}

// ───── Line chart (responsive simple) ─────
function LineChart({ series, width = 540, height = 200, xLabels = [], yMax }) {
  const pad = { l: 36, r: 12, t: 14, b: 24 };
  const w = width - pad.l - pad.r;
  const h = height - pad.t - pad.b;
  const allVals = series.flatMap(s => s.values);
  const max = yMax || Math.max(...allVals) * 1.1;
  const ticks = 4;
  const n = series[0].values.length;
  return (
    <svg width={width} height={height}>
      {/* grid */}
      {[...Array(ticks + 1)].map((_, i) => {
        const y = pad.t + (i / ticks) * h;
        const val = Math.round(max - (i / ticks) * max);
        return (
          <g key={i}>
            <line x1={pad.l} x2={pad.l + w} y1={y} y2={y} className="chart-grid"/>
            <text x={pad.l - 6} y={y + 3} textAnchor="end" className="chart-label">{val}</text>
          </g>
        );
      })}
      {/* x labels */}
      {xLabels.map((l, i) => {
        const x = pad.l + (i / (n - 1)) * w;
        return <text key={i} x={x} y={height - 8} textAnchor="middle" className="chart-label">{l}</text>;
      })}
      {/* series */}
      {series.map((s, si) => {
        const pts = s.values.map((v, i) => {
          const x = pad.l + (i / (n - 1)) * w;
          const y = pad.t + h - (v / max) * h;
          return `${x},${y}`;
        }).join(" ");
        return (
          <g key={si}>
            <polyline points={pts} fill="none" stroke={s.color} strokeWidth="2"/>
            {s.values.map((v, i) => {
              const x = pad.l + (i / (n - 1)) * w;
              const y = pad.t + h - (v / max) * h;
              return <circle key={i} cx={x} cy={y} r="2.5" fill={s.color}/>;
            })}
          </g>
        );
      })}
    </svg>
  );
}

// ───── Donut ─────
function Donut({ segments, size = 140, thickness = 22, centerLabel, centerSub }) {
  const r = size / 2 - thickness / 2;
  const c = size / 2;
  const total = segments.reduce((s, x) => s + x.value, 0);
  let offset = 0;
  const circ = 2 * Math.PI * r;
  return (
    <svg width={size} height={size}>
      <circle cx={c} cy={c} r={r} fill="none" stroke="var(--c-line-2)" strokeWidth={thickness}/>
      {segments.map((s, i) => {
        const len = (s.value / total) * circ;
        const dash = `${len} ${circ - len}`;
        const el = (
          <circle key={i} cx={c} cy={c} r={r} fill="none"
            stroke={s.color} strokeWidth={thickness}
            strokeDasharray={dash}
            strokeDashoffset={-offset}
            transform={`rotate(-90 ${c} ${c})`}/>
        );
        offset += len;
        return el;
      })}
      {centerLabel && (
        <>
          <text x={c} y={c - 2} textAnchor="middle" style={{ fontFamily: "var(--font-serif)", fontSize: 20, fontWeight: 600, fill: "var(--c-ink)" }}>{centerLabel}</text>
          <text x={c} y={c + 14} textAnchor="middle" style={{ fontSize: 10, fill: "var(--c-ink-4)" }}>{centerSub}</text>
        </>
      )}
    </svg>
  );
}

// ───── Helpers ─────
const colorFor = (tipo) => (window.TIPOS_ACTOR.find(t => t.id === tipo) || {}).color || "#888";
const labelFor = (tipo) => (window.TIPOS_ACTOR.find(t => t.id === tipo) || {}).label || tipo;

// Expose globally
Object.assign(window, {
  BrandMark, Icon, Swatch, Modal, Sparkline, HBarChart, LineChart, Donut,
  ToastProvider, useToast, colorFor, labelFor
});
