/* global React, window, CHART */
/* ============================================================
   Lightweight SVG charts — no external lib
   ============================================================ */
const { useState: useStateC } = React;

const niceNum = (n) => {
  if (Math.abs(n) >= 1000) return (n / 1000).toFixed(n % 1000 === 0 ? 0 : 1) + 'K';
  return String(n);
};

// ---------- Sparkline ----------
function Sparkline({ data, color = CHART.green, w = 88, h = 28 }) {
  const min = Math.min(...data), max = Math.max(...data);
  const rng = max - min || 1;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * w;
    const y = h - ((v - min) / rng) * (h - 4) - 2;
    return [x, y];
  });
  const d = pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = d + ` L ${w} ${h} L 0 ${h} Z`;
  return (
    <svg width={w} height={h} style={{ display: 'block', overflow: 'visible' }}>
      <path d={area} fill={color} opacity="0.12" />
      <path d={d} fill="none" stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.6" fill={color} />
    </svg>
  );
}

// ---------- Axis helpers ----------
function buildScale(values, padTop = 0.08) {
  const max = Math.max(...values);
  const min = Math.min(...values);
  const span = max - min;
  const top = max + span * padTop;
  const bottom = Math.max(0, min - span * 0.12);
  return { top, bottom, range: top - bottom || 1 };
}

// ---------- Line Chart (with optional hover) ----------
function LineChart({ months, series, color = CHART.green, height = 320, unit = '', fmt = niceNum, showArea = true }) {
  const [hover, setHover] = useStateC(null);
  const W = 880, H = height, padL = 56, padR = 20, padT = 18, padB = 34;
  const iw = W - padL - padR, ih = H - padT - padB;
  const sc = buildScale(series);
  const x = (i) => padL + (i / (series.length - 1)) * iw;
  const y = (v) => padT + ih - ((v - sc.bottom) / sc.range) * ih;
  const pts = series.map((v, i) => [x(i), y(v)]);
  const d = pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = d + ` L ${x(series.length - 1)} ${padT + ih} L ${padL} ${padT + ih} Z`;
  const ticks = 4;
  const gridVals = Array.from({ length: ticks + 1 }, (_, i) => sc.bottom + (sc.range * i) / ticks);
  const everyN = Math.ceil(months.length / 8);

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', fontFamily: "'Open Sans',sans-serif" }}
         onMouseLeave={() => setHover(null)}
         onMouseMove={(e) => {
           const r = e.currentTarget.getBoundingClientRect();
           const mx = ((e.clientX - r.left) / r.width) * W;
           const i = Math.round(((mx - padL) / iw) * (series.length - 1));
           if (i >= 0 && i < series.length) setHover(i);
         }}>
      {gridVals.map((v, i) => (
        <g key={i}>
          <line x1={padL} x2={W - padR} y1={y(v)} y2={y(v)} stroke={CHART.grid} strokeWidth="1" />
          <text x={padL - 10} y={y(v) + 4} textAnchor="end" fontSize="11" fill="#969696">{fmt(Math.round(v))}{unit}</text>
        </g>
      ))}
      {months.map((m, i) => (i % everyN === 0) && (
        <text key={i} x={x(i)} y={H - 12} textAnchor="middle" fontSize="10.5" fill="#969696">{m.label}</text>
      ))}
      {showArea && <path d={area} fill={color} opacity="0.10" />}
      <path d={d} fill="none" stroke={color} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
      {hover != null && (
        <g>
          <line x1={x(hover)} x2={x(hover)} y1={padT} y2={padT + ih} stroke={CHART.ink} strokeWidth="1" strokeDasharray="3 3" opacity="0.4" />
          <circle cx={x(hover)} cy={y(series[hover])} r="4.5" fill="#fff" stroke={color} strokeWidth="2.4" />
          <g transform={`translate(${Math.min(Math.max(x(hover), padL + 50), W - padR - 50)}, ${padT + 6})`}>
            <rect x="-50" y="-2" width="100" height="40" rx="4" fill={CHART.ink} />
            <text x="0" y="13" textAnchor="middle" fontSize="10" fill="#9AA39A">{months[hover].label}</text>
            <text x="0" y="29" textAnchor="middle" fontSize="14" fontWeight="700" fill="#fff">{fmt(series[hover])}{unit}</text>
          </g>
        </g>
      )}
    </svg>
  );
}

