#!/usr/bin/env npx tsx
/**
 * Sync Rosters - Fetch current team rosters and track player movements
 */

require('dotenv').config({ path: '.env.local' });
require('dotenv').config({ path: '.env' });

import { getSportsDb, isSportsDbEnabled } from '../lib/sportsDb';

const NBA_TEAMS: Record<string, { id: string; abbrev: string }> = {
  'ATL': { id: '1', abbrev: 'ATL' }, 'BOS': { id: '2', abbrev: 'BOS' },
  'BKN': { id: '17', abbrev: 'BKN' }, 'CHA': { id: '30', abbrev: 'CHA' },
  'CHI': { id: '4', abbrev: 'CHI' }, 'CLE': { id: '5', abbrev: 'CLE' },
  'DAL': { id: '6', abbrev: 'DAL' }, 'DEN': { id: '7', abbrev: 'DEN' },
  'DET': { id: '8', abbrev: 'DET' }, 'GSW': { id: '9', abbrev: 'GSW' },
  'HOU': { id: '10', abbrev: 'HOU' }, 'IND': { id: '11', abbrev: 'IND' },
  'LAC': { id: '12', abbrev: 'LAC' }, 'LAL': { id: '13', abbrev: 'LAL' },
  'MEM': { id: '29', abbrev: 'MEM' }, 'MIA': { id: '14', abbrev: 'MIA' },
  'MIL': { id: '15', abbrev: 'MIL' }, 'MIN': { id: '16', abbrev: 'MIN' },
  'NOP': { id: '3', abbrev: 'NOP' }, 'NYK': { id: '18', abbrev: 'NYK' },
  'OKC': { id: '25', abbrev: 'OKC' }, 'ORL': { id: '19', abbrev: 'ORL' },
  'PHI': { id: '20', abbrev: 'PHI' }, 'PHX': { id: '21', abbrev: 'PHX' },
  'POR': { id: '22', abbrev: 'POR' }, 'SAC': { id: '23', abbrev: 'SAC' },
  'SAS': { id: '24', abbrev: 'SAS' }, 'TOR': { id: '28', abbrev: 'TOR' },
  'UTA': { id: '26', abbrev: 'UTA' }, 'WAS': { id: '27', abbrev: 'WAS' },
};

const NFL_TEAMS: Record<string, { id: string; abbrev: string }> = {
  'ARI': { id: '22', abbrev: 'ARI' }, 'ATL': { id: '1', abbrev: 'ATL' },
  'BAL': { id: '33', abbrev: 'BAL' }, 'BUF': { id: '2', abbrev: 'BUF' },
  'CAR': { id: '29', abbrev: 'CAR' }, 'CHI': { id: '3', abbrev: 'CHI' },
  'CIN': { id: '4', abbrev: 'CIN' }, 'CLE': { id: '5', abbrev: 'CLE' },
  'DAL': { id: '6', abbrev: 'DAL' }, 'DEN': { id: '7', abbrev: 'DEN' },
  'DET': { id: '8', abbrev: 'DET' }, 'GB': { id: '9', abbrev: 'GB' },
  'HOU': { id: '34', abbrev: 'HOU' }, 'IND': { id: '11', abbrev: 'IND' },
  'JAX': { id: '30', abbrev: 'JAX' }, 'KC': { id: '12', abbrev: 'KC' },
  'LV': { id: '13', abbrev: 'LV' }, 'LAC': { id: '24', abbrev: 'LAC' },
  'LAR': { id: '14', abbrev: 'LAR' }, 'MIA': { id: '15', abbrev: 'MIA' },
  'MIN': { id: '16', abbrev: 'MIN' }, 'NE': { id: '17', abbrev: 'NE' },
  'NO': { id: '18', abbrev: 'NO' }, 'NYG': { id: '19', abbrev: 'NYG' },
  'NYJ': { id: '20', abbrev: 'NYJ' }, 'PHI': { id: '21', abbrev: 'PHI' },
  'PIT': { id: '23', abbrev: 'PIT' }, 'SF': { id: '25', abbrev: 'SF' },
  'SEA': { id: '26', abbrev: 'SEA' }, 'TB': { id: '27', abbrev: 'TB' },
  'TEN': { id: '10', abbrev: 'TEN' }, 'WAS': { id: '28', abbrev: 'WAS' },
};

interface RosterPlayer {
  espnId: string;
  name: string;
  position: string;
  team: string;
}

interface PlayerChange {
  name: string;
  oldTeam: string | null;
  newTeam: string;
  espnId?: string;
}

async function fetchESPNRoster(league: string, teamAbbrev: string, teamId: string): Promise<RosterPlayer[]> {
  const sport = league === 'nba' ? 'basketball/nba' : 'football/nfl';
  const url = `https://site.api.espn.com/apis/site/v2/sports/${sport}/teams/${teamId}/roster`;
  
  try {
    const response = await fetch(url);
    if (!response.ok) return [];
    
    const data = await response.json();
    const players: RosterPlayer[] = [];
    
    const athletes = data.athletes || [];
    
    // NFL has nested structure: athletes[{position, items[]}]
    // NBA has flat structure: athletes[]
    for (const item of athletes) {
      if (item.items) {
        // NFL structure
        for (const player of item.items) {
          if (player.fullName) {
            players.push({
              espnId: player.id,
              name: player.fullName,
              position: player.position?.abbreviation || '',
              team: teamAbbrev,
            });
          }
        }
      } else if (item.fullName) {
        // NBA structure
        players.push({
          espnId: item.id,
          name: item.fullName,
          position: item.position?.abbreviation || '',
          team: teamAbbrev,
        });
      }
    }
    
    return players;
  } catch (err) {
    return [];
  }
}

