import 'dotenv/config';

import pool from '../db';
import { sanitizeGameOddsForLeague } from '../services/sgo';

type NullableOdd = { line: number | null; odds: number | null } | null;
type GameOdds = {
  moneyline: { home: number | null; away: number | null };
  spread: { home: NullableOdd; away: NullableOdd };
  total: { over: NullableOdd; under: NullableOdd };
};

type EventRow = {
  event_id: string;
  moneyline: GameOdds['moneyline'] | null;
  spread: GameOdds['spread'] | null;
  total: GameOdds['total'] | null;
  opening_moneyline: GameOdds['moneyline'] | null;
  opening_spread: GameOdds['spread'] | null;
  opening_total: GameOdds['total'] | null;
};

function normalizeCurrentOdds(row: EventRow): GameOdds {
  return {
    moneyline: row.moneyline || { home: null, away: null },
    spread: row.spread || { home: null, away: null },
    total: row.total || { over: null, under: null },
  };
}

function normalizeOpeningOdds(row: EventRow): GameOdds {
  return {
    moneyline: row.opening_moneyline || { home: null, away: null },
    spread: row.opening_spread || { home: null, away: null },
    total: row.opening_total || { over: null, under: null },
  };
}

function sameJson(a: unknown, b: unknown): boolean {
  return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
}

async function main(): Promise<void> {
  const { rows } = await pool.query<EventRow>(
    `SELECT event_id, moneyline, spread, total, opening_moneyline, opening_spread, opening_total
     FROM rm_events
     WHERE league = 'mlb'`,
  );

  let changedRows = 0;
  let changedCurrent = 0;
  let changedOpening = 0;

  for (const row of rows) {
    const currentOdds = normalizeCurrentOdds(row);
    const openingOdds = normalizeOpeningOdds(row);
    const nextCurrent = sanitizeGameOddsForLeague('mlb', currentOdds);
    const nextOpening = sanitizeGameOddsForLeague('mlb', openingOdds);

    const currentChanged =
      !sameJson(row.moneyline, nextCurrent.moneyline) ||
      !sameJson(row.spread, nextCurrent.spread) ||
      !sameJson(row.total, nextCurrent.total);
    const openingChanged =
      !sameJson(row.opening_moneyline, nextOpening.moneyline) ||
      !sameJson(row.opening_spread, nextOpening.spread) ||
      !sameJson(row.opening_total, nextOpening.total);

    if (!currentChanged && !openingChanged) continue;

    await pool.query(
      `UPDATE rm_events
       SET moneyline = $2,
           spread = $3,
           total = $4,
           opening_moneyline = $5,
           opening_spread = $6,
           opening_total = $7,
           updated_at = NOW()
       WHERE event_id = $1`,
      [
        row.event_id,
        JSON.stringify(nextCurrent.moneyline),
        JSON.stringify(nextCurrent.spread),
        JSON.stringify(nextCurrent.total),
        JSON.stringify(nextOpening.moneyline),
        JSON.stringify(nextOpening.spread),
        JSON.stringify(nextOpening.total),
      ],
    );

    changedRows++;
    if (currentChanged) changedCurrent++;
    if (openingChanged) changedOpening++;
  }

  console.log(JSON.stringify({
    audited: rows.length,
    changedRows,
    changedCurrent,
    changedOpening,
  }));
}

main()
  .catch((error) => {
    console.error('[repair-mlb-event-odds] failed', error);
    process.exitCode = 1;
  })
  .finally(async () => {
    await pool.end().catch(() => undefined);
  });
