// UI primitives — shared across modules
// Icons inline (Lucide-style stroke), Stat, Card, Table, Badge, Button, Tabs

const { useState, useEffect, useRef, useMemo } = React;

// ============ ICONS ============
const Ic = ({ name, size = 16, ...rest }) => {
  const s = size;
  const common = { width: s, height: s, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", ...rest };
  const paths = {
    home: <><path d="M3 12l9-9 9 9"/><path d="M5 10v10h14V10"/></>,
    live: <><circle cx="12" cy="12" r="3"/><path d="M5.5 8.5a8 8 0 0 0 0 7M18.5 8.5a8 8 0 0 1 0 7M2 12a13 13 0 0 1 4-9M22 12a13 13 0 0 0-4-9"/></>,
    store: <><path d="M3 9l1.5-5h15L21 9"/><path d="M3 9v11h18V9"/><path d="M3 9h18M9 14h6"/></>,
    site: <><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></>,
    box: <><path d="M21 16V8l-9-5-9 5v8l9 5 9-5z"/><path d="M3.3 7L12 12l8.7-5M12 22V12"/></>,
    cart: <><circle cx="9" cy="20" r="1.5"/><circle cx="18" cy="20" r="1.5"/><path d="M3 4h2l3 12h11l2-8H6"/></>,
    users: <><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.87M16 3.13a4 4 0 0 1 0 7.75"/></>,
    chart: <><path d="M3 3v18h18"/><path d="M7 14l3-3 4 4 5-5"/></>,
    megaphone: <><path d="M3 11l15-7v16l-15-7v-2z"/><path d="M3 11v2a3 3 0 0 0 3 3l1 4h3l-1-4"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></>,
    search: <><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></>,
    bell: <><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></>,
    plus: <><path d="M12 5v14M5 12h14"/></>,
    arrowRight: <><path d="M5 12h14M13 5l7 7-7 7"/></>,
    chevronDown: <><path d="M6 9l6 6 6-6"/></>,
    chevronRight: <><path d="M9 6l6 6-6 6"/></>,
    x: <><path d="M18 6L6 18M6 6l12 12"/></>,
    check: <><path d="M20 6L9 17l-5-5"/></>,
    download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5M12 15V3"/></>,
    filter: <><path d="M22 3H2l8 9.5V19l4 2v-8.5L22 3z"/></>,
    play: <><path d="M5 3l14 9-14 9V3z"/></>,
    pause: <><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></>,
    edit: <><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></>,
    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"/></>,
    package: <><path d="M16 16l4-2v-4l-4-2-4 2-4-2-4 2v4l4 2 4-2z"/><path d="M12 12v8M8 14l4-2 4 2"/></>,
    tag: <><path d="M20 12l-9-9H3v8l9 9 8-8z"/><circle cx="7" cy="7" r="1.5"/></>,
    truck: <><rect x="1" y="6" width="13" height="11"/><path d="M14 9h4l3 3v5h-7"/><circle cx="6" cy="19" r="2"/><circle cx="17" cy="19" r="2"/></>,
    whatsapp: <><path d="M3 21l1.5-5A8 8 0 1 1 8 19.5L3 21z"/></>,
    instagram: <><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="0.5" fill="currentColor"/></>,
    pix: <><path d="M12 2l4 4-4 4-4-4 4-4zM12 14l4 4-4 4-4-4 4-4zM2 12l4-4 4 4-4 4-4-4zM14 12l4-4 4 4-4 4-4-4z"/></>,
    qr: <><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><path d="M14 14h3v3h-3zM14 19h3M19 14v7M14 17h7"/></>,
    barcode: <><path d="M3 4v16M6 4v16M9 4v16M11 4v16M14 4v16M16 4v16M19 4v16M21 4v16"/></>,
    gift: <><polyline points="20 12 20 22 4 22 4 12"/><rect x="2" y="7" width="20" height="5"/><line x1="12" y1="22" x2="12" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7zM12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/></>,
    sparkles: <><path d="M12 2l1.5 4.5L18 8l-4.5 1.5L12 14l-1.5-4.5L6 8l4.5-1.5L12 2zM19 14l.7 2.3L22 17l-2.3.7L19 20l-.7-2.3L16 17l2.3-.7L19 14zM5 16l.7 2.3L8 19l-2.3.7L5 22l-.7-2.3L2 19l2.3-.7L5 16z"/></>,
    dollar: <><path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></>,
    file: <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"/></>,
    folder: <><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></>,
    map: <><path d="M3 6l6-2 6 2 6-2v14l-6 2-6-2-6 2V6z"/><path d="M9 4v16M15 6v16"/></>,
    sliders: <><path d="M21 4H14M10 4H3M21 12h-9M8 12H3M21 20h-7M10 20H3"/><circle cx="12" cy="4" r="2"/><circle cx="6" cy="12" r="2"/><circle cx="12" cy="20" r="2"/></>,
    layers: <><path d="M12 2L2 8l10 6 10-6-10-6z"/><path d="M2 14l10 6 10-6M2 12l10 6 10-6"/></>,
    flame: <><path d="M12 2s4 4 4 9a4 4 0 0 1-8 0c0-2 1-3 1-3s-3 2-3 6a6 6 0 1 0 12 0c0-7-6-12-6-12z"/></>,
    refresh: <><path d="M23 4v6h-6M1 20v-6h6"/><path d="M3.5 9a9 9 0 0 1 15-3L23 10M1 14l4.5 4a9 9 0 0 0 15-3"/></>,
    eye: <><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z"/><circle cx="12" cy="12" r="3"/></>,
    send: <><path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/></>,
    user: <><circle cx="12" cy="7" r="4"/><path d="M5 21v-2a4 4 0 0 1 4-4h6a4 4 0 0 1 4 4v2"/></>,
    phone: <><path d="M22 16.9V20a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2 4.2 2 2 0 0 1 4 2h3a2 2 0 0 1 2 1.7c.1 1.2.4 2.4.7 3.6a2 2 0 0 1-.4 2.1L7.9 11a16 16 0 0 0 6 6l1.6-1.4a2 2 0 0 1 2.1-.4c1.2.3 2.4.6 3.6.7A2 2 0 0 1 22 17z"/></>,
    grid: <><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></>,
    list: <><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></>,
    print: <><path d="M6 9V2h12v7M6 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-2M6 14h12v8H6z"/></>,
    cake: <><path d="M20 21V9a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12M2 21h20M4 13h16M9 7V4M12 7V3M15 7V4"/></>,
    bag: <><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"/><path d="M3 6h18M16 10a4 4 0 0 1-8 0"/></>,
    spinner: <><circle cx="12" cy="12" r="9" strokeOpacity="0.2"/><path d="M12 3a9 9 0 0 1 9 9"/></>,
    moneyIn: <><path d="M12 1v22M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/><path d="M7 14l5-5 5 5"/></>,
    devices: <><rect x="2" y="3" width="14" height="11" rx="2"/><path d="M2 17h14M7 21h6"/><rect x="18" y="9" width="4" height="12" rx="1"/></>,
  };
  return <svg {...common}>{paths[name] || null}</svg>;
};

// ============ Currency helpers ============
const brl = (v) => "R$ " + Number(v).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const brlNoCents = (v) => "R$ " + Number(v).toLocaleString("pt-BR", { maximumFractionDigits: 0 });
const numFmt = (v) => Number(v).toLocaleString("pt-BR");
const pct = (v) => (v >= 0 ? "+" : "") + v.toFixed(1) + "%";

// ============ Stat card ============
const Stat = ({ label, value, valueSuffix, delta, glow, hint, footer }) => (
  <div className={"stat" + (glow ? " glow " + glow : "")}>
    <div className="sk">{label}</div>
    <div className="sv">{value}{valueSuffix && <small>{valueSuffix}</small>}</div>
    {delta !== undefined && delta !== null && (
      <div className={"delta " + (delta >= 0 ? "up" : "down")}>{pct(delta)} <span className="t-3" style={{letterSpacing:0, marginLeft:4}}>vs. período ant.</span></div>
    )}
    {hint && <div className="t-mono-label mt-4" style={{ letterSpacing: '0.08em', textTransform: 'none' }}>{hint}</div>}
    {footer}
  </div>
);

// ============ Badge ============
const Badge = ({ children, kind, dot }) => (
  <span className={"badge " + (kind || "")}>
    {dot && <span className="dotx"/>}
    {children}
  </span>
);

// ============ Toggle ============
const Toggle = ({ on, onChange }) => (
  <div className={"toggle" + (on ? " on" : "")} onClick={() => onChange && onChange(!on)} role="switch" aria-checked={on}/>
);

// ============ Tabs ============
const Tabs = ({ tabs, active, onChange }) => (
  <div className="tabs">
    {tabs.map(t => (
      <button key={t.id || t} className={"tab" + (active === (t.id || t) ? " active" : "")} onClick={() => onChange(t.id || t)}>
        {t.label || t}
        {t.count !== undefined && <span style={{marginLeft:6, color:'var(--text-4)', fontSize:'9.5px'}}>{t.count}</span>}
      </button>
    ))}
  </div>
);

// ============ Status helpers ============
const statusKind = (s) => {
  const m = (s || "").toLowerCase();
  if (m.includes("pago") || m.includes("aprovad") || m.includes("entregue") || m.includes("conclu") || m.includes("recupera")) return "green";
  if (m.includes("cancel") || m.includes("falha") || m.includes("vencido")) return "red";
  if (m.includes("aguard") || m.includes("pendente") || m.includes("rascunho")) return "muted";
  if (m.includes("envia") || m.includes("separa") || m.includes("vence")) return "cyan";
  if (m.includes("agend") || m.includes("sacola")) return "purple";
  if (m.includes("em dia")) return "green";
  return "";
};

const StatusBadge = ({ status }) => <Badge kind={statusKind(status)} dot>{status}</Badge>;

// ============ Avatar ============
const ClientAvatar = ({ name, size = "" }) => {
  const initials = name.split(" ").map(p => p[0]).slice(0, 2).join("").toUpperCase();
  return <div className={"client-avatar " + size}>{initials}</div>;
};

// ============ Level ============
const Level = ({ n }) => {
  const kind = n >= 8 ? "l-high" : n >= 5 ? "l-mid" : "l-low";
  return <span className={"level " + kind}>N{n}</span>;
};

// ============ Spark / line / bars ============
const LineChart = ({ data, height = 180, accent = "var(--accent)" }) => {
  // data: [{d, v}]
  const max = Math.max(...data.map(d => d.v));
  const min = 0;
  const w = 100;
  const h = 100;
  const pts = data.map((d, i) => {
    const x = (i / (data.length - 1)) * w;
    const y = h - ((d.v - min) / (max - min || 1)) * (h - 8) - 4;
    return [x, y];
  });
  const path = pts.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(2) + " " + p[1].toFixed(2)).join(" ");
  const area = path + ` L ${w} ${h} L 0 ${h} Z`;
  return (
    <div className="chart-line" style={{ height }}>
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
        <defs>
          <linearGradient id="lc-grad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={accent} stopOpacity="0.35"/>
            <stop offset="100%" stopColor={accent} stopOpacity="0"/>
          </linearGradient>
        </defs>
        <path d={area} fill="url(#lc-grad)"/>
        <path d={path} fill="none" stroke={accent} strokeWidth="0.8" vectorEffect="non-scaling-stroke"/>
        {pts.map((p, i) => (
          <circle key={i} cx={p[0]} cy={p[1]} r="0.9" fill={data[i].v === max ? "var(--green)" : accent} stroke="var(--bg-2)" strokeWidth="0.4"/>
        ))}
      </svg>
      <div style={{ display:'flex', justifyContent:'space-between', marginTop:4, fontFamily:'var(--mono)', fontSize:10, color:'var(--text-4)', letterSpacing:'0.08em' }}>
        {data.filter((_, i) => i % Math.max(1, Math.floor(data.length / 6)) === 0).map((d, i) => <span key={i}>{d.d}</span>)}
      </div>
    </div>
  );
};

