// Bookmaker-odds math, shared by the server (capture) and the client
// (Model-vs-Market scoreboard). Odds are a BENCHMARK only — never a model input.

import type { MatchProbs } from './types';

/** American moneyline → decimal odds (e.g. -235 → 1.4255, +340 → 4.40). */
export function americanToDecimal(ml: number): number {
  if (!Number.isFinite(ml) || ml === 0) return NaN;
  return ml < 0 ? 1 + 100 / Math.abs(ml) : 1 + ml / 100;
}

/**
 * De-vig a 1X2 set of American moneylines into fair probabilities: convert to
 * implied probabilities (1/decimal) and normalize away the bookmaker margin.
 * Returns null if any line is missing/invalid.
 */
export function deVig(homeMl: number | null, drawMl: number | null, awayMl: number | null): MatchProbs | null {
  if (homeMl == null || drawMl == null || awayMl == null) return null;
  const dh = americanToDecimal(homeMl);
  const dd = americanToDecimal(drawMl);
  const da = americanToDecimal(awayMl);
  if (!Number.isFinite(dh) || !Number.isFinite(dd) || !Number.isFinite(da)) return null;
  const ih = 1 / dh, id = 1 / dd, ia = 1 / da;
  const total = ih + id + ia;
  if (total <= 0) return null;
  return { home: ih / total, draw: id / total, away: ia / total };
}

/** Bookmaker overround (margin) for display: e.g. 1.052 → "5.2%". */
export function overround(homeMl: number, drawMl: number, awayMl: number): number {
  return 1 / americanToDecimal(homeMl) + 1 / americanToDecimal(drawMl) + 1 / americanToDecimal(awayMl);
}
