#!/usr/bin/env npx tsx
/**
 * Fetch Game Analysis Data
 * Gets odds, rosters, and player stats for a specific matchup
 *
 * Usage:
 *   npx tsx scripts/fetch-game-analysis.ts BKN DET    # Analyze Nets vs Pistons
 *   npx tsx scripts/fetch-game-analysis.ts MIL BOS    # Analyze Bucks vs Celtics
 */

import { PrismaClient } from '../prisma_sports/generated/sports-client';
import * as fs from 'fs';

const prisma = new PrismaClient();

const ESPN_SCOREBOARD = 'https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard';
const ESPN_TEAMS = 'https://site.api.espn.com/apis/site/v2/sports/basketball/nba/teams';

interface PlayerStats {
  name: string;
  points: { avg: number; high: number; last5: number[] };
  rebounds: { avg: number; high: number; last5: number[] };
  assists: { avg: number; high: number; last5: number[] };
}

async function getPlayerStats(playerName: string): Promise<PlayerStats | null> {
  const stats: PlayerStats = {
    name: playerName,
    points: { avg: 0, high: 0, last5: [] },
    rebounds: { avg: 0, high: 0, last5: [] },
    assists: { avg: 0, high: 0, last5: [] },
  };

  for (const statKey of ['points', 'rebounds', 'assists'] as const) {
    const metrics = await prisma.playerGameMetric.findMany({
      where: {
        league: 'nba',
        playerName: { contains: playerName, mode: 'insensitive' },
        statKey,
      },
      orderBy: { gameDate: 'desc' },
      take: 10,
    });

    if (metrics.length > 0) {
      const values = metrics.map(m => m.value || 0);
      stats[statKey] = {
        avg: values.reduce((a, b) => a + b, 0) / values.length,
        high: Math.max(...values),
        last5: values.slice(0, 5),
      };
    }
  }

  return stats.points.avg > 0 ? stats : null;
}

async function fetchTeamRoster(teamAbbr: string): Promise<string[]> {
  try {
    const teamsResponse = await fetch(`${ESPN_TEAMS}?limit=50`);
    const teamsData = await teamsResponse.json();

    const teams = teamsData?.sports?.[0]?.leagues?.[0]?.teams || [];
    const team = teams.find((t: any) =>
      t.team?.abbreviation?.toUpperCase() === teamAbbr.toUpperCase()
    );

    if (!team) return [];

    const rosterUrl = `https://site.api.espn.com/apis/site/v2/sports/basketball/nba/teams/${team.team.id}/roster`;
    const rosterResponse = await fetch(rosterUrl);
    const rosterData = await rosterResponse.json();

    const athletes = rosterData?.athletes || [];
    const roster: string[] = [];

    for (const item of athletes) {
      if (item?.fullName) {
        roster.push(item.fullName);
      } else if (item?.items) {
        for (const player of item.items) {
          if (player?.fullName) roster.push(player.fullName);
        }
      }
    }

    return roster;
  } catch (error) {
    console.error(`Error fetching roster for ${teamAbbr}:`, error);
    return [];
  }
}

async function fetchGameOdds(team1: string, team2: string): Promise<any> {
  try {
    const response = await fetch(ESPN_SCOREBOARD);
    const data = await response.json();

    for (const event of data.events || []) {
      const competition = event.competitions?.[0];
      if (!competition) continue;

      const homeTeam = competition.competitors?.find((c: any) => c.homeAway === 'home');
      const awayTeam = competition.competitors?.find((c: any) => c.homeAway === 'away');

      const homeAbbr = homeTeam?.team?.abbreviation?.toUpperCase();
      const awayAbbr = awayTeam?.team?.abbreviation?.toUpperCase();

      if (
        (homeAbbr === team1.toUpperCase() || homeAbbr === team2.toUpperCase()) &&
        (awayAbbr === team1.toUpperCase() || awayAbbr === team2.toUpperCase())
      ) {
        const odds = competition.odds?.[0];
        return {
          homeTeam: {
            abbr: homeAbbr,
            name: homeTeam?.team?.displayName,
            score: homeTeam?.score,
          },
          awayTeam: {
            abbr: awayAbbr,
            name: awayTeam?.team?.displayName,
            score: awayTeam?.score,
          },
          status: competition.status?.type?.shortDetail,
          gameTime: event.date,
          venue: competition.venue?.fullName,
          broadcast: competition.broadcasts?.[0]?.names?.[0],
          odds: odds
            ? {
                spread: odds.details,
                spreadHome: odds.pointSpread?.home?.close?.line,
                spreadAway: odds.pointSpread?.away?.close?.line,
                spreadOddsHome: odds.pointSpread?.home?.close?.odds,
                spreadOddsAway: odds.pointSpread?.away?.close?.odds,
                spreadOpen: odds.pointSpread?.home?.open?.line,
                moneylineHome: odds.moneyline?.home?.close?.odds,
                moneylineAway: odds.moneyline?.away?.close?.odds,
                moneylineHomeOpen: odds.moneyline?.home?.open?.odds,
                moneylineAwayOpen: odds.moneyline?.away?.open?.odds,
                total: odds.overUnder,
                totalOpen: odds.total?.over?.open?.line?.replace('o', ''),
                overOdds: odds.total?.over?.close?.odds,
                underOdds: odds.total?.under?.close?.odds,
                provider: odds.provider?.name,
              }
            : null,
        };
      }
    }

    return null;
  } catch (error) {
    console.error('Error fetching game odds:', error);
    return null;
  }
}