const BarH = ({ rows, max }) => {
  const m = max || Math.max(...rows.map(r => r.value));
  return (
    <div>
      {rows.map((r, i) => (
        <div key={i} className="bar-h">
          <span className="lbl">{r.label}</span>
          <span className="bar-track"><span className="bar-fill" style={{ width: (r.value / m * 100) + "%", background: r.color || 'var(--accent)' }}/></span>
          <span className="val">{r.display || r.value}</span>
        </div>
      ))}
    </div>
  );
};

const Donut = ({ segments, center, label }) => {
  // segments: [{value, color, label}]
  const total = segments.reduce((s, x) => s + x.value, 0);
  let acc = 0;
  const r = 36, c = 2 * Math.PI * r;
  return (
    <div className="donut">
      <svg viewBox="0 0 100 100" width="140" height="140">
        <circle cx="50" cy="50" r={r} fill="none" stroke="var(--bg-3)" strokeWidth="12"/>
        {segments.map((s, i) => {
          const len = (s.value / total) * c;
          const offset = (acc / total) * c;
          acc += s.value;
          return <circle key={i} cx="50" cy="50" r={r} fill="none" stroke={s.color} strokeWidth="12" strokeDasharray={`${len} ${c - len}`} strokeDashoffset={-offset}/>;
        })}
      </svg>
      <div className="center">
        <div className="big">{center}</div>
        <div className="lbl">{label}</div>
      </div>
    </div>
  );
};

// ============ Empty state ============
const Empty = ({ icon = "box", title, hint, action }) => (
  <div className="empty">
    <div style={{ color: 'var(--text-4)', display:'inline-flex' }}><Ic name={icon} size={36}/></div>
    <h4>{title}</h4>
    {hint && <p>{hint}</p>}
    {action && <div className="mt-12">{action}</div>}
  </div>
);

Object.assign(window, {
  Ic, Stat, Badge, Toggle, Tabs, StatusBadge, ClientAvatar, Level,
  LineChart, BarH, Donut, Empty,
  brl, brlNoCents, numFmt, pct, statusKind,
});
