// World-Football-Elo style ratings. Pure functions so the build script and the
// runtime (live re-rating after each result) share exactly one implementation.

/** Home-advantage in Elo points, added to the home side's rating (0 if neutral). */
export const HOME_ADV_ELO = 70;

/** Match-importance weight (K) by tournament, à la eloratings.net. */
export function importanceWeight(tournament: string): number {
  const t = tournament.toLowerCase();
  if (t.includes('friendly')) return 10;
  if (t.includes('qualification') || t.includes('nations league')) return 25;
  if (t.includes('fifa world cup')) return 55; // the finals themselves
  if (t.includes('confederations')) return 45;
  if (
    t.includes('euro') || t.includes('copa') || t.includes('african cup') ||
    t.includes('asian cup') || t.includes('gold cup') || t.includes('championship')
  ) return 40;
  return 20;
}

/** Goal-difference multiplier G: blowouts move ratings more. */
export function goalDiffMultiplier(gd: number): number {
  const n = Math.abs(gd);
  if (n <= 1) return 1;
  if (n === 2) return 1.5;
  return (11 + n) / 8;
}

/** Expected score for the home side (0..1). homeAdv is 0 for neutral venues. */
export function expectedHome(eloHome: number, eloAway: number, homeAdv: number): number {
  return 1 / (1 + 10 ** ((eloAway - eloHome - homeAdv) / 400));
}

/** Symmetric Elo exchange for one match. Returns the home side's delta; the away
 *  side's delta is the negation. */
export function eloDelta(
  homeGoals: number,
  awayGoals: number,
  eloHome: number,
  eloAway: number,
  k: number,
  homeAdv: number,
): number {
  const actual = homeGoals > awayGoals ? 1 : homeGoals < awayGoals ? 0 : 0.5;
  const expected = expectedHome(eloHome, eloAway, homeAdv);
  return k * goalDiffMultiplier(homeGoals - awayGoals) * (actual - expected);
}
