// Hand-rolled SVG charts. No libraries.

const { useMemo } = React;

// Sparkline — single tone, no axes.
function Sparkline({ data, width = 96, height = 28, color = '#97FCE4', stroke = 1.5 }) {
  const min = Math.min(...data), max = Math.max(...data);
  const span = max - min || 1;
  const stepX = width / (data.length - 1);
  const pts = data.map((v, i) => [i * stepX, height - ((v - min) / span) * (height - 4) - 2]);
  const d = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(' ');
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <path d={d} fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// Spot price chart — area + line, mint up, coral down. With y-grid + x-labels.
function SpotChart({ series, color = '#97FCE4', height = 340, range = '1D' }) {
  const padL = 56, padR = 16, padT = 16, padB = 28;
  const w = 880;
  const ps = series.map(s => s.p);
  const min = Math.min(...ps), max = Math.max(...ps);
  const span = (max - min) || 1;
  const innerH = height - padT - padB;
  const innerW = w - padL - padR;
  const stepX = innerW / (series.length - 1);

  const x = (i) => padL + i * stepX;
  const y = (p) => padT + innerH - ((p - min) / span) * innerH;

  const linePath = series.map((s, i) => (i === 0 ? `M${x(i)},${y(s.p)}` : `L${x(i)},${y(s.p)}`)).join(' ');
  const areaPath = `${linePath} L${x(series.length - 1)},${padT + innerH} L${x(0)},${padT + innerH} Z`;

  const yTicks = 4;
  const ticks = Array.from({ length: yTicks + 1 }, (_, i) => min + (span * i) / yTicks);
  const xLabels = useMemo(() => {
    const labels = {
      '1H': ['-60m','-45m','-30m','-15m','now'],
      '1D': ['9:30','12:00','14:00','16:00','now'],
      '1W': ['Mon','Tue','Wed','Thu','Fri'],
      '1M': ['Apr 4','Apr 11','Apr 18','Apr 25','May 2'],
      '1Y': ['Jun','Sep','Dec','Mar','now'],
      'All': ['2021','2022','2023','2024','2026'],
    };
    return labels[range] || labels['1D'];
  }, [range]);

  const fmtPrice = (p) => p > 1000 ? p.toFixed(0) : p > 100 ? p.toFixed(1) : p.toFixed(2);

  return (
    <svg width="100%" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none" style={{ display: 'block' }}>
      <defs>
        <linearGradient id={`vd-area-${color.replace('#','')}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.18" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      {/* y grid */}
      {ticks.map((t, i) => (
        <g key={i}>
          <line x1={padL} y1={y(t)} x2={w - padR} y2={y(t)} stroke="#1B262B" strokeWidth="1" />
          <text x={padL - 10} y={y(t) + 4} fill="#5E6970" fontSize="11" textAnchor="end" className="num" style={{fontFamily:'Geist Mono'}}>{fmtPrice(t)}</text>
        </g>
      ))}
      {/* x labels */}
      {xLabels.map((label, i) => {
        const xp = padL + (innerW * i) / (xLabels.length - 1);
        return (
          <text key={i} x={xp} y={height - 8} fill="#5E6970" fontSize="11" textAnchor="middle" className="num" style={{fontFamily:'Geist Mono'}}>{label}</text>
        );
      })}
      {/* area + line */}
      <path d={areaPath} fill={`url(#vd-area-${color.replace('#','')})`} />
      <path d={linePath} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
      {/* last point dot */}
      <circle cx={x(series.length - 1)} cy={y(series[series.length - 1].p)} r="3.5" fill={color} />
      <circle cx={x(series.length - 1)} cy={y(series[series.length - 1].p)} r="6" fill={color} opacity="0.18" />
    </svg>
  );
}

// Payoff diagram — binary; horizontal axis = price at expiry, vertical = P&L.
// strategy = { legs: [{side:'YES'|'NO', strike, qty, price}], spot, range }
function PayoffDiagram({ legs, spot, width = 480, height = 220 }) {
  const padL = 44, padR = 12, padT = 14, padB = 28;
  const w = width, h = height;
  const innerW = w - padL - padR, innerH = h - padT - padB;
  // x range — span around spot
  const allKs = legs.map(l => l.strike);
  const lo = Math.min(...allKs, spot) * 0.94;
  const hi = Math.max(...allKs, spot) * 1.06;
  const N = 120;
  const xs = Array.from({length: N}, (_, i) => lo + (hi - lo) * i / (N - 1));
  const evalP = (price) => legs.reduce((acc, l) => {
    // binary YES pays $1 if price > strike (call-style) at expiry; NO pays $1 if price <= strike.
    const won = l.side === 'YES' ? price > l.strike : price <= l.strike;
    const cost = (l.price / 100) * l.qty;
    const payoff = won ? 1 * l.qty : 0;
    return acc + (payoff - cost);
  }, 0);
  const ys = xs.map(evalP);
  const yMin = Math.min(...ys), yMax = Math.max(...ys);
  const yPad = (yMax - yMin) * 0.15 || 1;
  const lo2 = yMin - yPad, hi2 = yMax + yPad;

  const x = (p) => padL + ((p - lo) / (hi - lo)) * innerW;
  const y = (v) => padT + innerH - ((v - lo2) / (hi2 - lo2)) * innerH;

  // build segmented path; color by sign
  const segs = [];
  for (let i = 0; i < N - 1; i++) {
    segs.push({ x1: x(xs[i]), y1: y(ys[i]), x2: x(xs[i+1]), y2: y(ys[i+1]), pos: ys[i+1] >= 0 });
  }

  const fmt = (p) => p > 1000 ? Math.round(p) : p > 100 ? p.toFixed(0) : p.toFixed(1);

  return (
    <svg width="100%" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: 'block' }}>
      {/* zero line */}
      <line x1={padL} y1={y(0)} x2={w - padR} y2={y(0)} stroke="#283740" strokeDasharray="2 4" />
      {/* spot marker */}
      <line x1={x(spot)} y1={padT} x2={x(spot)} y2={h - padB} stroke="#5FBFA8" strokeDasharray="3 4" opacity="0.6" />
      <text x={x(spot)} y={padT + 10} fill="#5FBFA8" fontSize="10" textAnchor="middle" className="num">spot</text>
      {/* strikes */}
      {legs.map((l, i) => (
        <g key={i}>
          <line x1={x(l.strike)} y1={padT} x2={x(l.strike)} y2={h - padB} stroke="#3A4D55" strokeDasharray="1 3" opacity="0.7" />
          <text x={x(l.strike)} y={h - padB + 14} fill="#9BA5AB" fontSize="10" textAnchor="middle" className="num">{fmt(l.strike)}</text>
        </g>
      ))}
      {/* segments colored by sign */}
      {segs.map((s, i) => (
        <line key={i} x1={s.x1} y1={s.y1} x2={s.x2} y2={s.y2} stroke={s.pos ? '#97FCE4' : '#ED7088'} strokeWidth="2" strokeLinecap="round" />
      ))}
      {/* y axis labels */}
      <text x={padL - 6} y={y(0) + 4}    fill="#5E6970" fontSize="10" textAnchor="end" className="num">$0</text>
      <text x={padL - 6} y={y(yMax) + 4} fill="#97FCE4" fontSize="10" textAnchor="end" className="num">+${Math.round(yMax)}</text>
      <text x={padL - 6} y={y(yMin) + 4} fill="#ED7088" fontSize="10" textAnchor="end" className="num">-${Math.round(Math.abs(yMin))}</text>
      <text x={padL - 6} y={padT + 10}   fill="#5E6970" fontSize="9" textAnchor="end">P&amp;L</text>
    </svg>
  );
}

// Mini payoff for strategy cards (animated stroke-dasharray)
function MiniPayoff({ shape, animate = false, color = '#97FCE4', w = 240, h = 90 }) {
  // shape is a list of [x,y] points in 0..1
  const SHAPES = {
    long:   [[0,0.85],[0.5,0.85],[0.5,0.15],[1,0.15]],          // step up
    range:  [[0,0.85],[0.2,0.85],[0.35,0.15],[0.65,0.15],[0.8,0.85],[1,0.85]], // hat
    oor:    [[0,0.15],[0.2,0.15],[0.35,0.85],[0.65,0.85],[0.8,0.15],[1,0.15]], // valley
    hedge:  [[0,0.15],[0.4,0.85],[1,0.85]],                      // diagonal
    tails:  [[0,0.85],[0.7,0.85],[0.85,0.15],[1,0.05]],         // late spike
    event:  [[0,0.85],[0.45,0.85],[0.45,0.15],[1,0.15]],        // step + flat
  };
  const pts = SHAPES[shape] || SHAPES.long;
  const padL = 8, padR = 8, padT = 8, padB = 8;
  const innerW = w - padL - padR, innerH = h - padT - padB;
  const path = pts.map((p, i) => {
    const X = padL + p[0] * innerW;
    const Y = padT + p[1] * innerH;
    return (i === 0 ? `M${X},${Y}` : `L${X},${Y}`);
  }).join(' ');
  return (
    <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{display:'block'}}>
      <line x1={padL} y1={h/2} x2={w-padR} y2={h/2} stroke="#283740" strokeDasharray="2 4" />
      <path d={path}
            fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
            style={{
              strokeDasharray: 600,
              strokeDashoffset: animate ? 0 : 600,
              transition: 'stroke-dashoffset 720ms cubic-bezier(0.2,0,0,1)'
            }} />
    </svg>
  );
}

// Depth bar — for chain table
function DepthBar({ value, color = '#97FCE4', w = 56, h = 6 }) {
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      <rect x="0" y="0" width={w} height={h} rx="2" fill="#1A2A30" />
      <rect x="0" y="0" width={w * Math.max(0.04, Math.min(1, value))} height={h} rx="2" fill={color} opacity="0.65" />
    </svg>
  );
}

// Probability bar — small horizontal bar for builder strike picker
function ProbBar({ pct, w = 80, h = 4 }) {
  const v = Math.max(0, Math.min(1, pct));
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      <rect x="0" y="0" width={w} height={h} rx="2" fill="#1A2A30" />
      <rect x="0" y="0" width={w * v} height={h} rx="2" fill="#97FCE4" opacity="0.85" />
    </svg>
  );
}

window.VDChart = { Sparkline, SpotChart, PayoffDiagram, MiniPayoff, DepthBar, ProbBar };
