/**
 * Base rates for the strategy as it actually runs.
 *
 * The per-target `probability` on a setup answers "will price touch this S/R
 * level?" — a question about a level we never exit at. These numbers answer the
 * question the user is really asking ("what tends to happen when I take one of
 * these?") and they are measured under the *real* exit policy, from the same
 * backtest report the Track Record page already consumes.
 */

interface MonitorRun {
  strategy?: string;
  lookback?: string;
  is_production?: boolean;
  sharpe?: number | null;
  cagr_pct?: number | null;
  max_drawdown_pct?: number | null;
  trades?: number | null;
  win_rate?: number | null;
  avg_hold_days?: number | null;
  best_trade_r?: number | null;
  worst_trade_r?: number | null;
  exit_reasons?: Record<string, number> | null;
}

export interface BaseRates {
  lookbackLabel: string;
  trades: number;
  winRate: number;
  avgHoldDays: number | null;
  bestR: number | null;
  worstR: number | null;
  sharpe: number | null;
  /** How trades actually ended, as shares of the total (0-1). */
  exits: { reason: string; label: string; count: number; share: number }[];
}

const EXIT_LABELS: Record<string, string> = {
  stop: 'initial stop',
  trailing_stop: 'trailing stop',
  time: 'max hold',
  target: 'target',
};

/**
 * Pull the production strategy's full-history row out of a backtest report.
 * Returns null when the report hasn't run or has no production row.
 */
export function productionBaseRates(report: unknown): BaseRates | null {
  const monitor = (report as { portfolio_monitor?: { production_strategy?: string; runs?: MonitorRun[] } })
    ?.portfolio_monitor;
  if (!monitor?.runs?.length) return null;

  const strategy = monitor.production_strategy;
  const row =
    monitor.runs.find((r) => r.strategy === strategy && r.lookback === 'all') ??
    monitor.runs.find((r) => r.is_production && r.lookback === 'all');
  if (!row || !row.trades) return null;

  const reasons = row.exit_reasons ?? {};
  const total = Object.values(reasons).reduce((a, b) => a + b, 0);
  const exits = Object.entries(reasons)
    .map(([reason, count]) => ({
      reason,
      label: EXIT_LABELS[reason] ?? reason,
      count,
      share: total > 0 ? count / total : 0,
    }))
    .sort((a, b) => b.count - a.count);

  return {
    lookbackLabel: 'all history',
    trades: row.trades,
    winRate: row.win_rate ?? 0,
    avgHoldDays: row.avg_hold_days ?? null,
    bestR: row.best_trade_r ?? null,
    worstR: row.worst_trade_r ?? null,
    sharpe: row.sharpe ?? null,
    exits,
  };
}
