// ============ Charts (pure SVG) ============

// Sparkline
const Sparkline = ({ data, width = 120, height = 36, color = "var(--accent)", fill = true }) => {
  if (!data || data.length === 0) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const span = max - min || 1;
  const step = width / (data.length - 1);
  const points = data.map((v, i) => [i * step, height - ((v - min) / span) * (height - 4) - 2]);
  const d = points.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + "," + p[1].toFixed(1)).join(" ");
  const area = d + ` L ${width},${height} L 0,${height} Z`;
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      {fill && <path d={area} fill={color} opacity="0.15"/>}
      <path d={d} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
};

// Line chart with axes, grid, hover
const LineChart = ({ data, labels, height = 260, yLabel = "", color = "var(--accent)", onHover }) => {
  const ref = React.useRef(null);
  const [w, setW] = React.useState(800);
  React.useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(entries => {
      setW(Math.max(320, entries[0].contentRect.width));
    });
    ro.observe(ref.current);
    return () => ro.disconnect();
  }, []);

  const [hover, setHover] = React.useState(null);

  const pad = { l: 48, r: 18, t: 16, b: 30 };
  const iw = w - pad.l - pad.r;
  const ih = height - pad.t - pad.b;

  const min = 0;
  const max = Math.max(...data) * 1.1 || 1;
  const step = iw / (data.length - 1);
  const points = data.map((v, i) => [pad.l + i * step, pad.t + ih - (v / max) * ih]);

  const dLine = points.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + "," + p[1].toFixed(1)).join(" ");
  const dArea = dLine + ` L ${pad.l + iw},${pad.t + ih} L ${pad.l},${pad.t + ih} Z`;

  // Y ticks
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(t => ({
    y: pad.t + ih - t * ih,
    v: Math.round(max * t),
  }));

  // interactivity
  const onMove = (e) => {
    const rect = ref.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const idx = Math.max(0, Math.min(data.length - 1, Math.round((x - pad.l) / step)));
    setHover({ idx, x: points[idx][0], y: points[idx][1] });
    onHover && onHover(idx);
  };
  const onLeave = () => { setHover(null); onHover && onHover(null); };

  return (
    <div ref={ref} style={{ position: "relative", width: "100%" }}>
      <svg width={w} height={height} onMouseMove={onMove} onMouseLeave={onLeave}>
        <defs>
          <linearGradient id="area-grad" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.35"/>
            <stop offset="100%" stopColor={color} stopOpacity="0"/>
          </linearGradient>
        </defs>

        {/* grid */}
        {ticks.map((t, i) => (
          <g key={i}>
            <line x1={pad.l} x2={pad.l + iw} y1={t.y} y2={t.y} stroke="var(--line)" strokeDasharray="2 4"/>
            <text x={pad.l - 8} y={t.y + 4} fill="var(--text-faint)" fontSize="10" textAnchor="end" fontFamily="JetBrains Mono">
              {t.v.toLocaleString()}
            </text>
          </g>
        ))}

        {/* x labels */}
        {labels && labels.map((l, i) => {
          if (labels.length > 12 && i % Math.ceil(labels.length / 8) !== 0 && i !== labels.length - 1) return null;
          return (
            <text key={i} x={pad.l + i * step} y={height - 10} fill="var(--text-faint)" fontSize="10" textAnchor="middle" fontFamily="JetBrains Mono">
              {l}
            </text>
          );
        })}

        {/* area + line with draw animation */}
        <path d={dArea} fill="url(#area-grad)">
          <animate attributeName="opacity" from="0" to="1" dur="700ms" fill="freeze" />
        </path>
        <path d={dLine} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
          style={{ filter: "drop-shadow(0 0 6px " + color + ")" }}>
          <animate attributeName="stroke-dasharray" from="0 9999" to="9999 0" dur="1100ms" fill="freeze" />
        </path>

        {/* hover */}
        {hover && (
          <g>
            <line x1={hover.x} x2={hover.x} y1={pad.t} y2={pad.t + ih} stroke={color} strokeOpacity="0.4" strokeDasharray="2 2"/>
            <circle cx={hover.x} cy={hover.y} r="4" fill={color} stroke="#fff" strokeWidth="1.2"/>
          </g>
        )}
      </svg>

      {hover && (
        <div className="tt" style={{ left: hover.x, top: hover.y }}>
          <div className="t-title">{labels ? labels[hover.idx] : hover.idx}</div>
          <div className="t-val">{data[hover.idx].toLocaleString()}</div>
        </div>
      )}
    </div>
  );
};

// Bar chart (horizontal, for top terms)
const BarRow = ({ label, value, max, sub, color = "var(--accent)" }) => {
  const pct = (value / max) * 100;
  return (
    <div style={{ display: "grid", gridTemplateColumns: "160px 1fr 90px", gap: 10, alignItems: "center", padding: "8px 0" }}>
      <div style={{ fontSize: 13, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{label}</div>
      <div style={{ position: "relative", height: 10, borderRadius: 6, background: "var(--bg-2)" }}>
        <div style={{
          position: "absolute", inset: 0, width: pct + "%",
          borderRadius: 6,
          background: `linear-gradient(90deg, ${color}66, ${color})`,
          boxShadow: `0 0 10px ${color}55`,
          transition: "width 700ms var(--ease-emph)",
        }}/>
      </div>
      <div className="num-mono" style={{ fontSize: 12, color: "var(--text-dim)", textAlign: "right" }}>
        {value.toLocaleString()}{sub ? <span style={{ color: "var(--text-faint)" }}> · {sub}</span> : null}
      </div>
    </div>
  );
};

// Donut (for a small metric)
const Donut = ({ value, size = 80, stroke = 8, color = "var(--accent)", label }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - Math.min(1, Math.max(0, 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} stroke="var(--line-2)" strokeWidth={stroke} fill="none"/>
        <circle cx={size/2} cy={size/2} r={r} stroke={color} strokeWidth={stroke} fill="none"
          strokeLinecap="round"
          strokeDasharray={c}
          strokeDashoffset={off}
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: "stroke-dashoffset 1.1s var(--ease-emph)", filter: `drop-shadow(0 0 6px ${color})` }}
        />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", fontSize: 14, fontWeight: 600 }}>
        {label}
      </div>
    </div>
  );
};

Object.assign(window, { Sparkline, LineChart, BarRow, Donut });
