// Lumen — Charts (lightweight SVG, no deps)

// Sparkline
function Sparkline({ data, width = 120, height = 36, color = "currentColor", fill = false }) {
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const stepX = width / (data.length - 1);
  const points = data.map((v, i) => [i * stepX, height - ((v - min) / range) * (height - 4) - 2]);
  const path = points.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(" ");
  const fillPath = `${path} L${width},${height} L0,${height} Z`;
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{ display: "block" }}>
      {fill && <path d={fillPath} fill={color} fillOpacity="0.08" />}
      <path d={path} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// Area chart with axis + hover
function AreaChart({ data, height = 220, color = "var(--ink)", labels, format = (v) => v }) {
  const [hover, setHover] = React.useState(null);
  const ref = React.useRef(null);
  const [w, setW] = React.useState(800);
  React.useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(es => setW(es[0].contentRect.width));
    ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);

  const padL = 36, padR = 12, padT = 10, padB = 22;
  const innerW = Math.max(0, w - padL - padR);
  const innerH = height - padT - padB;
  const min = 0;
  const max = Math.max(...data) * 1.15 || 1;
  const stepX = innerW / Math.max(1, data.length - 1);
  const points = data.map((v, i) => [padL + i * stepX, padT + innerH - (v / max) * innerH]);
  const path = points.map((p, i) => i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`).join(" ");
  const fillPath = `${path} L${padL + innerW},${padT + innerH} L${padL},${padT + innerH} Z`;

  // y ticks
  const ticks = 4;
  const yTicks = Array.from({ length: ticks + 1 }, (_, i) => (max / ticks) * i);

  return (
    <div ref={ref} style={{ width: "100%", position: "relative" }}>
      <svg width={w} height={height} onMouseLeave={() => setHover(null)}
           onMouseMove={(e) => {
             const rect = e.currentTarget.getBoundingClientRect();
             const x = e.clientX - rect.left;
             const i = Math.round((x - padL) / stepX);
             if (i >= 0 && i < data.length) setHover(i);
           }}>
        {/* grid */}
        {yTicks.map((v, i) => {
          const y = padT + innerH - (v / max) * innerH;
          return (
            <g key={i}>
              <line x1={padL} y1={y} x2={padL + innerW} y2={y} stroke="var(--border)" strokeDasharray="2 4" />
              <text x={padL - 8} y={y + 4} fontSize="10" fill="var(--ink-4)" textAnchor="end" fontFamily="var(--font-mono)">
                {format(Math.round(v))}
              </text>
            </g>
          );
        })}
        {/* x labels */}
        {labels && labels.map((l, i) => {
          if (data.length > 12 && i % Math.ceil(data.length / 8) !== 0) return null;
          return (
            <text key={i} x={padL + i * stepX} y={height - 6} fontSize="10" fill="var(--ink-4)" textAnchor="middle">
              {l}
            </text>
          );
        })}
        {/* area + line */}
        <path d={fillPath} fill={color} fillOpacity="0.06" />
        <path d={path} fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
        {/* hover */}
        {hover != null && (
          <g>
            <line x1={points[hover][0]} y1={padT} x2={points[hover][0]} y2={padT + innerH}
                  stroke="var(--ink)" strokeDasharray="2 3" strokeOpacity=".4" />
            <circle cx={points[hover][0]} cy={points[hover][1]} r="4" fill={color} stroke="var(--bg)" strokeWidth="2" />
          </g>
        )}
      </svg>
      {hover != null && (
        <div style={{
          position: "absolute",
          left: Math.min(points[hover][0] + 10, w - 140),
          top: points[hover][1] - 12,
          background: "var(--ink)", color: "var(--bg)",
          padding: "6px 10px", borderRadius: 6, fontSize: 11, pointerEvents: "none",
          fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap",
          boxShadow: "var(--shadow-md)"
        }}>
          {labels && labels[hover]} · <strong>{format(data[hover])}</strong>
        </div>
      )}
    </div>
  );
}

// Bar chart
function BarChart({ data, height = 200, labels, color = "var(--ink)", format = (v) => v }) {
  const [hover, setHover] = React.useState(null);
  const ref = React.useRef(null);
  const [w, setW] = React.useState(800);
  React.useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(es => setW(es[0].contentRect.width));
    ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);
  const padL = 36, padR = 12, padT = 10, padB = 22;
  const innerW = Math.max(0, w - padL - padR);
  const innerH = height - padT - padB;
  const max = Math.max(...data) * 1.15 || 1;
  const bw = innerW / data.length * 0.6;
  const gap = innerW / data.length * 0.4;
  return (
    <div ref={ref} style={{ width: "100%" }}>
      <svg width={w} height={height}>
        {[0, 0.25, 0.5, 0.75, 1].map((p, i) => {
          const y = padT + innerH * (1 - p);
          return <line key={i} x1={padL} y1={y} x2={padL + innerW} y2={y} stroke="var(--border)" strokeDasharray="2 4" />;
        })}
        {data.map((v, i) => {
          const x = padL + i * (bw + gap) + gap / 2;
          const h = (v / max) * innerH;
          const y = padT + innerH - h;
          return (
            <g key={i} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
              <rect x={x} y={y} width={bw} height={h} rx="2"
                    fill={hover === i ? "var(--ink)" : color}
                    fillOpacity={hover === i ? 1 : 0.85} />
              {labels && (
                <text x={x + bw / 2} y={height - 6} fontSize="10" fill="var(--ink-4)" textAnchor="middle">
                  {labels[i]}
                </text>
              )}
              {hover === i && (
                <text x={x + bw / 2} y={y - 6} fontSize="11" fill="var(--ink)" textAnchor="middle"
                      fontFamily="var(--font-mono)" fontWeight="600">{format(v)}</text>
              )}
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// Donut
function Donut({ value, size = 80, stroke = 8, color = "var(--ink)", label }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const offset = c * (1 - value / 100);
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--bg-sunken)" strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
                strokeLinecap="round" strokeDasharray={c} strokeDashoffset={offset}
                transform={`rotate(-90 ${size/2} ${size/2})`} style={{ transition: "stroke-dashoffset 400ms" }}/>
      </svg>
      <div style={{
        position: "absolute", inset: 0, display: "flex", alignItems: "center",
        justifyContent: "center", flexDirection: "column", fontSize: 14,
        fontWeight: 600, fontVariantNumeric: "tabular-nums", fontFamily: "var(--font-display)",
        letterSpacing: "-0.02em"
      }}>
        {value}%
        {label && <div style={{ fontSize: 10, color: "var(--ink-3)", fontWeight: 500, marginTop: 2 }}>{label}</div>}
      </div>
    </div>
  );
}

// Funnel
function Funnel({ steps }) {
  const max = steps[0].value;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
      {steps.map((s, i) => {
        const pct = (s.value / max) * 100;
        const conv = i > 0 ? ((s.value / steps[i-1].value) * 100).toFixed(1) : null;
        return (
          <div key={i} style={{
            display: "grid", gridTemplateColumns: "150px 1fr 100px 70px",
            alignItems: "center", gap: 12, padding: "10px 0",
            borderBottom: i < steps.length - 1 ? "1px solid var(--border)" : "none"
          }}>
            <div style={{ fontSize: 13, fontWeight: 500 }}>{s.label}</div>
            <div style={{ position: "relative", height: 28, background: "var(--bg-sunken)", borderRadius: 4 }}>
              <div style={{
                position: "absolute", inset: 0, width: `${pct}%`,
                background: "var(--ink)", borderRadius: 4,
                transition: "width 400ms"
              }}/>
            </div>
            <div className="mono" style={{ fontSize: 13, fontWeight: 600 }}>{s.value.toLocaleString()}</div>
            <div className="mono" style={{ fontSize: 11, color: conv && conv > 50 ? "var(--green)" : "var(--ink-3)", textAlign: "right" }}>
              {conv ? `${conv}%` : "—"}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// Heatmap (cohort × week)
function Heatmap({ rows, cols, data, color = "10,10,10" }) {
  const max = Math.max(...data.flat());
  return (
    <div style={{ display: "inline-block" }}>
      <div style={{ display: "grid", gridTemplateColumns: `90px repeat(${cols.length}, 1fr)`, gap: 2 }}>
        <div></div>
        {cols.map((c, i) => (
          <div key={i} style={{ fontSize: 10, color: "var(--ink-3)", textAlign: "center", padding: "2px 0" }}>{c}</div>
        ))}
        {rows.map((r, i) => (
          <React.Fragment key={i}>
            <div style={{ fontSize: 11, color: "var(--ink-2)", padding: "4px 0", display: "flex", alignItems: "center" }}>{r}</div>
            {data[i].map((v, j) => (
              <div key={j} title={`${r} · ${cols[j]}: ${v}%`}
                style={{
                  height: 26,
                  background: `rgba(${color}, ${v / max * 0.95 + 0.05})`,
                  borderRadius: 3,
                  fontSize: 9,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  color: v / max > 0.5 ? "white" : "var(--ink-2)",
                  fontWeight: 600,
                  cursor: "default"
                }}>
                {v}
              </div>
            ))}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

window.Sparkline = Sparkline;
window.AreaChart = AreaChart;
window.BarChart = BarChart;
window.Donut = Donut;
window.Funnel = Funnel;
window.Heatmap = Heatmap;
