/* ============================================================
   CHARTS — SVG monocromáticos, fieles a la marca
   LineChart (con hover) + Sparkline
   ============================================================ */
const { useState: useStateCh, useRef: useRefCh, useMemo: useMemoCh } = React;

function niceMax(v) {
  if (v <= 0) return 1;
  const pow = Math.pow(10, Math.floor(Math.log10(v)));
  const n = v / pow;
  let step;
  if (n <= 1) step = 1;
  else if (n <= 2) step = 2;
  else if (n <= 2.5) step = 2.5;
  else if (n <= 5) step = 5;
  else step = 10;
  return step * pow;
}

// ----- LINE CHART -----------------------------------------------
function LineChart({ data, valueKey = "value", format = (v) => v, height = 150, accent = "var(--ink)" }) {
  const wrapRef = useRefCh(null);
  const [w, setW] = useStateCh(680);
  const [hover, setHover] = useStateCh(null);

  React.useEffect(() => {
    if (!wrapRef.current) return;
    const ro = new ResizeObserver((entries) => {
      for (const e of entries) setW(Math.max(280, e.contentRect.width));
    });
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  const padL = 38, padR = 12, padT = 12, padB = 22;
  const innerW = w - padL - padR;
  const innerH = height - padT - padB;

  const vals = data.map((d) => (d[valueKey] == null ? 0 : d[valueKey]));
  const rawMax = Math.max(...vals, 1);
  const yMax = niceMax(rawMax * 1.08);
  const n = data.length;

  const x = (i) => padL + (n <= 1 ? 0 : (i / (n - 1)) * innerW);
  const y = (v) => padT + innerH - (v / yMax) * innerH;

  const linePath = data.map((d, i) => `${i === 0 ? "M" : "L"} ${x(i).toFixed(1)} ${y(d[valueKey] || 0).toFixed(1)}`).join(" ");
  const areaPath = `${linePath} L ${x(n - 1).toFixed(1)} ${(padT + innerH).toFixed(1)} L ${x(0).toFixed(1)} ${(padT + innerH).toFixed(1)} Z`;

  const gridVals = [0, 0.5, 1].map((f) => yMax * f);

  // etiquetas X: ~5 puntos
  const xticks = [];
  const step = Math.max(1, Math.floor(n / 5));
  for (let i = 0; i < n; i += step) xticks.push(i);
  if (xticks[xticks.length - 1] !== n - 1) xticks.push(n - 1);

  function onMove(e) {
    const rect = e.currentTarget.getBoundingClientRect();
    const px = ((e.clientX - rect.left) / rect.width) * w;
    let idx = Math.round(((px - padL) / innerW) * (n - 1));
    idx = Math.max(0, Math.min(n - 1, idx));
    setHover(idx);
  }

  const hv = hover != null ? data[hover] : null;

  return (
    <div className="chart" ref={wrapRef} style={{ position: "relative" }}>
      <svg viewBox={`0 0 ${w} ${height}`} onMouseMove={onMove} onMouseLeave={() => setHover(null)}>
        {gridVals.map((gv, i) => (
          <g key={i}>
            <line className="grid-line" x1={padL} x2={w - padR} y1={y(gv)} y2={y(gv)} />
            <text className="axis-y" x={padL - 8} y={y(gv) + 3} textAnchor="end">{fmt.compact(gv)}</text>
          </g>
        ))}
        <path className="series-area" d={areaPath} style={{ fill: "rgba(17,17,17,0.045)" }} />
        <path className="series-line" d={linePath} style={{ stroke: accent }} />
        {xticks.map((i) => (
          <text key={i} className="axis-x" x={x(i)} y={height - 6} textAnchor={i === 0 ? "start" : i === n - 1 ? "end" : "middle"}>
            {fmt.fecha(data[i].fecha)}
          </text>
        ))}
        {/* punto final */}
        <circle className="dot-last" cx={x(n - 1)} cy={y(data[n - 1][valueKey] || 0)} r={3} style={{ fill: accent }} />
        {/* hover */}
        {hv && (
          <g>
            <line className="hover-x" x1={x(hover)} x2={x(hover)} y1={padT} y2={padT + innerH} />
            <circle cx={x(hover)} cy={y(hv[valueKey] || 0)} r={4} fill="var(--white)" stroke={accent} strokeWidth="1.75" />
          </g>
        )}
      </svg>
      {hv && (
        <div className="ch-tip" style={{ left: `${(x(hover) / w) * 100}%`, top: `${(y(hv[valueKey] || 0) / height) * 100}%` }}>
          <div className="tk">{fmt.fecha(hv.fecha)}</div>
          <div className="tf">{format(hv[valueKey])}</div>
        </div>
      )}
    </div>
  );
}

// ----- SPARKLINE ------------------------------------------------
function Sparkline({ data, valueKey = "value", width = 96, height = 30, accent = "var(--ink)" }) {
  const vals = data.map((d) => (d[valueKey] == null ? 0 : d[valueKey]));
  const max = Math.max(...vals, 1);
  const min = Math.min(...vals, 0);
  const n = data.length;
  const x = (i) => (n <= 1 ? 0 : (i / (n - 1)) * (width - 2) + 1);
  const y = (v) => height - 3 - ((v - min) / (max - min || 1)) * (height - 6);
  const path = data.map((d, i) => `${i === 0 ? "M" : "L"} ${x(i).toFixed(1)} ${y(d[valueKey] || 0).toFixed(1)}`).join(" ");
  return (
    <span className="spark">
      <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
        <path d={path} fill="none" stroke={accent} strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" />
        <circle cx={x(n - 1)} cy={y(data[n - 1][valueKey] || 0)} r="1.8" fill={accent} />
      </svg>
    </span>
  );
}

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