// ============================================================
// ROI 24-month projection chart · custom SVG
// Three lines: cumulative cost, cumulative revenue, cumulative net.
// Breakeven marker on the net line.
// ============================================================

function roiBuildSeries(state, calc) {
  const months = 24;
  const out = [];
  let cumCost = 0, cumRev = 0;
  for (let m = 1; m <= months; m++) {
    cumCost += calc.monthlyFeeTotal;
    if (m === 1) cumCost += calc.totalImpl;
    const earning = m > state.ramp;
    if (earning) cumRev += calc.totalRevenuePerMonth;
    out.push({ m, cost: cumCost, rev: cumRev, net: cumRev - cumCost });
  }
  return out;
}

// Build a smooth Catmull-Rom path through the points.
function roiSmoothPath(points) {
  if (points.length < 2) return '';
  const p = (i) => points[Math.max(0, Math.min(points.length - 1, i))];
  let d = `M ${points[0].x} ${points[0].y}`;
  for (let i = 0; i < points.length - 1; i++) {
    const p0 = p(i - 1), p1 = p(i), p2 = p(i + 1), p3 = p(i + 2);
    const c1x = p1.x + (p2.x - p0.x) / 6;
    const c1y = p1.y + (p2.y - p0.y) / 6;
    const c2x = p2.x - (p3.x - p1.x) / 6;
    const c2y = p2.y - (p3.y - p1.y) / 6;
    d += ` C ${c1x} ${c1y}, ${c2x} ${c2y}, ${p2.x} ${p2.y}`;
  }
  return d;
}

