/* global React */
const { useMemo, useState, useEffect, useRef } = React;

/* =====================================================
   Reusable atoms
===================================================== */

const I = ({ name, size = 18, stroke = 2, className = "", style }) => (
  <i data-lucide={name} style={{ width: size, height: size, strokeWidth: stroke, ...(style||{}) }} className={className}></i>
);

const Icon = I;

const Chip = ({ tone = "default", children, dot, leading }) => (
  <span className={`chip ${tone !== "default" ? `chip-${tone}` : ""}`}>
    {dot ? <span className={`dot ${dot}`}></span> : null}
    {leading ? leading : null}
    {children}
  </span>
);

const Btn = ({ as = "button", variant = "ghost", size = "md", iconOnly = false, children, ...props }) => {
  const Tag = as;
  const cls = [
    "btn",
    variant === "primary"   ? "btn-primary"
    : variant === "secondary" ? "btn-secondary"
    : variant === "outline"   ? "btn-outline"
    : variant === "danger"    ? "btn-danger"
    : "btn-ghost",
    size === "sm" ? "btn-sm" : "",
    iconOnly ? "btn-icon" : "",
    props.className || "",
  ].filter(Boolean).join(" ");
  return <Tag {...props} className={cls}>{children}</Tag>;
};

const Card = ({ as = "div", className = "", style, children, hover = false, padding = 18, ...rest }) => {
  const Tag = as;
  return (
    <Tag className={`card ${hover ? "card-hover" : ""} ${className}`} style={{ padding, ...(style || {}) }} {...rest}>
      {children}
    </Tag>
  );
};

const Eyebrow = ({ children }) => <div className="eyebrow">{children}</div>;

const SectionTitle = ({ title, sub, action }) => (
  <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginBottom: 12 }}>
    <div>
      <h3 className="section-title">{title}</h3>
      {sub ? <div style={{ color: "var(--fg-3)", fontSize: 12, marginTop: 2 }}>{sub}</div> : null}
    </div>
    {action || null}
  </div>
);

/* =====================================================
   Charts (inline SVG — no external libs)
===================================================== */

const AreaChart = ({ series, height = 220, color1 = "var(--primary)", color2 = "var(--violet-500)" }) => {
  const ref = useRef(null);
  const [w, setW] = useState(600);
  useEffect(() => {
    const ro = new ResizeObserver(entries => {
      const cw = entries[0].contentRect.width;
      setW(cw);
    });
    if (ref.current) ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);

  const padX = 8, padY = 10;
  const all = series.flatMap(s => s.values);
  const max = Math.max(...all) * 1.1 || 1;

  const yOf = (v) => height - padY - (v / max) * (height - padY * 2);

  const buildPath = (vals, sm = true) => {
    const n = vals.length;
    if (n === 0) return "";
    if (n === 1) { const y = yOf(vals[0]); return `M ${padX} ${y} L ${w - padX} ${y}`; }
    const dx = (w - padX * 2) / (n - 1);
    const ys = vals.map(v => height - padY - (v / max) * (height - padY * 2));
    let d = `M ${padX} ${ys[0]}`;
    for (let i = 1; i < n; i++) {
      const x = padX + dx * i;
      const px = padX + dx * (i - 1);
      const py = ys[i - 1];
      const cx1 = px + dx * 0.4;
      const cx2 = x - dx * 0.4;
      d += sm ? ` C ${cx1} ${py}, ${cx2} ${ys[i]}, ${x} ${ys[i]}` : ` L ${x} ${ys[i]}`;
    }
    return d;
  };

  const buildArea = (vals) => {
    const n = vals.length;
    if (n === 0) return "";
    if (n === 1) {
      const y = yOf(vals[0]);
      return `M ${padX} ${y} L ${w - padX} ${y} L ${w - padX} ${height - padY} L ${padX} ${height - padY} Z`;
    }
    const dx = (w - padX * 2) / (n - 1);
    const line = buildPath(vals);
    return `${line} L ${padX + dx * (n - 1)} ${height - padY} L ${padX} ${height - padY} Z`;
  };

  const gridY = 4;
  return (
    <div ref={ref} style={{ width: "100%" }}>
      <svg width={w} height={height} style={{ display: "block" }}>
        <defs>
          <linearGradient id="ac-grad-0" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color1} stopOpacity="0.35" />
            <stop offset="100%" stopColor={color1} stopOpacity="0" />
          </linearGradient>
          <linearGradient id="ac-grad-1" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color2} stopOpacity="0.30" />
            <stop offset="100%" stopColor={color2} stopOpacity="0" />
          </linearGradient>
        </defs>
        {[...Array(gridY)].map((_, i) => {
          const y = padY + ((height - padY * 2) / (gridY - 1)) * i;
          return <line key={i} x1={padX} x2={w - padX} y1={y} y2={y} stroke="var(--border)" strokeDasharray="3 4" />;
        })}
        {series.map((s, i) => (
          <g key={s.label}>
            <path d={buildArea(s.values)} fill={`url(#ac-grad-${i})`} />
            <path d={buildPath(s.values)} fill="none" stroke={i === 0 ? color1 : color2} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" />
          </g>
        ))}
      </svg>
    </div>
  );
};

