import React, { useMemo } from 'react';
import type { OHLCVBar } from '../../types';

function spark(values: number[], w: number, h: number, min?: number, max?: number): string {
  if (!values.length) return '';
  const lo = min ?? Math.min(...values);
  const hi = max ?? Math.max(...values);
  const range = hi - lo || 1;
  return values.map((v, i) => {
    const x = (i / Math.max(values.length - 1, 1)) * w;
    const y = h - ((v - lo) / range) * (h - 6) - 3;
    return `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');
}

function computeRsi(closes: number[], period = 14): number[] {
  if (closes.length < period + 1) return [];
  const out: number[] = [];
  let avgGain = 0;
  let avgLoss = 0;
  for (let i = 1; i <= period; i++) {
    const d = closes[i] - closes[i - 1];
    if (d >= 0) avgGain += d; else avgLoss -= d;
  }
  avgGain /= period;
  avgLoss /= period;
  for (let i = period; i < closes.length; i++) {
    const d = closes[i] - closes[i - 1];
    const gain = d > 0 ? d : 0;
    const loss = d < 0 ? -d : 0;
    avgGain = (avgGain * (period - 1) + gain) / period;
    avgLoss = (avgLoss * (period - 1) + loss) / period;
    const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
    out.push(100 - 100 / (1 + rs));
  }
  return out;
}

function computeMacd(closes: number[]): number[] {
  const ema = (arr: number[], p: number) => {
    const k = 2 / (p + 1);
    let v = arr[0];
    return arr.map((x, i) => (i === 0 ? x : (v = x * k + v * (1 - k))));
  };
  const e12 = ema(closes, 12);
  const e26 = ema(closes, 26);
  return e12.map((v, i) => v - e26[i]);
}

interface Props {
  bars: OHLCVBar[];
}

/** 백테스팅 분석 — RSI / MACD 하단 pane (참조 UI) */
const BacktestOscillatorPanes: React.FC<Props> = ({ bars }) => {
  const { rsiPath, macdPath, rsiLast, macdLast } = useMemo(() => {
    const closes = bars.map(b => b.close);
    const rsi = computeRsi(closes).slice(-80);
    const macd = computeMacd(closes).slice(-80);
    return {
      rsiPath: spark(rsi, 280, 52, 0, 100),
      macdPath: spark(macd, 280, 52),
      rsiLast: rsi[rsi.length - 1],
      macdLast: macd[macd.length - 1],
    };
  }, [bars]);

  if (bars.length < 20) return null;

  return (
    <div className="btd-osc-stack">
      <div className="btd-osc-pane">
        <div className="btd-osc-head">
          <span className="btd-osc-label">RSI (14)</span>
          <span className="btd-osc-val">{rsiLast != null ? rsiLast.toFixed(1) : '–'}</span>
        </div>
        <svg className="btd-osc-svg" viewBox="0 0 280 52" preserveAspectRatio="none">
          <line x1="0" y1="15" x2="280" y2="15" className="btd-osc-ref btd-osc-ref--hi" />
          <line x1="0" y1="26" x2="280" y2="26" className="btd-osc-ref" />
          <line x1="0" y1="37" x2="280" y2="37" className="btd-osc-ref btd-osc-ref--lo" />
          <path d={rsiPath} className="btd-osc-line btd-osc-line--rsi" fill="none" />
        </svg>
      </div>
      <div className="btd-osc-pane">
        <div className="btd-osc-head">
          <span className="btd-osc-label">MACD (12, 26, 9)</span>
          <span className="btd-osc-val">{macdLast != null ? macdLast.toFixed(2) : '–'}</span>
        </div>
        <svg className="btd-osc-svg" viewBox="0 0 280 52" preserveAspectRatio="none">
          <line x1="0" y1="26" x2="280" y2="26" className="btd-osc-ref" />
          <path d={macdPath} className="btd-osc-line btd-osc-line--macd" fill="none" />
        </svg>
      </div>
    </div>
  );
};

export default BacktestOscillatorPanes;
