import React, { memo, useMemo } from 'react';
import type { EquityPoint, TradeMarker } from '../../utils/backtestEquity';

interface Props {
  curve: EquityPoint[];
  markers: TradeMarker[];
}

function fmtDate(ts: number): string {
  const d = new Date(ts * 1000);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

function fmtMonth(ts: number): string {
  const d = new Date(ts * 1000);
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  return `${months[d.getMonth()]} ${d.getFullYear()}`;
}

interface LineSegment {
  d: string;
  up: boolean;
}

const BacktestAssetChart: React.FC<Props> = memo(({ curve, markers }) => {
  const W = 800;
  const H = 280;
  const pad = { t: 22, r: 14, b: 26, l: 48 };
  const innerW = W - pad.l - pad.r;
  const innerH = H - pad.t - pad.b;

  const chart = useMemo(() => {
    if (curve.length < 2) {
      const y = pad.t + innerH * 0.5;
      return {
        areaPath: `M${pad.l},${y} L${pad.l + innerW},${y} L${pad.l + innerW},${pad.t + innerH} L${pad.l},${pad.t + innerH} Z`,
        segments: [] as LineSegment[],
        yTicks: [0, 1],
        xLabels: [] as { x: number; label: string }[],
        markerPts: [] as Array<{ x: number; y: number; m: TradeMarker }>,
        toY: (_e: number) => y,
      };
    }

    const times = curve.map(p => p.time);
    const equities = curve.map(p => p.equity);
    const tMin = Math.min(...times);
    const tMax = Math.max(...times);
    const eMin = Math.min(...equities) * 0.985;
    const eMax = Math.max(...equities) * 1.015;
    const tRange = tMax - tMin || 1;
    const eRange = eMax - eMin || 1;

    const toX = (t: number) => pad.l + ((t - tMin) / tRange) * innerW;
    const toY = (e: number) => pad.t + innerH - ((e - eMin) / eRange) * innerH;

    const linePath = curve.map((p, i) => `${i === 0 ? 'M' : 'L'}${toX(p.time).toFixed(1)},${toY(p.equity).toFixed(1)}`).join(' ');
    const areaPath = `${linePath} L${toX(curve[curve.length - 1].time).toFixed(1)},${pad.t + innerH} L${toX(curve[0].time).toFixed(1)},${pad.t + innerH} Z`;

    const segments: LineSegment[] = [];
    for (let i = 1; i < curve.length; i++) {
      segments.push({
        d: `M${toX(curve[i - 1].time).toFixed(1)},${toY(curve[i - 1].equity).toFixed(1)} L${toX(curve[i].time).toFixed(1)},${toY(curve[i].equity).toFixed(1)}`,
        up: curve[i].equity >= curve[i - 1].equity,
      });
    }

    const yTicks = [0, 0.25, 0.5, 0.75, 1].map(r => eMin + eRange * r);
    const xLabels: { x: number; label: string }[] = [];
    const step = Math.max(1, Math.floor(curve.length / 5));
    for (let i = 0; i < curve.length; i += step) {
      xLabels.push({ x: toX(curve[i].time), label: i === 0 ? fmtMonth(curve[i].time) : fmtDate(curve[i].time) });
    }
    const last = curve[curve.length - 1];
    if (!xLabels.some(l => l.label === fmtDate(last.time))) {
      xLabels.push({ x: toX(last.time), label: fmtDate(last.time) });
    }

    const markerPts = markers.map(m => ({ x: toX(m.time), y: toY(m.equity), m }));

    return { areaPath, segments, yTicks, xLabels, markerPts, toY };
  }, [curve, markers, innerH, innerW, pad.l, pad.t]);

  const fmtY = (v: number) => {
    if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;
    if (v >= 10_000) return `${Math.round(v / 10_000)}만`;
    return Math.round(v).toLocaleString();
  };

  return (
    <div className="btd-chart-wrap">
      <svg className="btd-chart-svg" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
        <defs>
          <linearGradient id="btd-area-grad-up" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="rgba(34,197,94,0.28)" />
            <stop offset="100%" stopColor="rgba(34,197,94,0.02)" />
          </linearGradient>
        </defs>

        {[0.25, 0.5, 0.75].map(r => {
          const y = pad.t + innerH * (1 - r);
          return <line key={r} x1={pad.l} y1={y} x2={W - pad.r} y2={y} className="btd-chart-grid" />;
        })}

        <text x={pad.l - 8} y={pad.t - 6} textAnchor="start" className="btd-chart-label" fontSize="8">자본금</text>

        {chart.yTicks.map(v => (
          <text
            key={v}
            x={pad.l - 4}
            y={chart.toY(v)}
            textAnchor="end"
            dominantBaseline="middle"
            className="btd-chart-label"
            fontSize="8.5"
          >
            {fmtY(v)}
          </text>
        ))}

        <path d={chart.areaPath} fill="url(#btd-area-grad-up)" />
        {chart.segments.map((seg, i) => (
          <path
            key={i}
            d={seg.d}
            fill="none"
            className={seg.up ? 'btd-chart-line-up' : 'btd-chart-line-down'}
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        ))}

        {chart.markerPts.map(({ x, y, m }, i) => (
          <g key={`${m.time}-${m.type}-${i}`}>
            {m.type === 'buy' ? (
              <>
                <polygon points={`${x},${y - 9} ${x - 4},${y - 2} ${x + 4},${y - 2}`} fill="#22c55e" />
                <text x={x} y={y - 12} textAnchor="middle" fill="#22c55e" fontSize="7.5" fontWeight="700">
                  {fmtDate(m.time).slice(5)}
                </text>
              </>
            ) : (
              <>
                <polygon points={`${x},${y + 9} ${x - 4},${y + 2} ${x + 4},${y + 2}`} fill="#ef4444" />
                <text x={x} y={y + 20} textAnchor="middle" fill={m.pnlPct != null && m.pnlPct >= 0 ? '#22c55e' : '#ef4444'} fontSize="7.5" fontWeight="700">
                  {m.pnlPct != null ? `${m.pnlPct >= 0 ? '+' : ''}${(m.pnlPct * 100).toFixed(1)}%` : '매도'}
                </text>
              </>
            )}
          </g>
        ))}

        {chart.xLabels.map((l, i) => (
          <text key={i} x={l.x} y={H - 5} textAnchor="middle" className="btd-chart-label" fontSize="8">
            {l.label}
          </text>
        ))}
      </svg>
    </div>
  );
});

BacktestAssetChart.displayName = 'BacktestAssetChart';
export default BacktestAssetChart;
