// PortalTable Dashboard — lightweight SVG charts (no external libs).
// AreaChart, BarChart, Donut, MiniSpark. All read PortalTable tokens.

const { useState: useStateC } = React;

/* -------------------------------------------------------------------------- */
/* AreaChart — smooth gradient area with hover crosshair + tooltip            */
/* -------------------------------------------------------------------------- */
function AreaChart({ data, height = 200, valuePrefix = "", color = "var(--accent-press)" }) {
  // data: [{ label, value }]
  const [hover, setHover] = useStateC(null);
  const w = 760, h = height, padX = 8, padTop = 14, padBot = 26;
  const vals = data.map((d) => d.value);
  const max = Math.max(...vals) * 1.12 || 1;
  const min = 0;
  const innerW = w - padX * 2, innerH = h - padTop - padBot;
  const x = (i) => padX + (i / (data.length - 1)) * innerW;
  const y = (v) => padTop + innerH - ((v - min) / (max - min)) * innerH;

  // smooth path (catmull-rom -> bezier)
  function smooth(points) {
    if (points.length < 2) return "";
    let d = `M ${points[0][0]},${points[0][1]}`;
    for (let i = 0; i < points.length - 1; i++) {
      const p0 = points[i - 1] || points[i];
      const p1 = points[i], p2 = points[i + 1];
      const p3 = points[i + 2] || p2;
      const c1x = p1[0] + (p2[0] - p0[0]) / 6, c1y = p1[1] + (p2[1] - p0[1]) / 6;
      const c2x = p2[0] - (p3[0] - p1[0]) / 6, c2y = p2[1] - (p3[1] - p1[1]) / 6;
      d += ` C ${c1x},${c1y} ${c2x},${c2y} ${p2[0]},${p2[1]}`;
    }
    return d;
  }
  const pts = data.map((d, i) => [x(i), y(d.value)]);
  const line = smooth(pts);
  const area = `${line} L ${x(data.length - 1)},${padTop + innerH} L ${x(0)},${padTop + innerH} Z`;
  const gid = "areaGrad" + Math.round(height);

  return (
    <div style={{ position: "relative", width: "100%" }}>
      <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} preserveAspectRatio="none"
        onMouseLeave={() => setHover(null)}
        onMouseMove={(e) => {
          const rect = e.currentTarget.getBoundingClientRect();
          const px = ((e.clientX - rect.left) / rect.width) * w;
          let idx = Math.round(((px - padX) / innerW) * (data.length - 1));
          idx = Math.max(0, Math.min(data.length - 1, idx));
          setHover(idx);
        }}>
        <defs>
          <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.22" />
            <stop offset="100%" stopColor={color} stopOpacity="0.01" />
          </linearGradient>
        </defs>
        {/* gridlines */}
        {[0.25, 0.5, 0.75, 1].map((g) => (
          <line key={g} x1={padX} x2={w - padX} y1={padTop + innerH * g} y2={padTop + innerH * g} stroke="var(--line-1)" strokeWidth="1" />
        ))}
        <path d={area} fill={`url(#${gid})`} />
        <path d={line} fill="none" stroke={color} strokeWidth="2" vectorEffect="non-scaling-stroke" />
        {hover !== null && (
          <g>
            <line x1={x(hover)} x2={x(hover)} y1={padTop} y2={padTop + innerH} stroke="var(--line-3)" strokeWidth="1" strokeDasharray="3 3" vectorEffect="non-scaling-stroke" />
            <circle cx={x(hover)} cy={y(data[hover].value)} r="4" fill="var(--ink-900)" stroke={color} strokeWidth="2" vectorEffect="non-scaling-stroke" />
          </g>
        )}
      </svg>
      {/* x labels */}
      <div style={{ display: "flex", justifyContent: "space-between", padding: "0 6px", marginTop: -18 }}>
        {data.map((d, i) => (
          <span key={i} style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--fg-4)", opacity: data.length > 8 && i % 2 ? 0 : 1 }}>{d.label}</span>
        ))}
      </div>
      {hover !== null && (
        <div style={{
          position: "absolute", top: 0, left: `${(x(hover) / w) * 100}%`, transform: "translateX(-50%)",
          pointerEvents: "none", background: "var(--ink-900)", border: "1px solid var(--line-3)", borderRadius: 8,
          padding: "6px 10px", boxShadow: "var(--pd-shadow-md)", whiteSpace: "nowrap",
        }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--fg-1)" }}>{valuePrefix}{data[hover].value.toLocaleString()}</div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--fg-3)" }}>{data[hover].label}</div>
        </div>
      )}
    </div>
  );
}

