#!/usr/bin/env npx tsx
/**
 * Fetch Accurate Player Stats from ESPN
 *
 * This script fetches REAL player statistics directly from ESPN's game log API
 * to ensure accuracy for player props analysis.
 *
 * Usage:
 *   npx tsx scripts/fetch-accurate-player-stats.ts                    # All today's games
 *   npx tsx scripts/fetch-accurate-player-stats.ts --game CHI MIA     # Specific game
 *   npx tsx scripts/fetch-accurate-player-stats.ts --player "Bam Adebayo"  # Specific player
 */

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 PlayerGameLog {
  date: string;
  opponent: string;
  minutes: number;
  points: number;
  rebounds: number;
  assists: number;
  steals: number;
  blocks: number;
  turnovers: number;
  fgm: number;
  fga: number;
  threePm: number;
  threePa: number;
  ftm: number;
  fta: number;
}

interface PlayerStats {
  id: string;
  name: string;
  team: string;
  position: string;
  seasonAvg: {
    points: number;
    rebounds: number;
    assists: number;
    minutes: number;
  };
  last5Avg: {
    points: number;
    rebounds: number;
    assists: number;
  };
  last10Games: PlayerGameLog[];
  trend: 'hot' | 'cold' | 'stable';
}

// ESPN Player IDs for common NBA players
const PLAYER_IDS: Record<string, string> = {
  // Heat
  'bam adebayo': '3917376',
  'tyler herro': '4395725',
  'jimmy butler': '6430',
  'norman powell': '3059318',
  'andrew wiggins': '3059319',
  'jaime jaquez jr': '4702094',
  'terry rozier': '3074752',

  // Bulls
  'nikola vucevic': '3149673',
  'coby white': '4066354',
  'josh giddey': '4432809',
  'ayo dosunmu': '4397020',
  'zach lavine': '3064514',
  'patrick williams': '4594327',
  'matas buzelis': '5106508',

  // Nets
  'cam thomas': '4433218',
  'nic claxton': '4066328',
  'michael porter jr': '4278067',
  'ben simmons': '3907387',

  // Pistons
  'cade cunningham': '4432166',
  'jaden ivey': '4433247',
  'jalen duren': '4702092',
  'tobias harris': '6440',
  'ausar thompson': '4702093',

  // Celtics
  'jayson tatum': '4065648',
  'jaylen brown': '3917376',
  'derrick white': '3078576',
  'payton pritchard': '4066262',
  'kristaps porzingis': '3102531',

  // Bucks
  'giannis antetokounmpo': '3032977',
  'damian lillard': '6606',
  'khris middleton': '6609',
  'bobby portis': '3064439',
  'myles turner': '3064560',

  // Lakers
  'lebron james': '1966',
  'luka doncic': '3945274',
  'austin reaves': '4397136',

  // Other stars
  'kevin durant': '3202',
  'stephen curry': '3975',
  'shai gilgeous-alexander': '4278073',
  'nikola jokic': '3112335',
  'joel embiid': '3059318',
  'anthony davis': '6583',
  'trae young': '4277905',
};

async function fetchPlayerGameLog(playerId: string): Promise<PlayerGameLog[]> {
  try {
    const url = `https://site.web.api.espn.com/apis/common/v3/sports/basketball/nba/athletes/${playerId}/gamelog`;
    const response = await fetch(url);

    if (!response.ok) {
      console.error(`Failed to fetch game log for player ${playerId}: ${response.status}`);
      return [];
    }

    const data = await response.json();
    const events = data?.seasonTypes?.[0]?.categories?.[0]?.events || {};
    const games: PlayerGameLog[] = [];

    for (const [gameId, gameData] of Object.entries(events)) {
      const game = gameData as any;
      if (!game.stats) continue;

      games.push({
        date: game.gameDate || '',
        opponent: game.opponent?.abbreviation || '',
        minutes: parseFloat(game.stats[0]) || 0,
        fgm: parseInt(game.stats[1]?.split('-')[0]) || 0,
        fga: parseInt(game.stats[1]?.split('-')[1]) || 0,
        threePm: parseInt(game.stats[3]?.split('-')[0]) || 0,
        threePa: parseInt(game.stats[3]?.split('-')[1]) || 0,
        ftm: parseInt(game.stats[5]?.split('-')[0]) || 0,
        fta: parseInt(game.stats[5]?.split('-')[1]) || 0,
        rebounds: parseInt(game.stats[7]) || 0,
        assists: parseInt(game.stats[8]) || 0,
        blocks: parseInt(game.stats[9]) || 0,
        steals: parseInt(game.stats[10]) || 0,
        turnovers: parseInt(game.stats[12]) || 0,
        points: parseInt(game.stats[13]) || 0,
      });
    }

    return games.slice(0, 15); // Last 15 games
  } catch (error) {
    console.error(`Error fetching game log for player ${playerId}:`, error);
    return [];
  }
}