const Bars = ({ data, height = 200, barColor = "var(--primary)" }) => {
  // data: [{label, value}]
  const ref = useRef(null);
  const [w, setW] = useState(600);
  useEffect(() => {
    const ro = new ResizeObserver(e => setW(e[0].contentRect.width));
    if (ref.current) ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);
  const max = Math.max(...data.map(d => d.value)) * 1.15 || 1;
  const padY = 24;
  const gap = 12;
  const bw = Math.max(6, (w - gap * (data.length - 1)) / data.length);

  return (
    <div ref={ref}>
      <svg width={w} height={height + padY} style={{ display: "block" }}>
        <defs>
          <linearGradient id="bar-grad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={barColor} stopOpacity="1" />
            <stop offset="100%" stopColor="var(--violet-500)" stopOpacity="0.85" />
          </linearGradient>
        </defs>
        {data.map((d, i) => {
          const h = (d.value / max) * height;
          const x = i * (bw + gap);
          const y = padY + (height - h);
          return (
            <g key={d.label}>
              <rect x={x} y={y} width={bw} height={h} rx="6" fill="url(#bar-grad)" />
              <text x={x + bw / 2} y={padY + height + 14} textAnchor="middle" fontSize="10" fill="var(--fg-3)" fontFamily="Space Grotesk">{d.label}</text>
              <text x={x + bw / 2} y={y - 6} textAnchor="middle" fontSize="11" fill="var(--fg-1)" fontFamily="Space Grotesk" fontWeight="600">{d.short || d.value}</text>
            </g>
          );
        })}
      </svg>
    </div>
  );
};

const Donut = ({ slices, size = 160, stroke = 22, center }) => {
  const r = size / 2 - stroke / 2;
  const c = 2 * Math.PI * r;
  const total = slices.reduce((s, x) => s + x.value, 0) || 1;
  let offset = 0;
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} className="donut-svg">
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--bg-elev-2)" strokeWidth={stroke} />
        {slices.map((s, i) => {
          const len = (s.value / total) * c;
          const seg = <circle
            key={i} cx={size / 2} cy={size / 2} r={r} fill="none"
            stroke={s.color} strokeWidth={stroke}
            strokeDasharray={`${len} ${c - len}`}
            strokeDashoffset={-offset}
            strokeLinecap="butt"
          />;
          offset += len;
          return seg;
        })}
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        {center}
      </div>
    </div>
  );
};

