/**
 * Sync Today's Games with Odds from SportsGameOdds for multiple leagues
 */
import { PrismaClient } from '../prisma_sports/generated/sports-client';
import SportsGameOdds from 'sports-odds-api';
import { normalizeTeamFull } from '../src/lib/teamNormalization';

const API_KEY = process.env.SPORTSGAMEODDS_API_KEY || '';

const LEAGUE_CONFIG: Record<string, { leagueID: string; sportID: string }> = {
  nba: { leagueID: 'NBA', sportID: 'BASKETBALL' },
  nhl: { leagueID: 'NHL', sportID: 'HOCKEY' },
  ncaab: { leagueID: 'NCAAB', sportID: 'BASKETBALL' },
  nfl: { leagueID: 'NFL', sportID: 'FOOTBALL' },
  mlb: { leagueID: 'MLB', sportID: 'BASEBALL' },
};

function normalizeTeam(name: string, league?: string): string {
  return normalizeTeamFull(name, league) || name;
}

async function syncLeague(prisma: any, client: SportsGameOdds, league: string, todayEST: string, tomorrowIso: string) {
  const config = LEAGUE_CONFIG[league];
  if (!config) {
    console.log(`Unknown league: ${league}`);
    return { updated: 0, created: 0 };
  }

  console.log(`\nSyncing ${league.toUpperCase()} games for ${todayEST}...`);

  const events: any[] = [];
  try {
    for await (const event of client.events.get({
      leagueID: config.leagueID,
      sportID: config.sportID,
      startDate: todayEST,
      endDate: tomorrowIso,
      oddsAvailable: true,
      limit: 100,
    })) {
      events.push(event);
      if (events.length >= 100) break;
    }
  } catch (err) {
    console.error(`  Error fetching ${league}:`, err);
    return { updated: 0, created: 0 };
  }

  console.log(`  Found ${events.length} events with odds`);

  let updated = 0;
  let created = 0;

  for (const event of events) {
    const eventID = event.eventID;
    const gameDate = event.status?.startsAt ? new Date(event.status.startsAt) : null;
    if (!gameDate) continue;

    const homeTeamRaw = event.teams?.home?.names?.long || event.teams?.home?.names?.short || event.teams?.home?.names?.medium || '';
    const awayTeamRaw = event.teams?.away?.names?.long || event.teams?.away?.names?.short || event.teams?.away?.names?.medium || '';
    const homeTeam = normalizeTeam(homeTeamRaw, league) || homeTeamRaw;
    const awayTeam = normalizeTeam(awayTeamRaw, league) || awayTeamRaw;

    // Extract odds
    const odds = event.odds || {};
    let moneylineHome: number | null = null;
    let moneylineAway: number | null = null;
    let spreadHome: number | null = null;
    let total: number | null = null;

    for (const [key, market] of Object.entries(odds)) {
      if (!market || typeof market !== 'object') continue;
      const m = market as any;
      const k = key.toLowerCase();

      if (k.includes('-ml-home') && (m.bookOdds || m.fairOdds)) {
        moneylineHome = Math.round(Number(m.bookOdds || m.fairOdds));
      }
      if (k.includes('-ml-away') && (m.bookOdds || m.fairOdds)) {
        moneylineAway = Math.round(Number(m.bookOdds || m.fairOdds));
      }
      if (k.includes('-sp-home') && m.bookSpread != null) {
        spreadHome = Number(m.bookSpread);
      }
      if (k.includes('-ou-') && m.bookOverUnder != null) {
        const val = Number(m.bookOverUnder);
        if (val > 50) total = val; // NHL/NBA totals are typically 5-7 or 200+
      }
    }

    const hasOdds = moneylineHome != null || spreadHome != null;
    if (!hasOdds) continue;

    // Calculate season
    const gameYear = gameDate.getFullYear();
    const gameMonth = gameDate.getMonth();
    const season = gameMonth >= 9 ? gameYear : gameYear - 1;

    const externalGameId = `sgo:${eventID}`;

    try {
      // Try to find existing game
      let game = await prisma.sportsGame.findFirst({
        where: { league, externalGameId },
      });

      if (!game) {
        const dayStart = new Date(gameDate);
        dayStart.setHours(0, 0, 0, 0);
        const dayEnd = new Date(gameDate);
        dayEnd.setHours(23, 59, 59, 999);

        game = await prisma.sportsGame.findFirst({
          where: {
            league,
            homeTeam,
            awayTeam,
            gameDate: { gte: dayStart, lte: dayEnd },
          },
        });
      }

      if (game) {
        await prisma.sportsGame.update({
          where: { id: game.id },
          data: {
            moneylineHome,
            moneylineAway,
            spreadHome,
            total: total || game.total,
            oddsUpdatedAt: new Date(),
            updatedAt: new Date(),
          },
        });
        updated++;
      } else {
        await prisma.sportsGame.create({
          data: {
            league,
            externalGameId,
            homeTeam,
            awayTeam,
            gameDate,
            season,
            moneylineHome,
            moneylineAway,
            spreadHome,
            total,
            status: event.status?.displayShort || 'scheduled',
            oddsUpdatedAt: new Date(),
            updatedAt: new Date(),
          },
        });
        created++;
      }
    } catch (err) {
      // Skip errors
    }
  }

  console.log(`  Updated: ${updated}, Created: ${created}`);
  return { updated, created };
}

async function main() {
  if (!API_KEY) {
    console.error('SPORTSGAMEODDS_API_KEY not set');
    process.exit(1);
  }

  const args = process.argv.slice(2);
  const leagueArg = args.find(a => a.startsWith('--league='))?.split('=')[1];
  const leagues = leagueArg ? [leagueArg] : ['nba', 'nhl', 'ncaab'];

  const prisma = new PrismaClient();
  const client = new SportsGameOdds({
    apiKeyHeader: API_KEY,
    apiKeyParam: API_KEY,
    maxRetries: 3,
    timeout: 30000,
  });

  try {
    // Get today in EST
    const now = new Date();
    const estOffset = -5 * 60;
    const estTime = new Date(now.getTime() + (estOffset + now.getTimezoneOffset()) * 60 * 1000);
    const todayEST = estTime.toISOString().slice(0, 10);
    const tomorrowEST = new Date(estTime);
    tomorrowEST.setDate(tomorrowEST.getDate() + 1);
    const tomorrowIso = tomorrowEST.toISOString().slice(0, 10);

    console.log(`Syncing games for ${todayEST} (EST)`);

    let totalUpdated = 0;
    let totalCreated = 0;

    for (const league of leagues) {
      const result = await syncLeague(prisma, client, league, todayEST, tomorrowIso);
      totalUpdated += result.updated;
      totalCreated += result.created;
    }

    console.log(`\n=== COMPLETE ===`);
    console.log(`Total Updated: ${totalUpdated}`);
    console.log(`Total Created: ${totalCreated}`);

  } finally {
    await prisma.$disconnect();
  }
}

main().catch(console.error);
