import 'dotenv/config';
import pool from '../db';
import { fetchEvents, parseOdds } from '../services/sgo';
import { canonicalizeTeamName } from '../lib/team-abbreviations';
import { fetchCurrentOdds, hasTheOddsApiConfigured, type TheOddsCurrentEvent } from '../services/the-odds';
import { reconcileStartTimeFromCurrentOdds } from '../services/start-time-reconciliation';

function parseArgs(): { date: string } {
  const dateFlag = process.argv.indexOf('--date');
  const date = dateFlag >= 0 && process.argv[dateFlag + 1]
    ? process.argv[dateFlag + 1]
    : new Date().toLocaleDateString('en-CA', { timeZone: 'America/New_York' });

  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
    throw new Error('Usage: npx tsx src/scripts/sync-mlb-events.ts --date YYYY-MM-DD');
  }

  return { date };
}

function makeEventId(league: string, awayShort: string, homeShort: string, dateStr: string): string {
  return `${league}-${awayShort.toLowerCase()}-${homeShort.toLowerCase()}-${dateStr.replace(/-/g, '')}`;
}

function isTargetDateET(startsAt: string, targetDate: string): boolean {
  const eventDate = new Date(startsAt);
  const etStr = eventDate.toLocaleString('en-US', { timeZone: 'America/New_York' });
  const et = new Date(etStr);
  const y = et.getFullYear();
  const m = String(et.getMonth() + 1).padStart(2, '0');
  const d = String(et.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}` === targetDate;
}

async function main() {
  const { date } = parseArgs();
  const startsAfter = `${date}T00:00:00-05:00`;
  const events = await fetchEvents('mlb', startsAfter);
  const targetEvents = events.filter((event) => event.status?.startsAt && isTargetDateET(event.status.startsAt, date));
  let currentOddsEvents: TheOddsCurrentEvent[] = [];

  if (hasTheOddsApiConfigured()) {
    try {
      currentOddsEvents = await fetchCurrentOdds({
        sportKey: 'baseball_mlb',
        markets: ['h2h', 'spreads', 'totals'],
      });
    } catch (err: any) {
      console.warn(`[sync-mlb-events] Start-time reconciliation skipped: ${err.message}`);
    }
  }

  let inserted = 0;
  let updated = 0;

  for (const event of targetEvents) {
    if (!event.teams?.home?.names?.short || !event.teams?.away?.names?.short) continue;

    const homeTeam = canonicalizeTeamName(event.teams.home.names.long);
    const awayTeam = canonicalizeTeamName(event.teams.away.names.long);
    const homeShort = event.teams.home.names.short;
    const awayShort = event.teams.away.names.short;
    const startsAt = reconcileStartTimeFromCurrentOdds({
      homeTeam,
      awayTeam,
      startsAt: event.status.startsAt,
      currentEvents: currentOddsEvents,
    }).startsAt;
    const odds = parseOdds(event);
    const propCount = odds.props.length;
    const eventId = makeEventId('mlb', awayShort, homeShort, date);

    const result = await pool.query(
      `INSERT INTO rm_events
         (event_id, league, home_team, home_short, away_team, away_short, starts_at, status, moneyline, spread, total, prop_count, source)
       VALUES
         ($1, 'mlb', $2, $3, $4, $5, $6, 'scheduled', $7, $8, $9, $10, 'sgo-mlb-sync')
       ON CONFLICT (event_id) DO UPDATE SET
         home_team = EXCLUDED.home_team,
         home_short = EXCLUDED.home_short,
         away_team = EXCLUDED.away_team,
         away_short = EXCLUDED.away_short,
         starts_at = EXCLUDED.starts_at,
         status = EXCLUDED.status,
         moneyline = EXCLUDED.moneyline,
         spread = EXCLUDED.spread,
         total = EXCLUDED.total,
         prop_count = EXCLUDED.prop_count,
         source = EXCLUDED.source,
         updated_at = NOW()
       RETURNING (xmax = 0) AS inserted`,
      [
        eventId,
        homeTeam,
        homeShort,
        awayTeam,
        awayShort,
        startsAt,
        JSON.stringify(odds.moneyline),
        JSON.stringify(odds.spread),
        JSON.stringify(odds.total),
        propCount,
      ],
    );

    if (result.rows[0]?.inserted) inserted += 1;
    else updated += 1;
  }

  console.log(JSON.stringify({
    date_et: date,
    fetched: events.length,
    matched: targetEvents.length,
    inserted,
    updated,
  }, null, 2));

  await pool.end();
}

if (require.main === module) {
  main().catch(async (err) => {
    console.error('[sync-mlb-events] Fatal:', err);
    await pool.end().catch(() => {});
    process.exit(1);
  });
}
