/* Cash flow chart + Revenue/Expenses bar chart, both hand-rolled SVG with
   interactive hover. Each is wrapped in a panel with header + legend. */

function PanelHeader({ eyebrow, title, sub, right }) {
  return (
    <header className="cb-panel-head">
      <div>
        {eyebrow && <div className="cb-panel-eyebrow">{eyebrow}</div>}
        <h3 className="cb-panel-title">{title}</h3>
        {sub && <div className="cb-panel-sub">{sub}</div>}
      </div>
      {right && <div className="cb-panel-right">{right}</div>}
    </header>
  );
}

/* ── Cash flow area chart ─────────────────────────────────────────────── */
function CashFlowChart() {
  const data = CB.cashflow;
  if (!data || data.length < 2) {
    const latestCash = (data && data.length && data[data.length - 1].cash) || 0;
    return (
      <section className="cb-panel cb-panel-cashflow">
        <PanelHeader eyebrow="Cash flow" title={CB.fmtMoney(latestCash)}
                     sub={<span>Operating account · last 12 weeks</span>} />
        <div className="cb-chart-empty">Not enough weekly history yet to chart cash flow.</div>
      </section>
    );
  }
  const W = 720, H = 240, PAD = { l: 56, r: 18, t: 18, b: 32 };
  const iw = W - PAD.l - PAD.r, ih = H - PAD.t - PAD.b;
  const vals = data.map((d) => d.cash);
  const min = Math.floor(Math.min(...vals) / 10000) * 10000;
  const max = Math.ceil(Math.max(...vals) / 10000) * 10000;
  const range = max - min || 1;
  const stepX = iw / (data.length - 1);
  const pts = data.map((d, i) => [
    PAD.l + i * stepX,
    PAD.t + ih - ((d.cash - min) / range) * ih,
  ]);
  // smooth path via simple cubic
  const line = pts.reduce((s, p, i, a) => {
    if (i === 0) return `M ${p[0]} ${p[1]}`;
    const prev = a[i - 1];
    const cx1 = prev[0] + stepX * 0.4, cy1 = prev[1];
    const cx2 = p[0] - stepX * 0.4, cy2 = p[1];
    return s + ` C ${cx1} ${cy1} ${cx2} ${cy2} ${p[0]} ${p[1]}`;
  }, '');
  const area = line + ` L ${pts[pts.length - 1][0]} ${PAD.t + ih} L ${pts[0][0]} ${PAD.t + ih} Z`;

  const [hover, setHover] = React.useState(null);

  const onMove = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const x = ((e.clientX - r.left) / r.width) * W;
    const i = Math.max(0, Math.min(data.length - 1, Math.round((x - PAD.l) / stepX)));
    setHover(i);
  };

  // y-axis ticks
  const ticks = 4;
  const ys = Array.from({ length: ticks + 1 }, (_, i) => min + (range * i) / ticks);

  const latest = data[data.length - 1];
  const first = data[0];
  const change = latest.cash - first.cash;
  const changePct = (change / first.cash) * 100;

  return (
    <section className="cb-panel cb-panel-cashflow">
      <PanelHeader
        eyebrow="Cash flow"
        title={CB.fmtMoney(latest.cash)}
        sub={
          <span>
            Operating account · last 12 weeks{' '}
            <Delta value={changePct} label="" />
          </span>
        }
        right={
          <div className="cb-legend">
            <span><i style={{ background: 'var(--cb-primary)' }} /> Cash</span>
            <span className="cb-legend-meta">{first.w} – {latest.w}</span>
          </div>
        }
      />
      <div className="cb-chart-wrap">
        <svg viewBox={`0 0 ${W} ${H}`} className="cb-chart" preserveAspectRatio="none"
             onMouseMove={onMove} onMouseLeave={() => setHover(null)}>
          <defs>
            <linearGradient id="cb-cash-grad" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="var(--cb-primary)" stopOpacity=".22" />
              <stop offset="100%" stopColor="var(--cb-primary)" stopOpacity="0" />
            </linearGradient>
          </defs>
          {/* gridlines + axis labels */}
          {ys.map((y, i) => {
            const yy = PAD.t + ih - ((y - min) / range) * ih;
            return (
              <g key={i}>
                <line x1={PAD.l} y1={yy} x2={W - PAD.r} y2={yy}
                      stroke="var(--cb-line)" strokeDasharray={i === 0 ? '0' : '2 4'} />
                <text x={PAD.l - 10} y={yy + 4} fontSize="11" textAnchor="end"
                      fill="var(--cb-fg-3)">{CB.fmtCompact(y)}</text>
              </g>
            );
          })}
          {/* x labels — every other */}
          {data.map((d, i) => (
            i % 2 === 0 ? (
              <text key={i} x={PAD.l + i * stepX} y={H - 8} fontSize="11"
                    textAnchor="middle" fill="var(--cb-fg-3)">{d.w}</text>
            ) : null
          ))}
          <path d={area} fill="url(#cb-cash-grad)" />
          <path d={line} fill="none" stroke="var(--cb-primary)" strokeWidth="2"
                strokeLinecap="round" strokeLinejoin="round" />
          {/* dots */}
          {pts.map((p, i) => (
            <circle key={i} cx={p[0]} cy={p[1]} r={hover === i ? 4.5 : 0}
                    fill="var(--cb-surface)" stroke="var(--cb-primary)" strokeWidth="2" />
          ))}
          {/* hover line + tooltip */}
          {hover != null && (
            <g pointerEvents="none">
              <line x1={pts[hover][0]} y1={PAD.t} x2={pts[hover][0]} y2={PAD.t + ih}
                    stroke="var(--cb-fg-3)" strokeDasharray="3 3" />
              <foreignObject x={Math.min(W - 160, Math.max(0, pts[hover][0] - 70))}
                             y={Math.max(4, pts[hover][1] - 64)} width="160" height="60">
                <div xmlns="http://www.w3.org/1999/xhtml" className="cb-tip">
                  <div className="cb-tip-h">Week of {data[hover].w}</div>
                  <div className="cb-tip-row"><span>Cash</span><b>{CB.fmtMoney(data[hover].cash)}</b></div>
                  <div className="cb-tip-row cb-tip-sub">
                    <span>In {CB.fmtCompact(data[hover].inflow)}</span>
                    <span>Out {CB.fmtCompact(data[hover].outflow)}</span>
                  </div>
                </div>
              </foreignObject>
            </g>
          )}
        </svg>
      </div>
    </section>
  );
}