// ---------- Column Chart ----------
function ColumnChart({ months, series, color = CHART.green, height = 320, unit = '', fmt = niceNum }) {
  const [hover, setHover] = useStateC(null);
  const W = 880, H = height, padL = 56, padR = 20, padT = 18, padB = 34;
  const iw = W - padL - padR, ih = H - padT - padB;
  const sc = buildScale(series, 0.1);
  const bottom = 0;
  const x = (i) => padL + (i / series.length) * iw;
  const bw = (iw / series.length) * 0.62;
  const y = (v) => padT + ih - ((v - bottom) / (sc.top - bottom || 1)) * ih;
  const ticks = 4;
  const gridVals = Array.from({ length: ticks + 1 }, (_, i) => (sc.top * i) / ticks);
  const everyN = Math.ceil(months.length / 8);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', fontFamily: "'Open Sans',sans-serif" }}
         onMouseLeave={() => setHover(null)}>
      {gridVals.map((v, i) => (
        <g key={i}>
          <line x1={padL} x2={W - padR} y1={y(v)} y2={y(v)} stroke={CHART.grid} strokeWidth="1" />
          <text x={padL - 10} y={y(v) + 4} textAnchor="end" fontSize="11" fill="#969696">{fmt(Math.round(v))}{unit}</text>
        </g>
      ))}
      {series.map((v, i) => {
        const cx = x(i) + (iw / series.length - bw) / 2;
        const isH = hover === i;
        return (
          <g key={i} onMouseEnter={() => setHover(i)}>
            <rect x={cx} y={y(v)} width={bw} height={padT + ih - y(v)} rx="2" fill={color} opacity={isH ? 1 : 0.82} />
            <rect x={x(i)} y={padT} width={iw / series.length} height={ih} fill="transparent" />
            {(i % everyN === 0) && <text x={cx + bw / 2} y={H - 12} textAnchor="middle" fontSize="10.5" fill="#969696">{months[i].label}</text>}
            {isH && <text x={cx + bw / 2} y={y(v) - 7} textAnchor="middle" fontSize="11.5" fontWeight="700" fill={CHART.ink}>{fmt(v)}{unit}</text>}
          </g>
        );
      })}
    </svg>
  );
}

// ---------- Mix Chart: bars (sales) + line (price) ----------
function MixChart({ months, bars, line, barColor = CHART.green40 || '#C1E4C1', lineColor = CHART.green, height = 320 }) {
  const W = 880, H = height, padL = 50, padR = 50, padT = 18, padB = 34;
  const iw = W - padL - padR, ih = H - padT - padB;
  const bsc = buildScale(bars, 0.1);
  const lsc = buildScale(line, 0.12);
  const x = (i) => padL + (i / bars.length) * iw;
  const bw = (iw / bars.length) * 0.56;
  const by = (v) => padT + ih - (v / (bsc.top || 1)) * ih;
  const ly = (v) => padT + ih - ((v - lsc.bottom) / lsc.range) * ih;
  const lpts = line.map((v, i) => [x(i) + (iw / bars.length) / 2, ly(v)]);
  const ld = lpts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const everyN = Math.ceil(months.length / 8);
  const ticks = 4;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', fontFamily: "'Open Sans',sans-serif" }}>
      {Array.from({ length: ticks + 1 }, (_, i) => (bsc.top * i) / ticks).map((v, i) => (
        <g key={i}>
          <line x1={padL} x2={W - padR} y1={by(v)} y2={by(v)} stroke={CHART.grid} strokeWidth="1" />
          <text x={padL - 8} y={by(v) + 4} textAnchor="end" fontSize="10.5" fill="#969696">{niceNum(Math.round(v))}</text>
        </g>
      ))}
      {bars.map((v, i) => {
        const cx = x(i) + (iw / bars.length - bw) / 2;
        return <rect key={i} x={cx} y={by(v)} width={bw} height={padT + ih - by(v)} rx="2" fill={barColor} />;
      })}
      <path d={ld} fill="none" stroke={lineColor} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
      {lpts.map((p, i) => (i % everyN === 0) && <circle key={i} cx={p[0]} cy={p[1]} r="2.6" fill={lineColor} />)}
      {months.map((m, i) => (i % everyN === 0) && (
        <text key={i} x={x(i) + (iw / bars.length) / 2} y={H - 12} textAnchor="middle" fontSize="10.5" fill="#969696">{m.label}</text>
      ))}
    </svg>
  );
}

// ---------- Grouped comparison (two lines) ----------
function CompareChart({ months, a, b, colorA = CHART.green, colorB = CHART.steel, height = 320, fmt = niceNum }) {
  const W = 880, H = height, padL = 56, padR = 20, padT = 18, padB = 34;
  const iw = W - padL - padR, ih = H - padT - padB;
  const all = [...a, ...b];
  const sc = buildScale(all);
  const x = (i) => padL + (i / (a.length - 1)) * iw;
  const y = (v) => padT + ih - ((v - sc.bottom) / sc.range) * ih;
  const mk = (s) => s.map((v, i) => (i ? 'L' : 'M') + x(i).toFixed(1) + ' ' + y(v).toFixed(1)).join(' ');
  const everyN = Math.ceil(months.length / 8);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', fontFamily: "'Open Sans',sans-serif" }}>
      {Array.from({ length: 5 }, (_, i) => sc.bottom + (sc.range * i) / 4).map((v, i) => (
        <g key={i}>
          <line x1={padL} x2={W - padR} y1={y(v)} y2={y(v)} stroke={CHART.grid} strokeWidth="1" />
          <text x={padL - 10} y={y(v) + 4} textAnchor="end" fontSize="11" fill="#969696">{fmt(Math.round(v))}</text>
        </g>
      ))}
      <path d={mk(a)} fill="none" stroke={colorA} strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
      <path d={mk(b)} fill="none" stroke={colorB} strokeWidth="2.4" strokeDasharray="1 0" strokeLinecap="round" strokeLinejoin="round" opacity="0.9" />
      {months.map((m, i) => (i % everyN === 0) && (
        <text key={i} x={x(i)} y={H - 12} textAnchor="middle" fontSize="10.5" fill="#969696">{m.label}</text>
      ))}
    </svg>
  );
}

Object.assign(window, { Sparkline, LineChart, ColumnChart, MixChart, CompareChart, niceNum });