const Sparkline = ({ values, color = "var(--primary)", width = 80, height = 24 }) => {
  const max = Math.max(...values), min = Math.min(...values);
  const rng = max - min || 1;
  const pts = values.map((v, i) => {
    const x = values.length > 1 ? (i / (values.length - 1)) * width : width / 2;
    const y = height - ((v - min) / rng) * height;
    return `${x},${y}`;
  }).join(" ");
  return (
    <svg width={width} height={height}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
};

/* =====================================================
   BRL formatter
===================================================== */
const brl = (v) => "R$ " + (Number(v) || 0).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const brlShort = (v) => {
  const n = Number(v) || 0;
  if (Math.abs(n) >= 1000) return "R$ " + (n / 1000).toLocaleString("pt-BR", { maximumFractionDigits: 1 }) + "k";
  return brl(n);
};
const pct = (v, d = 1) => {
  const n = Number(v) || 0;
  return (n >= 0 ? "+" : "") + n.toFixed(d).replace(".", ",") + "%";
};

/* =====================================================
   Toast — feedback simples para ações sem destino próprio
===================================================== */
function vendusToast(message, opts = {}) {
  const { tone = "default", icon = "check-circle", duration = 2400 } = opts;
  let stack = document.getElementById("vendus-toast-stack");
  if (!stack) {
    stack = document.createElement("div");
    stack.id = "vendus-toast-stack";
    Object.assign(stack.style, {
      position: "fixed", right: "24px", bottom: "24px", zIndex: 9999,
      display: "flex", flexDirection: "column", gap: "8px",
      pointerEvents: "none", maxWidth: "360px"
    });
    document.body.appendChild(stack);
  }
  const toneColor = {
    success: ["#22C55E", "rgba(34,197,94,.15)", "rgba(34,197,94,.3)"],
    warning: ["#FACC15", "rgba(250,204,21,.15)", "rgba(250,204,21,.3)"],
    danger:  ["#EF4444", "rgba(239,68,68,.15)", "rgba(239,68,68,.3)"],
    info:    ["#789BFF", "rgba(120,155,255,.15)", "rgba(120,155,255,.3)"],
    violet:  ["#C4B5FD", "rgba(139,92,246,.15)", "rgba(139,92,246,.3)"],
    default: ["#FB923C", "rgba(249,115,22,.15)", "rgba(249,115,22,.3)"],
  }[tone] || ["#FB923C", "rgba(249,115,22,.15)", "rgba(249,115,22,.3)"];

  const toast = document.createElement("div");
  Object.assign(toast.style, {
    background: "var(--bg-surface)",
    border: "1px solid var(--border-strong)",
    borderRadius: "12px",
    padding: "12px 14px",
    display: "flex", alignItems: "center", gap: "12px",
    color: "var(--fg-1)",
    fontSize: "13px",
    fontFamily: "var(--font-sans)",
    fontWeight: "500",
    boxShadow: "var(--shadow-3)",
    pointerEvents: "auto",
    opacity: "0", transform: "translateY(10px)",
    transition: "opacity .2s ease, transform .2s ease",
  });
  toast.innerHTML = `
    <span style="width:30px;height:30px;border-radius:8px;display:grid;place-items:center;flex-shrink:0;background:${toneColor[1]};color:${toneColor[0]};border:1px solid ${toneColor[2]};">
      <i data-lucide="${icon}" style="width:16px;height:16px;stroke-width:2;"></i>
    </span>
    <span style="flex:1;min-width:0;">${message}</span>
  `;
  stack.appendChild(toast);
  if (window.lucide) window.lucide.createIcons();
  requestAnimationFrame(() => {
    toast.style.opacity = "1";
    toast.style.transform = "translateY(0)";
  });
  setTimeout(() => {
    toast.style.opacity = "0";
    toast.style.transform = "translateY(10px)";
    setTimeout(() => toast.remove(), 250);
  }, duration);
}

/* Estado vazio — usado quando o usuário ainda não tem dados (loja recém-criada) */
const EmptyState = ({ icon = "inbox", title, desc, cta, onCta }) => (
  <Card padding={48}>
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", padding: "32px 20px", gap: 12 }}>
      <div style={{ width: 60, height: 60, borderRadius: 16, background: "var(--bg-elev)", display: "grid", placeItems: "center", color: "var(--fg-2)" }}>
        <I name={icon} size={26} />
      </div>
      <div className="font-display" style={{ fontSize: 18, fontWeight: 700 }}>{title}</div>
      {desc && <div className="text-muted" style={{ fontSize: 13.5, maxWidth: 380, lineHeight: 1.55 }}>{desc}</div>}
      {cta && <div style={{ marginTop: 6 }}><Btn variant="primary" onClick={onCta}><I name="plus" size={14} /> {cta}</Btn></div>}
    </div>
  </Card>
);

window.vendusToast = vendusToast;
window.VendusAtoms = { I, Icon, Chip, Btn, Card, Eyebrow, SectionTitle, AreaChart, Bars, Donut, Sparkline, EmptyState, brl, brlShort, pct };
