import type { BacktestSignal } from './backendApi';

export interface EquityPoint {
  time: number;
  equity: number;
}

export interface TradeMarker {
  time: number;
  equity: number;
  type: 'buy' | 'sell';
  price: number;
  pnlPct?: number;
}

export interface TradeHistoryRow {
  id: number;
  time: number;
  symbol: string;
  side: 'buy' | 'sell';
  price: number;
  quantity: number;
  pnlPct?: number;
}

const BUY_TYPES = new Set(['BUY']);
const SELL_TYPES = new Set(['SELL', 'SHORT_EXIT', 'PARTIAL_SELL']);

export function buildEquityFromSignals(
  signals: BacktestSignal[],
  initialCapital: number,
  symbol: string,
): { curve: EquityPoint[]; markers: TradeMarker[]; trades: TradeHistoryRow[] } {
  const sorted = [...signals].sort((a, b) => a.time - b.time);
  const curve: EquityPoint[] = [];
  const markers: TradeMarker[] = [];
  const trades: TradeHistoryRow[] = [];

  if (sorted.length === 0) {
    const now = Math.floor(Date.now() / 1000);
    return {
      curve: [{ time: now, equity: initialCapital }],
      markers: [],
      trades: [],
    };
  }

  let cash = initialCapital;
  let qty = 0;
  let entryPrice = 0;
  let tradeId = 0;

  const pushCurve = (time: number, price: number) => {
    const equity = qty > 0 ? qty * price : cash;
    const last = curve[curve.length - 1];
    if (!last || last.time !== time || Math.abs(last.equity - equity) > 0.01) {
      curve.push({ time, equity });
    }
  };

  pushCurve(sorted[0].time, sorted[0].price);

  for (const s of sorted) {
    if (BUY_TYPES.has(s.type) && qty === 0 && cash > 0) {
      qty = cash / s.price;
      entryPrice = s.price;
      cash = 0;
      tradeId += 1;
      const eq = qty * s.price;
      trades.push({
        id: tradeId,
        time: s.time,
        symbol,
        side: 'buy',
        price: s.price,
        quantity: qty,
      });
      markers.push({ time: s.time, equity: eq, type: 'buy', price: s.price });
      pushCurve(s.time, s.price);
    } else if (SELL_TYPES.has(s.type) && qty > 0) {
      const pnlPct = entryPrice > 0 ? (s.price - entryPrice) / entryPrice : 0;
      cash = qty * s.price;
      tradeId += 1;
      trades.push({
        id: tradeId,
        time: s.time,
        symbol,
        side: 'sell',
        price: s.price,
        quantity: qty,
        pnlPct,
      });
      markers.push({ time: s.time, equity: cash, type: 'sell', price: s.price, pnlPct });
      qty = 0;
      entryPrice = 0;
      pushCurve(s.time, s.price);
    } else {
      pushCurve(s.time, s.price);
    }
  }

  if (curve.length === 1 && sorted.length > 0) {
    const last = sorted[sorted.length - 1];
    const equity = qty > 0 ? qty * last.price : cash;
    curve.push({ time: last.time, equity });
  }

  return { curve, markers, trades };
}

export function sparklinePath(values: number[], w: number, h: number): string {
  if (values.length < 2) {
    const y = h * 0.5;
    return `M0,${y} L${w},${y}`;
  }
  const min = Math.min(...values);
  const max = Math.max(...values);
  const range = max - min || 1;
  return values.map((v, i) => {
    const x = (i / (values.length - 1)) * w;
    const y = h - 4 - ((v - min) / range) * (h - 8);
    return `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');
}

export function equityToSparkline(curve: EquityPoint[]): number[] {
  if (curve.length <= 1) return [0, 1];
  return curve.map(p => p.equity);
}