async function fetchTeamRoster(teamAbbr: string): Promise<Array<{id: string, name: string, position: 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: Array<{id: string, name: string, position: string}> = [];

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

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

function calculatePlayerStats(name: string, team: string, position: string, games: PlayerGameLog[]): PlayerStats {
  const last5 = games.slice(0, 5);
  const last10 = games.slice(0, 10);

  const avg = (arr: number[]) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;

  const seasonPts = avg(last10.map(g => g.points));
  const seasonReb = avg(last10.map(g => g.rebounds));
  const seasonAst = avg(last10.map(g => g.assists));
  const seasonMin = avg(last10.map(g => g.minutes));

  const last5Pts = avg(last5.map(g => g.points));
  const last5Reb = avg(last5.map(g => g.rebounds));
  const last5Ast = avg(last5.map(g => g.assists));

  // Determine trend
  let trend: 'hot' | 'cold' | 'stable' = 'stable';
  if (last5Pts > seasonPts * 1.15) trend = 'hot';
  else if (last5Pts < seasonPts * 0.85) trend = 'cold';

  return {
    id: PLAYER_IDS[name.toLowerCase()] || '',
    name,
    team,
    position,
    seasonAvg: {
      points: Math.round(seasonPts * 10) / 10,
      rebounds: Math.round(seasonReb * 10) / 10,
      assists: Math.round(seasonAst * 10) / 10,
      minutes: Math.round(seasonMin * 10) / 10,
    },
    last5Avg: {
      points: Math.round(last5Pts * 10) / 10,
      rebounds: Math.round(last5Reb * 10) / 10,
      assists: Math.round(last5Ast * 10) / 10,
    },
    last10Games: last10,
    trend,
  };
}

async function fetchGameAnalysis(team1: string, team2: string) {
  console.log(`\n${'='.repeat(60)}`);
  console.log(`ACCURATE PLAYER STATS: ${team1} vs ${team2}`);
  console.log(`${'='.repeat(60)}`);
  console.log(`Generated: ${new Date().toISOString()}\n`);

  // Fetch rosters
  console.log('Fetching rosters...');
  const roster1 = await fetchTeamRoster(team1);
  const roster2 = await fetchTeamRoster(team2);

  console.log(`${team1}: ${roster1.length} players`);
  console.log(`${team2}: ${roster2.length} players\n`);

  const allPlayerStats: PlayerStats[] = [];

  // Process team 1
  console.log(`\n--- ${team1} PLAYER STATS ---\n`);
  for (const player of roster1.slice(0, 10)) {
    const games = await fetchPlayerGameLog(player.id);
    if (games.length > 0) {
      const stats = calculatePlayerStats(player.name, team1, player.position, games);
      allPlayerStats.push(stats);

      const last5Str = games.slice(0, 5).map(g => g.points).join(', ');
      const trendIcon = stats.trend === 'hot' ? '🔥' : stats.trend === 'cold' ? '❄️' : '➡️';

      console.log(`${player.name} (${player.position})`);
      console.log(`  Season: ${stats.seasonAvg.points} PPG | ${stats.seasonAvg.rebounds} RPG | ${stats.seasonAvg.assists} APG`);
      console.log(`  Last 5: ${last5Str} (avg ${stats.last5Avg.points}) ${trendIcon}`);
    }

    // Small delay to avoid rate limiting
    await new Promise(r => setTimeout(r, 100));
  }

  // Process team 2
  console.log(`\n--- ${team2} PLAYER STATS ---\n`);
  for (const player of roster2.slice(0, 10)) {
    const games = await fetchPlayerGameLog(player.id);
    if (games.length > 0) {
      const stats = calculatePlayerStats(player.name, team2, player.position, games);
      allPlayerStats.push(stats);

      const last5Str = games.slice(0, 5).map(g => g.points).join(', ');
      const trendIcon = stats.trend === 'hot' ? '🔥' : stats.trend === 'cold' ? '❄️' : '➡️';

      console.log(`${player.name} (${player.position})`);
      console.log(`  Season: ${stats.seasonAvg.points} PPG | ${stats.seasonAvg.rebounds} RPG | ${stats.seasonAvg.assists} APG`);
      console.log(`  Last 5: ${last5Str} (avg ${stats.last5Avg.points}) ${trendIcon}`);
    }

    await new Promise(r => setTimeout(r, 100));
  }

  // Save to JSON
  const filename = `/var/www/html/eventheodds/data/player_stats_${team1}_${team2}_${new Date().toISOString().split('T')[0]}.json`;
  fs.writeFileSync(filename, JSON.stringify({
    generatedAt: new Date().toISOString(),
    teams: [team1, team2],
    players: allPlayerStats,
  }, null, 2));

  console.log(`\nSaved to: ${filename}`);

  return allPlayerStats;
}

async function fetchTodaysGames() {
  try {
    const response = await fetch(ESPN_SCOREBOARD);
    const data = await response.json();

    const games: Array<{away: string, home: string, time: string, spread?: string, total?: number}> = [];

    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 odds = competition.odds?.[0];

      games.push({
        away: awayTeam?.team?.abbreviation || '',
        home: homeTeam?.team?.abbreviation || '',
        time: competition.status?.type?.shortDetail || '',
        spread: odds?.details,
        total: odds?.overUnder,
      });
    }

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

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

  if (args.includes('--game') && args.length >= 3) {
    const idx = args.indexOf('--game');
    const team1 = args[idx + 1]?.toUpperCase();
    const team2 = args[idx + 2]?.toUpperCase();

    if (team1 && team2) {
      await fetchGameAnalysis(team1, team2);
    }
  } else if (args.includes('--player')) {
    const idx = args.indexOf('--player');
    const playerName = args[idx + 1];

    if (playerName) {
      const playerId = PLAYER_IDS[playerName.toLowerCase()];
      if (playerId) {
        console.log(`Fetching stats for ${playerName}...`);
        const games = await fetchPlayerGameLog(playerId);
        console.log(`\nLast 10 games:`);
        games.slice(0, 10).forEach((g, i) => {
          console.log(`${i + 1}. ${g.points} pts, ${g.rebounds} reb, ${g.assists} ast vs ${g.opponent}`);
        });
      } else {
        console.log(`Player "${playerName}" not found in database. Add their ESPN ID to PLAYER_IDS.`);
      }
    }
  } else {
    // Fetch all today's games
    console.log('='.repeat(60));
    console.log('TODAY\'S NBA GAMES WITH LIVE ODDS');
    console.log('='.repeat(60));
    console.log(`Generated: ${new Date().toISOString()}\n`);

    const games = await fetchTodaysGames();

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

    for (const game of games) {
      console.log(`${game.away} @ ${game.home}`);
      console.log(`  Time: ${game.time}`);
      if (game.spread) console.log(`  Spread: ${game.spread}`);
      if (game.total) console.log(`  Total: ${game.total}`);
      console.log('');
    }

    // Save schedule
    const schedulePath = '/var/www/html/eventheodds/data/nba_schedule_today.json';
    fs.writeFileSync(schedulePath, JSON.stringify({
      date: new Date().toISOString().split('T')[0],
      generatedAt: new Date().toISOString(),
      games,
    }, null, 2));

    console.log(`Schedule saved to: ${schedulePath}`);
  }
}

main().catch(console.error);
