/* ============================================================
   PCP — UI primitives: Icon set + shared components
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

// ---- Lucide-style line icons (24x24, stroke) ----
const ICONS = {
  search: 'M11 11m-7 0a7 7 0 1 0 14 0a7 7 0 1 0-14 0 M21 21l-4.3-4.3',
  command: 'M15 6a3 3 0 1 0 0 0 M9 6a3 3 0 1 1 0 0 M9 6v12 M15 6v12 M9 18a3 3 0 1 0 0 0 M15 18a3 3 0 1 1 0 0',
  chevronDown: 'M6 9l6 6 6-6',
  chevronRight: 'M9 6l6 6-6 6',
  chevronLeft: 'M15 6l-6 6 6 6',
  chevronsUpDown: 'M7 15l5 5 5-5 M7 9l5-5 5 5',
  panelLeft: 'M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z M9 4v16',
  plus: 'M12 5v14 M5 12h14',
  check: 'M20 6L9 17l-5-5',
  checkCircle: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M9 12l2 2 4-4',
  alert: '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 0z M12 9v4 M12 17h.01',
  box: 'M21 8l-9-5-9 5 9 5 9-5z M3 8v8l9 5 9-5V8 M12 13v8',
  package: 'M16.5 9.4 7.5 4.2 M21 16V8a2 2 0 0 0-1-1.7l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.7l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z M3.3 7 12 12l8.7-5 M12 22V12',
  factory: 'M2 20h20 M4 20V9l5 4V9l5 4V6l5 4v10 M9 20v-5h6v5',
  cart: 'M8 22a1 1 0 1 0 0 0 M19 22a1 1 0 1 0 0 0 M2 2h2l2.6 12.4a2 2 0 0 0 2 1.6h7.7a2 2 0 0 0 2-1.6L23 6H6',
  fileText: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M9 13h6 M9 17h6',
  wallet: 'M19 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5 M18 12a1 1 0 1 0 0 2 1 1 0 0 0 0-2z',
  chart: 'M3 3v18h18 M7 16v-5 M12 16V8 M17 16v-9',
  users: 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M22 21v-2a4 4 0 0 0-3-3.9 M16 3.1a4 4 0 0 1 0 7.8',
  settings: 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z',
  layers: 'M12 2 2 7l10 5 10-5-10-5z M2 17l10 5 10-5 M2 12l10 5 10-5',
  clipboard: '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 M9 2h6a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1z M9 13l2 2 4-4',
  clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z M12 6v6l4 2',
  truck: 'M14 18V6a1 1 0 0 0-1-1H2v12 M14 9h4l3 3v5a1 1 0 0 1-1 1h-1 M8 19a2 2 0 1 0 0 0 M18 19a2 2 0 1 0 0 0',
  wifi: 'M5 12.55a11 11 0 0 1 14 0 M8.5 16.1a6 6 0 0 1 7 0 M12 20h.01 M2 8.8a16 16 0 0 1 20 0',
  wifiOff: 'M2 8.8a16 16 0 0 1 4.5-2.7 M19.5 6.1A16 16 0 0 1 22 8.8 M5 12.55a11 11 0 0 1 5.1-2.5 M16.7 11.2a11 11 0 0 1 2.3 1.3 M8.5 16.1a6 6 0 0 1 5-1.4 M12 20h.01 M2 2l20 20',
  refresh: 'M3 12a9 9 0 0 1 15-6.7L21 8 M21 3v5h-5 M21 12a9 9 0 0 1-15 6.7L3 16 M3 21v-5h5',
  cloud: 'M17.5 19a4.5 4.5 0 0 0 0-9 6 6 0 0 0-11.6-1.5A4 4 0 0 0 6 18',
  cloudOff: 'M2 2l20 20 M5.8 5.8A6 6 0 0 0 5.9 8.5 4 4 0 0 0 6 18h9 M17.5 19a4.5 4.5 0 0 0 1.3-8.8 6 6 0 0 0-3.4-4',
  x: 'M18 6 6 18 M6 6l12 12',
  arrowUp: 'M12 19V5 M5 12l7-7 7 7',
  arrowDown: 'M12 5v14 M19 12l-7 7-7-7',
  trendUp: 'M3 17l6-6 4 4 8-8 M21 7v6h-6',
  trendDown: 'M3 7l6 6 4-4 8 8 M21 17v-6h-6',
  dollar: 'M12 2v20 M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6',
  filter: 'M22 3H2l8 9.5V19l4 2v-8.5L22 3z',
  download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3',
  upload: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M17 8l-5-5-5 5 M12 3v12',
  scan: 'M3 7V5a2 2 0 0 1 2-2h2 M17 3h2a2 2 0 0 1 2 2v2 M21 17v2a2 2 0 0 1-2 2h-2 M7 21H5a2 2 0 0 1-2-2v-2 M3 12h18',
  image: 'M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M8.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z M21 15l-5-5L5 21',
  more: 'M12 12h.01 M19 12h.01 M5 12h.01',
  printer: 'M6 9V2h12v7 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 M6 14h12v8H6z',
  sliders: 'M4 21v-7 M4 10V3 M12 21v-9 M12 8V3 M20 21v-5 M20 12V3 M1 14h6 M9 8h6 M17 16h6',
  sun: 'M12 17a5 5 0 1 0 0-10 5 5 0 0 0 0 10z M12 1v2 M12 21v2 M4.2 4.2l1.4 1.4 M18.4 18.4l1.4 1.4 M1 12h2 M21 12h2 M4.2 19.8l1.4-1.4 M18.4 5.6l1.4-1.4',
  moon: 'M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z',
  logout: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4 M16 17l5-5-5-5 M21 12H9',
  zap: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z',
  calendar: 'M8 2v4 M16 2v4 M3 10h18 M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z',
  tag: 'M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0l-7.2-7.2A2 2 0 0 1 2.8 12V4a1 1 0 0 1 1-1h8a2 2 0 0 1 1.4.6l7.4 7.4a2 2 0 0 1 0 2.8z M7 7h.01',
  percent: 'M19 5L5 19 M6.5 9a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z M17.5 20a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z',
  list: 'M8 6h13 M8 12h13 M8 18h13 M3 6h.01 M3 12h.01 M3 18h.01',
  grid: 'M3 3h7v7H3z M14 3h7v7h-7z M14 14h7v7h-7z M3 14h7v7H3z',
  gantt: 'M8 6h10 M6 12h12 M4 18h7 M3 3v18',
  inbox: 'M22 12h-6l-2 3h-4l-2-3H2 M5.5 5.1 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.5-6.9A2 2 0 0 0 16.7 4H7.3a2 2 0 0 0-1.8 1.1z',
  building: 'M3 21h18 M5 21V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16 M9 7h1 M9 11h1 M9 15h1 M14 7h1 M14 11h1 M14 15h1',
  bell: 'M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9 M10.3 21a1.94 1.94 0 0 0 3.4 0',
  qr: 'M3 3h7v7H3z M14 3h7v7h-7z M3 14h7v7H3z M14 14h3v3h-3z M20 14v7 M17 20h4',
  receipt: '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 1-2-1z M8 7h8 M8 11h8 M8 15h5',
  play: 'M6 3l14 9-14 9V3z',
  pause: 'M6 4h4v16H6z M14 4h4v16h-4z',
  edit: 'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z',
  trash: 'M3 6h18 M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2 M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6 M10 11v6 M14 11v6',
  link: 'M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1 M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1',
  eye: 'M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7z M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  paperclip: 'M21.4 11.05 12.25 20.2a6 6 0 0 1-8.49-8.49l9.2-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48'
};

function Icon({ name, size = 16, className = "", style }) {
  const d = ICONS[name];
  return (
    <svg className={"ico " + className} width={size} height={size} viewBox="0 0 24 24"
    fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" style={style}>
      {(d || "").split(" M").map((seg, i) => <path key={i} d={(i ? "M" : "") + seg} />)}
    </svg>);

}

function Btn({ children, icon, variant, size, onClick, title, style, disabled }) {
  const cls = ["btn", variant, size, disabled ? "is-disabled" : ""].filter(Boolean).join(" ");
  return (
    <button className={cls} onClick={onClick} title={title} style={style} disabled={disabled}>
      {icon && <Icon name={icon} size={15} />}
      {children}
    </button>);

}

function IconBtn({ icon, onClick, title, bordered, size = 16, active }) {
  return (
    <button className={"ico-btn" + (bordered ? " bordered" : "")} onClick={onClick} title={title}
    style={active ? { background: "var(--accent-tint)", color: "var(--accent)" } : undefined}>
      <Icon name={icon} size={size} />
    </button>);

}

function Badge({ tone, dotted, children }) {
  return <span className={["badge", tone, dotted ? "dotted" : ""].filter(Boolean).join(" ")}>{children}</span>;
}

function MetricCard({ icon, label, value, unit, foot, delta, deltaTone, state, onClick }) {
  return (
    <div className={["metric", state ? "is-" + state : "", onClick ? "clickable" : ""].filter(Boolean).join(" ")} onClick={onClick}>
      <div className="m-top">
        <div className="m-ico"><Icon name={icon} size={15} /></div>
        <span className="m-label">{label}</span>
      </div>
      <div className="m-value">{value}{unit && <span className="unit"> {unit}</span>}</div>
      {(foot || delta != null) &&
      <div className="m-foot">
          {delta != null &&
        <span className={"m-delta " + deltaTone}>
              <Icon name={deltaTone === "up" ? "trendUp" : "trendDown"} size={12} />{delta}
            </span>
        }
          {foot && <span>{foot}</span>}
        </div>
      }
    </div>);

}

function Empty({ icon = "inbox", title, children, action }) {
  return (
    <div className="empty">
      <div className="e-ico"><Icon name={icon} size={22} /></div>
      <h4>{title}</h4>
      {children && <p>{children}</p>}
      {action}
    </div>);

}

function SectionLabel({ children, right }) {
  return <div className="sec-label">{children}{right && <span style={{ flex: "none", textTransform: "none", letterSpacing: 0 }}>{right}</span>}</div>;
}

// mini bar chart
function MiniBars({ data, max, height = 64, accent = "var(--accent)" }) {
  const mx = max || Math.max(...data.map((d) => d.v));
  return (
    <div style={{ display: "flex", alignItems: "flex-end", gap: 8, height }}>
      {data.map((d, i) =>
      <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 6, height: "100%" }}>
          <div style={{ flex: 1, width: "100%", display: "flex", alignItems: "flex-end" }}>
            <div style={{ width: "100%", height: d.v / mx * 100 + "%", minHeight: 3, borderRadius: "5px 5px 0 0",
            background: i === data.length - 1 ? accent : "color-mix(in srgb, var(--muted) 32%, transparent)", transition: "height .5s var(--ease)" }} />
          </div>
          <span style={{ fontSize: 10.5, color: "var(--muted)" }}>{d.m}</span>
        </div>
      )}
    </div>);

}

function Bar({ value, tone, style }) {
  return <div className={"bar " + (tone || "")} style={style}><span style={{ width: Math.min(100, value) + "%" }} /></div>;
}

// Upload de imagem único — preview + botão trocar/remover
function ImgUpload({ value, onChange, folder, height = 160, toast }) {
  const inputRef = useRef(null);
  const [busy, setBusy] = useState(false);
  const pick = () => inputRef.current && inputRef.current.click();
  const handle = async (e) => {
    const file = e.target.files && e.target.files[0];
    e.target.value = "";
    if (!file) return;
    if (!window.pcpStorage || !window.pcpStorage.ready()) {
      toast && toast("Storage não disponível", "crit", { sub: "verifique a conexão e o login" });
      return;
    }
    setBusy(true);
    try {
      const { url, path } = await window.pcpStorage.upload(file, folder);
      onChange && onChange({ url, path });
    } catch (err) {
      toast && toast(err.message || "Falha ao enviar imagem", "crit");
    }
    setBusy(false);
  };
  const remove = async () => {
    if (value && value.path && window.pcpStorage) await window.pcpStorage.remove(value.path);
    onChange && onChange(null);
  };
  const hasImg = value && value.url;
  return (
    <div>
      <input ref={inputRef} type="file" accept="image/*" style={{ display: "none" }} onChange={handle} />
      <div className="img-slot" style={{ height, position: "relative", cursor: busy ? "default" : "pointer", padding: 0, overflow: "hidden" }}
        onClick={() => !busy && !hasImg && pick()}>
        {hasImg ? (
          <img src={value.url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
        ) : busy ? (
          <div className="row gap8 muted small"><Icon name="refresh" size={14} /> Enviando…</div>
        ) : (
          <div className="row gap8 muted small"><Icon name="image" size={16} /> Clique para adicionar foto</div>
        )}
      </div>
      {hasImg && (
        <div className="row gap8" style={{ marginTop: 8 }}>
          <Btn size="sm" icon="image" onClick={pick} disabled={busy}>Trocar</Btn>
          <Btn size="sm" icon="trash" onClick={remove} disabled={busy}>Remover</Btn>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { Icon, Btn, IconBtn, Badge, MetricCard, Empty, SectionLabel, MiniBars, Bar, ImgUpload });