// chart.jsx — Plat portfolio chart: scrubbable line + time-range toggles
// Exports to window: PortfolioChart
const { useState, useRef, useEffect, useCallback } = React;

// deterministic series: n points trending start->end with gentle noise
function genSeries(n, start, end, vol, seed) {
  let s = seed;
  const rnd = () => (s = (s * 9301 + 49297) % 233280) / 233280;
  const pts = [];
  for (let i = 0; i < n; i++) {
    const t = i / (n - 1);
    const base = start + (end - start) * (t * 0.7 + 0.3 * t * t);
    const noise = (rnd() - 0.5) * vol * start;
    pts.push(Math.round(base + (i === 0 || i === n - 1 ? 0 : noise)));
  }
  pts[0] = start; pts[n - 1] = end;
  return pts;
}

const NOW = new Date(2026, 4, 1); // May 2026
const RANGES = [
  { key: '3M',  label: '3M',  n: 14, start: 1198000, months: 3,  vol: 0.010, seed: 7 },
  { key: '6M',  label: '6M',  n: 20, start: 1162000, months: 6,  vol: 0.013, seed: 23 },
  { key: '1Y',  label: '1Y',  n: 26, start: 1086000, months: 12, vol: 0.016, seed: 51 },
  { key: '3Y',  label: '3Y',  n: 37, start: 858000,  months: 36, vol: 0.020, seed: 91 },
  { key: 'ALL', label: 'All', n: 40, start: 712000,  months: 48, vol: 0.024, seed: 134 },
];
const END_VAL = 1240000;

function fmtBig(v) { return '$' + (v / 1e6).toFixed(2) + 'M'; }
function fmtSigned(v) { return (v < 0 ? '-$' : '+$') + Math.abs(Math.round(v)).toLocaleString(); }
function dateFor(range, i) {
  const frac = i / (range.n - 1);
  const d = new Date(NOW);
  d.setMonth(d.getMonth() - Math.round(range.months * (1 - frac)));
  return d.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
}

function smoothPath(p) {
  if (p.length < 2) return '';
  let d = `M ${p[0].x} ${p[0].y}`;
  for (let i = 0; i < p.length - 1; i++) {
    const p0 = p[i - 1] || p[i], p1 = p[i], p2 = p[i + 1], p3 = p[i + 2] || p2;
    const c1x = p1.x + (p2.x - p0.x) / 6, c1y = p1.y + (p2.y - p0.y) / 6;
    const c2x = p2.x - (p3.x - p1.x) / 6, c2y = p2.y - (p3.y - p1.y) / 6;
    d += ` C ${c1x.toFixed(1)} ${c1y.toFixed(1)}, ${c2x.toFixed(1)} ${c2y.toFixed(1)}, ${p2.x} ${p2.y}`;
  }
  return d;
}

