// Chart primitives for the story template.
// Hand-rolled SVG — matches the warm-paper aesthetic better than
// Recharts and avoids a 200KB script tag. Recharts is approved
// for ordinary line/area charts in non-hero contexts (see README).

const { useEffect: chartsUseEffect, useState: chartsUseState, useRef: chartsUseRef } = React;

/* =========================================================
   BigStat — animated count-up of a hero number.
   ========================================================= */

function BigStat({ value, suffix = "", duration = 900 }) {
  const [n, setN] = chartsUseState(0);
  const start = chartsUseRef(null);
  chartsUseEffect(() => {
    let raf;
    const tick = (t) => {
      if (!start.current) start.current = t;
      const p = Math.min(1, (t - start.current) / duration);
      // ease-out cubic
      const eased = 1 - Math.pow(1 - p, 3);
      setN(value * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [value, duration]);
  const display = Number.isInteger(value) ? Math.round(n) : n.toFixed(1);
  return (
    <span className="stat-big">
      {display}
      {suffix ? <sup>{suffix}</sup> : null}
    </span>
  );
}

/* =========================================================
   BarsChart — vertical-label horizontal bars.
   Animates the fill width on mount.
   ========================================================= */

function BarsChart({ series, max, unit = "%" }) {
  const m = max || Math.max(...series.map((s) => s.value)) * 1.1;
  return (
    <div className="bars-chart">
      {series.map((s, i) => (
        <div className="bar-row" key={i}>
          <div className="bar-label">{s.label}</div>
          <div className="bar-track">
            <div
              className="bar-fill"
              style={{ "--w": `${(s.value / m) * 100}%`, animationDelay: `${i * 120}ms` }}
            />
            <span className="bar-value">{s.value}{unit}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

/* =========================================================
   Donut — single-percentage donut. Reserved for future beats.
   ========================================================= */

function Donut({ value, size = 200, stroke = 28, label }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const offset = c * (1 - value / 100);
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle
        cx={size / 2} cy={size / 2} r={r}
        fill="none"
        stroke="currentColor" strokeOpacity="0.18"
        strokeWidth={stroke}
      />
      <circle
        cx={size / 2} cy={size / 2} r={r}
        fill="none"
        stroke="var(--brand)"
        strokeWidth={stroke}
        strokeDasharray={c}
        strokeDashoffset={offset}
        transform={`rotate(-90 ${size / 2} ${size / 2})`}
        style={{ transition: "stroke-dashoffset 900ms cubic-bezier(.16,1,.3,1)" }}
      />
      <text
        x="50%" y="50%"
        textAnchor="middle" dominantBaseline="central"
        fontFamily="var(--primary-heading)" fontWeight="900"
        fontSize={size * 0.32}
        fill="var(--brand)"
      >{value}%</text>
      {label ? (
        <text
          x="50%" y="78%"
          textAnchor="middle"
          fontFamily="var(--mono)" fontSize="10"
          letterSpacing="0.1em"
          textTransform="uppercase"
          fill="currentColor" opacity="0.55"
        >{label}</text>
      ) : null}
    </svg>
  );
}

Object.assign(window, { BigStat, BarsChart, Donut });