/* -------------------------------------------------------------------------- */
/* BarChart — vertical bars with hover                                         */
/* -------------------------------------------------------------------------- */
function BarChart({ data, height = 180, color = "var(--accent)", valuePrefix = "" }) {
  const [hover, setHover] = useStateC(null);
  const max = Math.max(...data.map((d) => d.value)) * 1.1 || 1;
  return (
    <div style={{ width: "100%" }}>
      <div style={{ display: "flex", alignItems: "flex-end", gap: 10, height, padding: "0 2px" }}>
        {data.map((d, i) => (
          <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 8, height: "100%", justifyContent: "flex-end", position: "relative" }}
            onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
            {hover === i && (
              <div style={{ position: "absolute", top: -6, transform: "translateY(-100%)", background: "var(--ink-900)", border: "1px solid var(--line-3)", borderRadius: 7, padding: "4px 8px", fontSize: 12, fontWeight: 600, color: "var(--fg-1)", boxShadow: "var(--pd-shadow-md)", whiteSpace: "nowrap", zIndex: 2 }}>
                {valuePrefix}{d.value.toLocaleString()}
              </div>
            )}
            <div style={{
              width: "100%", maxWidth: 38, height: `${(d.value / max) * 100}%`, minHeight: 3,
              background: hover === i ? "var(--accent-press)" : (d.color || color), borderRadius: "6px 6px 3px 3px",
              transition: "height var(--dur-4) var(--ease-out), background var(--dur-2) var(--ease-out)",
            }} />
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--fg-4)" }}>{d.label}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* -------------------------------------------------------------------------- */
/* Donut — segmented ring + center label + legend                             */
/* -------------------------------------------------------------------------- */
function Donut({ segments, size = 150, thickness = 18, centerLabel, centerValue }) {
  // segments: [{ label, value, color }]
  const total = segments.reduce((s, x) => s + x.value, 0) || 1;
  const r = (size - thickness) / 2;
  const c = 2 * Math.PI * r;
  let offset = 0;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 24, flexWrap: "wrap" }}>
      <div style={{ position: "relative", width: size, height: size, flexShrink: 0 }}>
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ transform: "rotate(-90deg)" }}>
          <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="var(--ink-800)" strokeWidth={thickness} />
          {segments.map((s, i) => {
            const len = (s.value / total) * c;
            const el = (
              <circle key={i} cx={size / 2} cy={size / 2} r={r} fill="none" stroke={s.color} strokeWidth={thickness}
                strokeDasharray={`${len} ${c - len}`} strokeDashoffset={-offset} strokeLinecap="butt" />
            );
            offset += len;
            return el;
          })}
        </svg>
        <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
          <span style={{ fontSize: 26, fontWeight: 600, color: "var(--fg-1)", letterSpacing: "-0.02em" }}>{centerValue}</span>
          {centerLabel && <span style={{ fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--fg-3)" }}>{centerLabel}</span>}
        </div>
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 11, flex: 1, minWidth: 140 }}>
        {segments.map((s, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 9 }}>
            <span style={{ width: 9, height: 9, borderRadius: 3, background: s.color, flexShrink: 0 }} />
            <span style={{ fontSize: 13, color: "var(--fg-2)", flex: 1 }}>{s.label}</span>
            <span style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-1)", fontVariantNumeric: "tabular-nums" }}>{s.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* -------------------------------------------------------------------------- */
/* MiniSpark — tiny inline sparkline for KPI cards                             */
/* -------------------------------------------------------------------------- */
function MiniSpark({ points, color = "var(--accent-press)", up = true, width = 96, height = 30 }) {
  const max = Math.max(...points), min = Math.min(...points), range = max - min || 1;
  const step = width / (points.length - 1);
  const coords = points.map((p, i) => [i * step, height - ((p - min) / range) * (height - 4) - 2]);
  const poly = coords.map(([x, y]) => `${x.toFixed(1)},${y.toFixed(1)}`).join(" ");
  const stroke = up ? "var(--green)" : "var(--red)";
  const gid = "spk" + Math.round(Math.random() * 1e6);
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{ display: "block" }}>
      <defs><linearGradient id={gid} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor={stroke} stopOpacity="0.18" /><stop offset="100%" stopColor={stroke} stopOpacity="0" /></linearGradient></defs>
      <polygon points={`0,${height} ${poly} ${width},${height}`} fill={`url(#${gid})`} />
      <polyline points={poly} fill="none" stroke={stroke} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

Object.assign(window, { AreaChart, BarChart, Donut, MiniSpark });