function PortfolioChart({ dark = false, compact = false }) {
  const [rangeKey, setRangeKey] = useState('1Y');
  const [scrub, setScrub] = useState(null);
  const overlayRef = useRef(null);

  const range = RANGES.find(r => r.key === rangeKey);
  const data = React.useMemo(() => genSeries(range.n, range.start, END_VAL, range.vol, range.seed), [rangeKey]); // eslint-disable-line

  const W = 320, H = compact ? 96 : 124, padX = 3, padT = 10, padB = 8;
  const innerW = W - padX * 2, innerH = H - padT - padB;
  const min = Math.min(...data), max = Math.max(...data);
  const span = (max - min) || 1;
  const pts = data.map((v, i) => ({
    x: +(padX + (i / (data.length - 1)) * innerW).toFixed(2),
    y: +(padT + (1 - (v - min) / span) * innerH).toFixed(2),
    v,
  }));
  const linePath = smoothPath(pts);
  const areaPath = `${linePath} L ${pts[pts.length - 1].x} ${H - padB} L ${pts[0].x} ${H - padB} Z`;
  const baseY = pts[0].y;

  const tealDeep = dark ? '#4DC8BE' : '#0E7A72';

  const handleMove = useCallback((clientX) => {
    const rect = overlayRef.current.getBoundingClientRect();
    const t = Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));
    setScrub(Math.round(t * (data.length - 1)));
  }, [data.length]);

  const idx = scrub == null ? data.length - 1 : scrub;
  const curV = data[idx];
  const startV = data[0];
  const chg = curV - startV;
  const pct = (chg / startV) * 100;
  const up = chg >= 0;

  const idLabel = (dark ? 'd' : 'l') + rangeKey;

  return (
    <div style={{ padding: compact ? '14px 16px 10px' : '16px 18px 12px', background: dark ? 'var(--teal-strip)' : 'var(--teal)' }}>
      <div style={{ fontFamily: 'var(--cond)', fontSize: 9, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.78)' }}>Total Portfolio Value</div>
      <div className="serif" style={{ fontSize: compact ? 34 : 40, fontWeight: 900, color: '#fff', lineHeight: 1, marginTop: 2 }}>{fmtBig(curV)}</div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4, minHeight: 16 }}>
        <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: '#fff', fontWeight: 500 }}>
          {up ? '▲' : '▼'} {fmtSigned(chg)} ({up ? '+' : ''}{pct.toFixed(1)}%)
        </span>
        <span style={{ fontFamily: 'var(--mono)', fontSize: 10, color: 'rgba(255,255,255,0.7)' }}>
          {scrub == null ? `past ${range.label === 'All' ? 'all time' : range.label}` : dateFor(range, idx)}
        </span>
      </div>

      <div style={{ position: 'relative', marginTop: 8 }}>
        <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} style={{ display: 'block', overflow: 'visible' }}>
          <defs>
            <linearGradient id={'g' + idLabel} x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="#fff" stopOpacity="0.38" />
              <stop offset="100%" stopColor="#fff" stopOpacity="0" />
            </linearGradient>
          </defs>
          <line x1={padX} y1={baseY} x2={W - padX} y2={baseY} stroke="rgba(255,255,255,0.35)" strokeWidth="1" strokeDasharray="3 3" />
          <path key={'a' + rangeKey} d={areaPath} fill={`url(#g${idLabel})`} />
          <path key={'l' + rangeKey} d={linePath} fill="none" stroke="#fff" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" />
          {scrub != null && (
            <g>
              <line x1={pts[idx].x} y1={padT - 6} x2={pts[idx].x} y2={H - padB} stroke="rgba(255,255,255,0.55)" strokeWidth="1" />
              <circle cx={pts[idx].x} cy={pts[idx].y} r="5.5" fill="#fff" />
              <circle cx={pts[idx].x} cy={pts[idx].y} r="9" fill="#fff" opacity="0.25" />
            </g>
          )}
        </svg>
        <div ref={overlayRef}
          style={{ position: 'absolute', inset: 0, cursor: 'crosshair', touchAction: 'none' }}
          onPointerDown={(e) => { e.currentTarget.setPointerCapture(e.pointerId); handleMove(e.clientX); }}
          onPointerMove={(e) => { if (scrub != null || e.buttons) handleMove(e.clientX); }}
          onPointerEnter={(e) => { if (e.pointerType === 'mouse') handleMove(e.clientX); }}
          onPointerLeave={() => setScrub(null)}
          onPointerUp={() => setScrub(null)}
        />
      </div>

      <div style={{ display: 'flex', gap: 4, marginTop: 8 }}>
        {RANGES.map(r => {
          const on = r.key === rangeKey;
          return (
            <button key={r.key} onClick={() => { setScrub(null); setRangeKey(r.key); }}
              style={{ flex: 1, border: 'none', cursor: 'pointer', borderRadius: 5, padding: '5px 0',
                fontFamily: 'var(--cond)', fontWeight: 700, letterSpacing: '0.06em', fontSize: 11, textTransform: 'uppercase',
                background: on ? '#fff' : 'rgba(255,255,255,0.16)', color: on ? 'var(--teal-deep)' : 'rgba(255,255,255,0.85)' }}>
              {r.label}
            </button>
          );
        })}
      </div>
    </div>
  );
}

window.PortfolioChart = PortfolioChart;
