// Custom SVG charts

// Smooth path generator
function smoothPath(points) {
  if (points.length < 2) return '';
  let d = `M ${points[0].x} ${points[0].y}`;
  for (let i = 0; i < points.length - 1; i++) {
    const p0 = points[Math.max(0, i - 1)];
    const p1 = points[i];
    const p2 = points[i + 1];
    const p3 = points[Math.min(points.length - 1, i + 2)];
    const cp1x = p1.x + (p2.x - p0.x) / 6;
    const cp1y = p1.y + (p2.y - p0.y) / 6;
    const cp2x = p2.x - (p3.x - p1.x) / 6;
    const cp2y = p2.y - (p3.y - p1.y) / 6;
    d += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
  }
  return d;
}

// --- BarChart: monthly savings
function SavingsChart({ data = [], height = 240 }) {
  const padL = 56, padR = 16, padT = 24, padB = 36;
  const ref = useRef(null);
  const [width, setW] = useState(640);
  useLayoutEffect(() => {
    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 max = Math.max(...data.map(d => d.value)) * 1.15;
  const innerW = width - padL - padR;
  const innerH = height - padT - padB;
  const bw = innerW / data.length;

  return (
    <div ref={ref} style={{ width: '100%' }}>
      <svg width={width} height={height} style={{ display: 'block' }}>
        <defs>
          <linearGradient id="barg" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor="oklch(0.82 0.16 160)"/>
            <stop offset="100%" stopColor="oklch(0.50 0.12 160)"/>
          </linearGradient>
        </defs>
        {[0, 0.25, 0.5, 0.75, 1].map((t, i) => {
          const y = padT + innerH * (1 - t);
          const v = max * t;
          return (
            <g key={i}>
              <line x1={padL} y1={y} x2={width - padR} y2={y} stroke="oklch(0.24 0.012 250)" strokeDasharray={i === 0 ? '' : '3 5'} />
              <text x={padL - 10} y={y + 4} fill="oklch(0.55 0.012 250)" fontSize="10" textAnchor="end" fontFamily="JetBrains Mono">{v >= 1000 ? (v/1000).toFixed(1) + 'k' : v.toFixed(0)}</text>
            </g>
          );
        })}
        {data.map((d, i) => {
          const h = innerH * (d.value / max);
          const x = padL + i * bw + bw * 0.18;
          const y = padT + innerH - h;
          const w = bw * 0.64;
          return (
            <g key={d.m}>
              <rect x={x} y={y} width={w} height={h} fill="url(#barg)" rx="4">
                <animate attributeName="height" from="0" to={h} dur=".5s" fill="freeze" />
                <animate attributeName="y" from={padT + innerH} to={y} dur=".5s" fill="freeze" />
              </rect>
              <text x={x + w / 2} y={padT + innerH + 16} fill="oklch(0.62 0.012 250)" fontSize="11" textAnchor="middle">{d.m}</text>
              <text x={x + w / 2} y={y - 6} fill="oklch(0.94 0.005 250)" fontSize="11" textAnchor="middle" fontFamily="JetBrains Mono" fontWeight="600">{(d.value/1000).toFixed(1)}k</text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

// --- Donut chart: category share
function DonutChart({ data = [], size = 220, thick = 26, onArcClick, centerLabel = 'Total 30d' }) {
  const total = data.reduce((s, d) => s + d.value, 0);
  const r = (size - thick) / 2;
  const cx = size / 2, cy = size / 2;
  let acc = 0;
  const arcs = data.map((d, i) => {
    const start = acc;
    const end = acc + d.value / total;
    acc = end;
    const a1 = start * 2 * Math.PI - Math.PI / 2;
    const a2 = end * 2 * Math.PI - Math.PI / 2;
    const x1 = cx + r * Math.cos(a1), y1 = cy + r * Math.sin(a1);
    const x2 = cx + r * Math.cos(a2), y2 = cy + r * Math.sin(a2);
    const large = end - start > 0.5 ? 1 : 0;
    return { d: `M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2}`, tone: d.tone, label: d.label, value: d.value, raw: d };
  });
  const colorMap = {
    emerald: 'oklch(0.78 0.16 160)',
    coral:   'oklch(0.74 0.18 25)',
    sky:     'oklch(0.78 0.13 230)',
    amber:   'oklch(0.84 0.14 78)',
    violet:  'oklch(0.74 0.14 285)',
  };
  const clickable = !!onArcClick;
  return (
    <div className="scp-donut">
      <svg width={size} height={size}>
        <circle cx={cx} cy={cy} r={r} stroke="oklch(0.24 0.012 250)" strokeWidth={thick} fill="none" />
        {arcs.map((a, i) => (
          <path
            key={i}
            d={a.d}
            stroke={colorMap[a.tone]}
            strokeWidth={thick}
            fill="none"
            strokeLinecap="butt"
            className={clickable ? 'scp-donut-arc' : undefined}
            onClick={clickable ? () => onArcClick(a.raw) : undefined}
          >
            <title>{`${a.label} · ${window.SCP.BRLk(a.value)}`}</title>
          </path>
        ))}
      </svg>
      <div className="scp-donut-center">
        <span className="lbl">{centerLabel}</span>
        <span className="val">{window.SCP.BRLk(total)}</span>
      </div>
    </div>
  );
}

// --- Line chart: price evolution
function LineChart({ data = [], height = 180, color = 'oklch(0.78 0.16 160)' }) {
  const padL = 44, padR = 16, padT = 16, padB = 28;
  const ref = useRef(null);
  const [width, setW] = useState(560);
  useLayoutEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(entries => setW(Math.max(280, entries[0].contentRect.width)));
    ro.observe(ref.current); return () => ro.disconnect();
  }, []);
  const min = Math.min(...data.map(d => d.v));
  const max = Math.max(...data.map(d => d.v));
  const span = max - min || 1;
  const innerW = width - padL - padR;
  const innerH = height - padT - padB;
  const pts = data.map((d, i) => ({
    x: padL + (i / (data.length - 1)) * innerW,
    y: padT + (1 - (d.v - min) / span) * innerH,
    v: d.v, d: d.d
  }));
  const pathD = smoothPath(pts);
  const areaD = pathD + ` L ${pts[pts.length - 1].x} ${padT + innerH} L ${pts[0].x} ${padT + innerH} Z`;

  return (
    <div ref={ref} style={{ width: '100%' }}>
      <svg width={width} height={height}>
        <defs>
          <linearGradient id="line-area" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.30"/>
            <stop offset="100%" stopColor={color} stopOpacity="0"/>
          </linearGradient>
        </defs>
        {[0, 1, 2, 3].map(t => {
          const y = padT + (t / 3) * innerH;
          const v = max - (span * t / 3);
          return (
            <g key={t}>
              <line x1={padL} y1={y} x2={width - padR} y2={y} stroke="oklch(0.22 0.012 250)" strokeDasharray="3 5"/>
              <text x={padL - 8} y={y + 4} fill="oklch(0.55 0.012 250)" fontSize="10" textAnchor="end" fontFamily="JetBrains Mono">{v.toFixed(2)}</text>
            </g>
          );
        })}
        <path d={areaD} fill="url(#line-area)" />
        <path d={pathD} stroke={color} strokeWidth="2" fill="none" />
        {pts.map((p, i) => (
          <g key={i}>
            <circle cx={p.x} cy={p.y} r="3.5" fill="oklch(0.16 0.012 250)" stroke={color} strokeWidth="2" />
            <text x={p.x} y={height - 10} fill="oklch(0.55 0.012 250)" fontSize="10" textAnchor="middle">{p.d}</text>
          </g>
        ))}
      </svg>
    </div>
  );
}

// Mini sparkline
function Sparkline({ values = [], width = 80, height = 28, color = 'oklch(0.78 0.16 160)' }) {
  const min = Math.min(...values);
  const max = Math.max(...values);
  const span = max - min || 1;
  const pts = values.map((v, i) => ({
    x: (i / (values.length - 1)) * width,
    y: height - ((v - min) / span) * height * 0.8 - height * 0.1,
  }));
  return (
    <svg width={width} height={height}>
      <path d={smoothPath(pts)} stroke={color} strokeWidth="1.6" fill="none" />
    </svg>
  );
}

// inject chart css
(function() {
  if (document.getElementById('scp-charts-css')) return;
  const s = document.createElement('style'); s.id = 'scp-charts-css';
  s.textContent = `
    .scp-donut { position: relative; display: inline-block; }
    .scp-donut-center {
      position: absolute; inset: 0; display: flex; flex-direction: column;
      align-items: center; justify-content: center; pointer-events: none;
    }
    .scp-donut-center .lbl { font-size: 10px; color: var(--fg-3); text-transform: uppercase; letter-spacing: .1em; font-weight: 600; }
    .scp-donut-center .val { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin-top: 2px; font-family: var(--font-sans); font-feature-settings: "tnum"; }
    .scp-donut-arc { cursor: pointer; transition: opacity .15s, stroke-width .15s; transform-origin: center; transform-box: fill-box; }
    .scp-donut:hover .scp-donut-arc { opacity: 0.55; }
    .scp-donut .scp-donut-arc:hover { opacity: 1; stroke-width: 30; }
  `;
  document.head.appendChild(s);
})();

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