async function main() {
  const args = process.argv.slice(2);

  if (args.length < 2) {
    console.log('Usage: npx tsx scripts/fetch-game-analysis.ts TEAM1 TEAM2');
    console.log('Example: npx tsx scripts/fetch-game-analysis.ts BKN DET');
    process.exit(1);
  }

  const [team1, team2] = args.map(a => a.toUpperCase());

  console.log('='.repeat(60));
  console.log(`GAME ANALYSIS: ${team1} vs ${team2}`);
  console.log('='.repeat(60));
  console.log(`Generated: ${new Date().toISOString()}\n`);

  // Fetch game odds
  console.log('Fetching game odds from ESPN...');
  const gameData = await fetchGameOdds(team1, team2);

  if (!gameData) {
    console.log(`No game found for ${team1} vs ${team2} today`);
    await prisma.$disconnect();
    return;
  }

  console.log(`\n${gameData.awayTeam.name} @ ${gameData.homeTeam.name}`);
  console.log(`Time: ${gameData.status}`);
  console.log(`Venue: ${gameData.venue || 'TBD'}`);
  console.log(`TV: ${gameData.broadcast || 'TBD'}`);

  if (gameData.odds) {
    console.log('\n--- ODDS ---');
    console.log(`Provider: ${gameData.odds.provider}`);
    console.log(`Spread: ${gameData.odds.spread} (${gameData.odds.spreadOddsHome})`);
    console.log(`  Opened: ${gameData.odds.spreadOpen}`);
    console.log(`Moneyline: ${gameData.homeTeam.abbr} ${gameData.odds.moneylineHome} | ${gameData.awayTeam.abbr} ${gameData.odds.moneylineAway}`);
    console.log(`  Opened: ${gameData.homeTeam.abbr} ${gameData.odds.moneylineHomeOpen} | ${gameData.awayTeam.abbr} ${gameData.odds.moneylineAwayOpen}`);
    console.log(`Total: ${gameData.odds.total} (O ${gameData.odds.overOdds} | U ${gameData.odds.underOdds})`);
    console.log(`  Opened: ${gameData.odds.totalOpen}`);
  }

  // Fetch rosters
  console.log('\nFetching rosters...');
  const homeRoster = await fetchTeamRoster(gameData.homeTeam.abbr);
  const awayRoster = await fetchTeamRoster(gameData.awayTeam.abbr);

  // Get stats for key players
  console.log('\nFetching player stats...');

  const analysis: any = {
    gameInfo: gameData,
    homeTeam: {
      ...gameData.homeTeam,
      roster: homeRoster,
      playerStats: [],
    },
    awayTeam: {
      ...gameData.awayTeam,
      roster: awayRoster,
      playerStats: [],
    },
    generatedAt: new Date().toISOString(),
  };

  // Get stats for home team players
  console.log(`\n--- ${gameData.homeTeam.name.toUpperCase()} ---`);
  for (const playerName of homeRoster.slice(0, 8)) {
    const stats = await getPlayerStats(playerName);
    if (stats && stats.points.avg > 5) {
      analysis.homeTeam.playerStats.push(stats);
      console.log(`${stats.name}: ${stats.points.avg.toFixed(1)} PPG | ${stats.rebounds.avg.toFixed(1)} RPG | ${stats.assists.avg.toFixed(1)} APG`);
    }
  }

  // Get stats for away team players
  console.log(`\n--- ${gameData.awayTeam.name.toUpperCase()} ---`);
  for (const playerName of awayRoster.slice(0, 8)) {
    const stats = await getPlayerStats(playerName);
    if (stats && stats.points.avg > 5) {
      analysis.awayTeam.playerStats.push(stats);
      console.log(`${stats.name}: ${stats.points.avg.toFixed(1)} PPG | ${stats.rebounds.avg.toFixed(1)} RPG | ${stats.assists.avg.toFixed(1)} APG`);
    }
  }

  // Save analysis
  const filename = `/var/www/html/eventheodds/data/game_analysis_${team1}_${team2}_${new Date().toISOString().split('T')[0]}.json`;
  fs.writeFileSync(filename, JSON.stringify(analysis, null, 2));
  console.log(`\nAnalysis saved to: ${filename}`);

  await prisma.$disconnect();
}

main().catch(async (e) => {
  console.error(e);
  await prisma.$disconnect();
  process.exit(1);
});