async function syncLeagueRosters(league: string): Promise<PlayerChange[]> {
  const prisma = getSportsDb();
  const teams = league === 'nba' ? NBA_TEAMS : NFL_TEAMS;
  const changes: PlayerChange[] = [];
  
  console.log(`\n📋 Fetching ${league.toUpperCase()} rosters from ESPN...`);
  
  let totalPlayers = 0;
  const allRosterPlayers: RosterPlayer[] = [];
  
  let teamIndex = 0;
  for (const [abbrev, team] of Object.entries(teams)) {
    const roster = await fetchESPNRoster(league, abbrev, team.id);
    totalPlayers += roster.length;
    allRosterPlayers.push(...roster);
    teamIndex++;
    process.stdout.write(`\r  Fetched ${teamIndex}/${Object.keys(teams).length} teams (${totalPlayers} players)`);
    await new Promise(r => setTimeout(r, 100));
  }
  
  console.log(`\n  Total roster players: ${totalPlayers}`);
  console.log(`\n🔄 Checking for player movements...`);
  
  let checked = 0;
  for (const rosterPlayer of allRosterPlayers) {
    checked++;
    if (checked % 100 === 0) {
      process.stdout.write(`\r  Checked ${checked}/${allRosterPlayers.length} players`);
    }
    
    const dbPlayer = await prisma.player.findFirst({
      where: {
        name: { equals: rosterPlayer.name, mode: 'insensitive' },
        league: league,
      },
    });
    
    if (dbPlayer && dbPlayer.team) {
      const dbTeam = dbPlayer.team.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 3);
      const newTeam = rosterPlayer.team.toUpperCase();
      
      if (dbTeam !== newTeam && dbTeam !== newTeam.slice(0, 3)) {
        changes.push({
          name: rosterPlayer.name,
          oldTeam: dbPlayer.team,
          newTeam: rosterPlayer.team,
          espnId: rosterPlayer.espnId,
        });

        // Update player's current team
        await prisma.player.update({
          where: { id: dbPlayer.id },
          data: {
            team: rosterPlayer.team,
            position: rosterPlayer.position || dbPlayer.position,
            updatedAt: new Date(),
          },
        });

        // Log transaction to PlayerTransaction table
        const currentSeason = new Date().getMonth() >= 9 ? new Date().getFullYear() + 1 : new Date().getFullYear();
        await prisma.playerTransaction.upsert({
          where: {
            league_externalPlayerId_transactionDate_toTeam: {
              league: league,
              externalPlayerId: rosterPlayer.espnId || '',
              transactionDate: new Date(),
              toTeam: rosterPlayer.team,
            },
          },
          create: {
            league: league,
            externalPlayerId: rosterPlayer.espnId,
            playerName: rosterPlayer.name,
            fromTeam: dbPlayer.team,
            toTeam: rosterPlayer.team,
            transactionType: 'roster_move',  // Could be trade, FA, etc - ESPN doesn't tell us
            transactionDate: new Date(),
            season: currentSeason,
            source: 'espn',
            verified: false,
          },
          update: {},  // Don't update if exists
        });
      }
    }
  }
  
  console.log(`\r  Checked ${allRosterPlayers.length}/${allRosterPlayers.length} players`);
  return changes;
}

async function main() {
  const args = process.argv.slice(2);
  const allLeagues = args.includes('--all');
  const leagueArg = args.find(a => a.startsWith('--league='));
  const league = leagueArg?.split('=')[1]?.toLowerCase();

  console.log('🔄 Roster Sync Tool');
  console.log('='.repeat(50));

  if (!isSportsDbEnabled()) {
    console.error('❌ SportsDB not enabled');
    process.exit(1);
  }

  const leagues = allLeagues ? ['nba', 'nfl'] : (league ? [league] : []);

  if (leagues.length === 0) {
    console.log('\nUsage: npx tsx src/scripts/syncRosters.ts --league=nba|nfl|--all');
    process.exit(0);
  }

  const prisma = getSportsDb();
  let totalTransactions = 0;

  for (const l of leagues) {
    const changes = await syncLeagueRosters(l);
    totalTransactions += changes.length;

    console.log(`\n${l.toUpperCase()}: ${changes.length} player movements logged`);
    if (changes.length > 0) {
      console.log('  Key moves:');
      for (const c of changes.slice(0, 25)) {
        console.log(`    ${c.name}: ${c.oldTeam} → ${c.newTeam}`);
      }
      if (changes.length > 25) console.log(`    ... and ${changes.length - 25} more`);
    }
  }

  // Show transaction table stats
  const txCount = await prisma.playerTransaction.count();
  console.log(`\n📊 PlayerTransaction table: ${txCount} total records`);

  // Show recent transactions
  const recentTx = await prisma.playerTransaction.findMany({
    orderBy: { createdAt: 'desc' },
    take: 5,
  });
  if (recentTx.length > 0) {
    console.log('  Recent transactions:');
    for (const tx of recentTx) {
      console.log(`    ${tx.playerName} (${tx.league.toUpperCase()}): ${tx.fromTeam || '?'} → ${tx.toTeam} [${tx.transactionDate.toISOString().slice(0, 10)}]`);
    }
  }

  console.log('\n✅ Roster sync complete!');
}

main().catch(console.error);