/* ── Tax estimate widget ──────────────────────────────────────────────── */
function TaxWidget() {
  const t = CB.tax;
  if (!t || !t.estimate) {
    return (
      <section className="cb-panel cb-panel-tax">
        <PanelHeader eyebrow="Estimated taxes" title="Not set up yet"
                     sub="Your bookkeeper hasn't entered a quarterly estimate." />
        <div className="cb-chart-empty">Once a tax estimate is added, your set-aside progress shows here.</div>
      </section>
    );
  }
  const pct = t.estimate ? Math.round((t.setAside / t.estimate) * 100) : 0;
  const remaining = t.estimate - t.setAside;
  const daysToDue = t.dueDate ? CB.daysAgo(t.dueDate) * -1 : null;

  // donut
  const R = 58, C = 2 * Math.PI * R;
  const dash = (pct / 100) * C;

  return (
    <section className="cb-panel cb-panel-tax">
      <PanelHeader
        eyebrow="Estimated taxes"
        title={t.qLabel}
        sub={t.dueDate ? `Due ${CB.fmtDate(t.dueDate)}${daysToDue != null ? ` · in ${daysToDue} days` : ''}` : 'No due date set'}
      />
      <div className="cb-tax-body">
        <div className="cb-donut">
          <svg viewBox="0 0 160 160" width="160" height="160">
            <circle cx="80" cy="80" r={R} fill="none"
                    stroke="var(--cb-line-strong)" strokeWidth="14" />
            <circle cx="80" cy="80" r={R} fill="none"
                    stroke="var(--cb-accent)" strokeWidth="14"
                    strokeDasharray={`${dash} ${C}`} strokeLinecap="round"
                    transform="rotate(-90 80 80)" />
            <text x="80" y="76" textAnchor="middle" fontSize="26"
                  fontWeight="500" fill="var(--cb-fg)">{pct}%</text>
            <text x="80" y="96" textAnchor="middle" fontSize="11"
                  fill="var(--cb-fg-2)">set aside</text>
          </svg>
        </div>
        <div className="cb-tax-stats">
          <div className="cb-tax-row">
            <span>Estimate</span>
            <b>{CB.fmtMoney(t.estimate)}</b>
          </div>
          <div className="cb-tax-row">
            <span>Set aside</span>
            <b style={{ color: 'var(--cb-accent)' }}>{CB.fmtMoney(t.setAside)}</b>
          </div>
          <div className="cb-tax-row cb-tax-row-divide">
            <span>Still needed</span>
            <b>{CB.fmtMoney(remaining)}</b>
          </div>
          <button type="button" className="cb-btn cb-btn-primary cb-btn-block">
            Move {CB.fmtCompact(remaining)} to tax savings
          </button>
        </div>
      </div>
    </section>
  );
}