function RoiChart({ state, calc }) {
  const series = React.useMemo(() => roiBuildSeries(state, calc), [state, calc]);

  const wrapRef = React.useRef(null);
  const [w, setW] = React.useState(800);
  React.useEffect(() => {
    if (!wrapRef.current) return;
    const ro = new ResizeObserver(entries => {
      for (const e of entries) setW(e.contentRect.width);
    });
    ro.observe(wrapRef.current);
    return () => ro.disconnect();
  }, []);

  const h = 320;
  const padL = 56, padR = 28, padT = 22, padB = 42;
  const plotW = Math.max(60, w - padL - padR);
  const plotH = h - padT - padB;

  // Y-domain: include 0, max(cost & rev), min(net)
  const allVals = series.flatMap(s => [s.cost, s.rev, s.net, 0]);
  let yMax = Math.max(...allVals);
  let yMin = Math.min(...allVals);
  if (yMax === yMin) yMax = yMin + 1;
  // Round nicely
  const niceStep = (v) => {
    const p = Math.pow(10, Math.floor(Math.log10(Math.abs(v))));
    const n = v / p;
    if (n <= 1) return p;
    if (n <= 2) return 2 * p;
    if (n <= 5) return 5 * p;
    return 10 * p;
  };
  const range = yMax - yMin;
  const step = niceStep(range / 4);
  yMax = Math.ceil(yMax / step) * step;
  yMin = Math.floor(yMin / step) * step;
  const ySteps = [];
  for (let v = yMin; v <= yMax + 0.5; v += step) ySteps.push(v);

  const xAt = (m) => padL + ((m - 1) / 23) * plotW;
  const yAt = (v) => padT + (1 - (v - yMin) / (yMax - yMin)) * plotH;
  const zeroY = yAt(0);

  const costPts = series.map(s => ({ x: xAt(s.m), y: yAt(s.cost) }));
  const revPts  = series.map(s => ({ x: xAt(s.m), y: yAt(s.rev) }));
  const netPts  = series.map(s => ({ x: xAt(s.m), y: yAt(s.net) }));

  const costPath = roiSmoothPath(costPts);
  const revPath = roiSmoothPath(revPts);
  const netPath = roiSmoothPath(netPts);

  // Area fill under "net" line, clipped at zero
  const netAreaUp = `${netPath} L ${netPts[netPts.length-1].x} ${zeroY} L ${netPts[0].x} ${zeroY} Z`;

  // Breakeven detection
  const beIdx = series.findIndex(s => s.net >= 0 && s.m > state.ramp);
  const showBE = beIdx >= 0 && isFinite(calc.breakeven);
  const beX = showBE ? xAt(beIdx + 1) : null;

  // Hover
  const [hover, setHover] = React.useState(null);
  const svgRef = React.useRef(null);
  const handleMove = (e) => {
    const rect = svgRef.current.getBoundingClientRect();
    const px = ((e.clientX - rect.left) / rect.width) * w;
    if (px < padL || px > w - padR) { setHover(null); return; }
    const rel = (px - padL) / plotW;
    const m = Math.round(rel * 23) + 1;
    const idx = Math.max(0, Math.min(23, m - 1));
    setHover({ idx });
  };
  const handleLeave = () => setHover(null);

  const xLbls = [1, 6, 12, 18, 24];

  return (
    <div className="roi-chart" ref={wrapRef}>
      <svg
        ref={svgRef}
        viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none"
        onMouseMove={handleMove}
        onMouseLeave={handleLeave}
      >
        <defs>
          <linearGradient id="roiNetGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#4D01B4" stopOpacity="0.22" />
            <stop offset="100%" stopColor="#4D01B4" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="roiLineCost" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="#FB993F" />
            <stop offset="100%" stopColor="#F83C72" />
          </linearGradient>
          <linearGradient id="roiLineNet" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#8D0D9C" />
            <stop offset="100%" stopColor="#4D01B4" />
          </linearGradient>
        </defs>

        {/* Y gridlines + labels */}
        {ySteps.map((v, i) => {
          const y = yAt(v);
          return (
            <g key={`y${i}`}>
              <line x1={padL} y1={y} x2={w - padR} y2={y} className={v === 0 ? 'zero-line' : 'grid-line'} />
              <text x={padL - 12} y={y + 3.5} className="ax-y-lbl" textAnchor="end">
                {roiFormatEUR(v, { k: true }).replace('€ ', '')}
              </text>
            </g>
          );
        })}

        {/* X labels */}
        {xLbls.map(m => (
          <text key={`x${m}`} x={xAt(m)} y={h - padB + 22} className="ax-x-lbl">
            mnd {m}
          </text>
        ))}

        {/* Net area fill (above zero only — visual cue) */}
        <path d={netAreaUp} fill="url(#roiNetGrad)" />

        {/* Cost line (orange→pink gradient) */}
        <path d={costPath} fill="none" stroke="url(#roiLineCost)" strokeWidth="2.4" />

        {/* Revenue line (green, dashed) */}
        <path d={revPath} fill="none" stroke="#0E9F71" strokeWidth="2" strokeDasharray="6 4" />

        {/* Net line (purple) */}
        <path d={netPath} fill="none" stroke="url(#roiLineNet)" strokeWidth="3" />

        {/* Breakeven marker */}
        {showBE && (
          <g>
            <line x1={beX} y1={padT} x2={beX} y2={h - padB} className="be-line" />
            <g transform={`translate(${beX}, ${padT + 4})`}>
              <rect x={-46} y={-2} width={92} height={22} rx={11} className="be-pill" />
              <text x={0} y={13} textAnchor="middle" className="be-lbl">
                Break-even · m{beIdx + 1}
              </text>
            </g>
            <circle cx={beX} cy={yAt(series[beIdx].net)} r={5} fill="#fff" stroke="#F83C72" strokeWidth="2" />
          </g>
        )}

        {/* Hover line + dots */}
        {hover && (() => {
          const s = series[hover.idx];
          const x = xAt(s.m);
          return (
            <g>
              <line x1={x} y1={padT} x2={x} y2={h - padB} className="hover-line" />
              <circle cx={x} cy={yAt(s.cost)} r={4} fill="#fff" stroke="#F83C72" strokeWidth="2" />
              <circle cx={x} cy={yAt(s.rev)}  r={4} fill="#fff" stroke="#0E9F71" strokeWidth="2" />
              <circle cx={x} cy={yAt(s.net)}  r={4} fill="#fff" stroke="#4D01B4" strokeWidth="2" />
            </g>
          );
        })()}
      </svg>

      {/* Tooltip */}
      {hover && (() => {
        const s = series[hover.idx];
        const x = xAt(s.m);
        const leftPct = (x / w) * 100;
        const yTop = Math.min(yAt(s.cost), yAt(s.rev), yAt(s.net));
        const topPct = (yTop / h) * 100;
        return (
          <div
            className="roi-chart-tooltip on"
            style={{ left: `${leftPct}%`, top: `${topPct}%` }}
          >
            <div className="ttl">Maand {s.m}</div>
            <div className="row" style={{'--swatch': '#F83C72'}}>
              <span className="k">Kosten</span>
              <span className="v">{roiFormatEUR(s.cost, { k: true })}</span>
            </div>
            <div className="row" style={{'--swatch': '#0E9F71'}}>
              <span className="k">Opbrengst</span>
              <span className="v">{roiFormatEUR(s.rev, { k: true })}</span>
            </div>
            <div className="row" style={{'--swatch': '#4D01B4'}}>
              <span className="k">Netto winst</span>
              <span className="v">{roiFormatEUR(s.net, { sign: true, k: true })}</span>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

Object.assign(window, { RoiChart, roiBuildSeries });
