#!/usr/bin/env npx tsx
/**
 * Fetch Live NBA Data from ESPN
 *
 * Usage:
 *   npx tsx scripts/fetch-live-nba-data.ts              # Get today's games
 *   npx tsx scripts/fetch-live-nba-data.ts --save       # Save to JSON files
 *   npx tsx scripts/fetch-live-nba-data.ts --game BKN   # Get specific game by team abbr
 */

import * as fs from 'fs';

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 GameOdds {
  spread: string;
  spreadOdds: string;
  moneylineHome: string;
  moneylineAway: string;
  total: number;
  overOdds: string;
  underOdds: string;
  provider: string;
}

interface GameInfo {
  id: string;
  status: string;
  statusDetail: string;
  startTime: string;
  homeTeam: {
    abbr: string;
    name: string;
    score: string;
  };
  awayTeam: {
    abbr: string;
    name: string;
    score: string;
  };
  odds?: GameOdds;
  venue?: string;
  broadcast?: string;
}

async function fetchTodaysGames(): Promise<GameInfo[]> {
  try {
    const response = await fetch(ESPN_SCOREBOARD);
    if (!response.ok) {
      throw new Error(`ESPN API error: ${response.status}`);
    }

    const data = await response.json();
    const games: GameInfo[] = [];

    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 game: GameInfo = {
        id: event.id,
        status: competition.status?.type?.state || 'unknown',
        statusDetail: competition.status?.type?.shortDetail || '',
        startTime: event.date,
        homeTeam: {
          abbr: homeTeam?.team?.abbreviation || '',
          name: homeTeam?.team?.displayName || '',
          score: homeTeam?.score || '0',
        },
        awayTeam: {
          abbr: awayTeam?.team?.abbreviation || '',
          name: awayTeam?.team?.displayName || '',
          score: awayTeam?.score || '0',
        },
        venue: competition.venue?.fullName,
        broadcast: competition.broadcasts?.[0]?.names?.[0],
      };

      // Parse odds if available
      const oddsData = competition.odds?.[0];
      if (oddsData) {
        game.odds = {
          spread: oddsData.details || '',
          spreadOdds: oddsData.pointSpread?.home?.close?.odds || '',
          moneylineHome: oddsData.moneyline?.home?.close?.odds || '',
          moneylineAway: oddsData.moneyline?.away?.close?.odds || '',
          total: oddsData.overUnder || 0,
          overOdds: oddsData.total?.over?.close?.odds || '',
          underOdds: oddsData.total?.under?.close?.odds || '',
          provider: oddsData.provider?.name || 'Unknown',
        };
      }

      games.push(game);
    }

    return games;
  } catch (error) {
    console.error('Error fetching games:', error);
    return [];
  }
}

async function fetchTeamRoster(teamAbbr: string): Promise<any> {
  try {
    // First get team ID
    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) {
      console.log(`Team ${teamAbbr} not found`);
      return null;
    }

    // Fetch roster
    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: Array<{ name: string; position: string; jersey: string }> = [];

    for (const item of athletes) {
      if (item?.fullName || item?.displayName) {
        roster.push({
          name: item?.fullName || item?.displayName || '',
          position: item?.position?.abbreviation || '',
          jersey: item?.jersey || '',
        });
      } else if (item?.items) {
        for (const player of item.items) {
          roster.push({
            name: player?.fullName || player?.displayName || '',
            position: player?.position?.abbreviation || '',
            jersey: player?.jersey || '',
          });
        }
      }
    }

    return {
      team: team.team.displayName,
      abbr: team.team.abbreviation,
      roster,
    };
  } catch (error) {
    console.error(`Error fetching roster for ${teamAbbr}:`, error);
    return null;
  }
}

function formatGameDisplay(game: GameInfo): string {
  const time = new Date(game.startTime).toLocaleTimeString('en-US', {
    hour: 'numeric',
    minute: '2-digit',
    timeZoneName: 'short',
  });

  let output = `\n${game.awayTeam.name} @ ${game.homeTeam.name}`;
  output += `\nTime: ${time} | Status: ${game.statusDetail}`;

  if (game.status === 'in') {
    output += `\nScore: ${game.awayTeam.abbr} ${game.awayTeam.score} - ${game.homeTeam.abbr} ${game.homeTeam.score}`;
  }

  if (game.odds) {
    output += `\n--- ODDS (${game.odds.provider}) ---`;
    output += `\nSpread: ${game.odds.spread} (${game.odds.spreadOdds})`;
    output += `\nMoneyline: ${game.homeTeam.abbr} ${game.odds.moneylineHome} | ${game.awayTeam.abbr} ${game.odds.moneylineAway}`;
    output += `\nTotal: ${game.odds.total} (O ${game.odds.overOdds} | U ${game.odds.underOdds})`;
  }

  if (game.venue) output += `\nVenue: ${game.venue}`;
  if (game.broadcast) output += `\nTV: ${game.broadcast}`;

  return output;
}

async function main() {
  const args = process.argv.slice(2);
  const shouldSave = args.includes('--save');
  const gameFilter = args.find(a => a !== '--save' && !a.startsWith('--'))?.toUpperCase();

  console.log('='.repeat(60));
  console.log('LIVE NBA DATA FROM ESPN');
  console.log('='.repeat(60));
  console.log(`Fetched: ${new Date().toISOString()}\n`);

  const games = await fetchTodaysGames();

  if (games.length === 0) {
    console.log('No games found for today');
    return;
  }

  console.log(`Found ${games.length} games today\n`);

  // Filter by team if specified
  const filteredGames = gameFilter
    ? games.filter(g =>
        g.homeTeam.abbr === gameFilter || g.awayTeam.abbr === gameFilter
      )
    : games;

  for (const game of filteredGames) {
    console.log(formatGameDisplay(game));
    console.log('-'.repeat(50));
  }

  // Save to JSON if requested
  if (shouldSave) {
    const dataDir = '/var/www/html/eventheodds/data';

    // Save games
    const gamesPath = `${dataDir}/nba_live_games.json`;
    fs.writeFileSync(gamesPath, JSON.stringify({
      lastUpdated: new Date().toISOString(),
      source: 'ESPN',
      games,
    }, null, 2));
    console.log(`\nSaved games to: ${gamesPath}`);

    // Save schedule summary
    const schedulePath = `${dataDir}/nba_today_schedule.json`;
    const schedule = games.map(g => ({
      time: g.statusDetail,
      away: g.awayTeam.abbr,
      home: g.homeTeam.abbr,
      spread: g.odds?.spread || 'N/A',
      total: g.odds?.total || 'N/A',
      status: g.status,
    }));
    fs.writeFileSync(schedulePath, JSON.stringify({
      date: new Date().toISOString().split('T')[0],
      games: schedule,
    }, null, 2));
    console.log(`Saved schedule to: ${schedulePath}`);
  }
}

main().catch(console.error);