/* ── Revenue vs Expenses bar chart ────────────────────────────────────── */
function RevExpChart() {
  const data = CB.revVsExp;
  const W = 480, H = 230, PAD = { l: 48, r: 12, t: 18, b: 28 };
  const iw = W - PAD.l - PAD.r, ih = H - PAD.t - PAD.b;
  const max = Math.ceil(Math.max(...data.map((d) => Math.max(d.rev, d.exp))) / 25000) * 25000;
  const groupW = iw / data.length;
  const barW = (groupW - 14) / 2;

  const [hover, setHover] = React.useState(null);

  const total = data.reduce((s, d) => s + d.rev, 0);
  const totalExp = data.reduce((s, d) => s + d.exp, 0);

  return (
    <section className="cb-panel">
      <PanelHeader
        eyebrow="Revenue vs Expenses"
        title="6-month profit"
        sub={`${CB.fmtMoney(total - totalExp)} kept of ${CB.fmtMoney(total)} earned`}
        right={
          <div className="cb-legend">
            <span><i style={{ background: 'var(--cb-primary)' }} /> Revenue</span>
            <span><i style={{ background: 'var(--cb-fg-3)' }} /> Expenses</span>
          </div>
        }
      />
      <div className="cb-chart-wrap">
        <svg viewBox={`0 0 ${W} ${H}`} className="cb-chart" preserveAspectRatio="none">
          {[0, 0.25, 0.5, 0.75, 1].map((f, i) => {
            const y = PAD.t + ih - f * ih;
            return (
              <g key={i}>
                <line x1={PAD.l} y1={y} x2={W - PAD.r} y2={y}
                      stroke="var(--cb-line)" strokeDasharray={f === 0 ? '0' : '2 4'} />
                <text x={PAD.l - 8} y={y + 4} fontSize="11" textAnchor="end"
                      fill="var(--cb-fg-3)">{CB.fmtCompact(max * f)}</text>
              </g>
            );
          })}
          {data.map((d, i) => {
            const gx = PAD.l + i * groupW + 7;
            const hR = (d.rev / max) * ih;
            const hE = (d.exp / max) * ih;
            const on = hover === i;
            return (
              <g key={i} onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
                {/* invisible hit area */}
                <rect x={PAD.l + i * groupW} y={PAD.t} width={groupW} height={ih}
                      fill="transparent" />
                <rect x={gx} y={PAD.t + ih - hR} width={barW} height={hR} rx="3"
                      fill="var(--cb-primary)" opacity={on || hover == null ? 1 : 0.55} />
                <rect x={gx + barW + 4} y={PAD.t + ih - hE} width={barW} height={hE} rx="3"
                      fill="var(--cb-fg-3)" opacity={on || hover == null ? 0.65 : 0.4} />
                <text x={gx + barW + 2} y={H - 8} fontSize="11" textAnchor="middle"
                      fill={on ? 'var(--cb-fg)' : 'var(--cb-fg-3)'}
                      fontWeight={on ? '600' : '400'}>{d.m}</text>
                {on && (
                  <foreignObject x={Math.min(W - 150, Math.max(0, gx - 30))}
                                 y={PAD.t + ih - Math.max(hR, hE) - 64}
                                 width="150" height="60">
                    <div xmlns="http://www.w3.org/1999/xhtml" className="cb-tip">
                      <div className="cb-tip-h">{d.m} 2026</div>
                      <div className="cb-tip-row"><span>Revenue</span><b>{CB.fmtMoney(d.rev)}</b></div>
                      <div className="cb-tip-row"><span>Expenses</span><b>{CB.fmtMoney(d.exp)}</b></div>
                    </div>
                  </foreignObject>
                )}
              </g>
            );
          })}
        </svg>
      </div>
    </section>
  );
}

Object.assign(window, { CashFlowChart, TaxWidget, RevExpChart, PanelHeader });
