#!/usr/bin/env npx tsx
/**
 * Fix NHL Player Team Assignments
 * Uses NHL API to get current rosters and update canonical players
 */

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

const prisma = new PrismaClient();

const NHL_TEAMS = [
  { id: 1, abbr: 'NJD', name: 'New Jersey Devils' },
  { id: 2, abbr: 'NYI', name: 'New York Islanders' },
  { id: 3, abbr: 'NYR', name: 'New York Rangers' },
  { id: 4, abbr: 'PHI', name: 'Philadelphia Flyers' },
  { id: 5, abbr: 'PIT', name: 'Pittsburgh Penguins' },
  { id: 6, abbr: 'BOS', name: 'Boston Bruins' },
  { id: 7, abbr: 'BUF', name: 'Buffalo Sabres' },
  { id: 8, abbr: 'MTL', name: 'Montreal Canadiens' },
  { id: 9, abbr: 'OTT', name: 'Ottawa Senators' },
  { id: 10, abbr: 'TOR', name: 'Toronto Maple Leafs' },
  { id: 12, abbr: 'CAR', name: 'Carolina Hurricanes' },
  { id: 13, abbr: 'FLA', name: 'Florida Panthers' },
  { id: 14, abbr: 'TBL', name: 'Tampa Bay Lightning' },
  { id: 15, abbr: 'WSH', name: 'Washington Capitals' },
  { id: 16, abbr: 'CHI', name: 'Chicago Blackhawks' },
  { id: 17, abbr: 'DET', name: 'Detroit Red Wings' },
  { id: 18, abbr: 'NSH', name: 'Nashville Predators' },
  { id: 19, abbr: 'STL', name: 'St. Louis Blues' },
  { id: 20, abbr: 'CGY', name: 'Calgary Flames' },
  { id: 21, abbr: 'COL', name: 'Colorado Avalanche' },
  { id: 22, abbr: 'EDM', name: 'Edmonton Oilers' },
  { id: 23, abbr: 'VAN', name: 'Vancouver Canucks' },
  { id: 24, abbr: 'ANA', name: 'Anaheim Ducks' },
  { id: 25, abbr: 'DAL', name: 'Dallas Stars' },
  { id: 26, abbr: 'LAK', name: 'Los Angeles Kings' },
  { id: 28, abbr: 'SJS', name: 'San Jose Sharks' },
  { id: 29, abbr: 'CBJ', name: 'Columbus Blue Jackets' },
  { id: 30, abbr: 'MIN', name: 'Minnesota Wild' },
  { id: 52, abbr: 'WPG', name: 'Winnipeg Jets' },
  { id: 53, abbr: 'ARI', name: 'Arizona Coyotes' },
  { id: 54, abbr: 'VGK', name: 'Vegas Golden Knights' },
  { id: 55, abbr: 'SEA', name: 'Seattle Kraken' },
  { id: 59, abbr: 'UTA', name: 'Utah Hockey Club' },
];

function normalizePlayerName(name: string): string {
  return name.toLowerCase()
    .normalize('NFD').replace(/[\u0300-\u036f]/g, '')
    .replace(/[.']/g, '')
    .replace(/\s+(jr|sr|iii|ii|iv|v)$/i, '')
    .replace(/\s+/g, ' ')
    .trim();
}

async function fetchNHLRoster(teamId: number): Promise<any[]> {
  try {
    const res = await fetch(`https://api-web.nhle.com/v1/roster/${NHL_TEAMS.find(t => t.id === teamId)?.abbr}/current`);
    if (!res.ok) return [];
    const data = await res.json();

    const players: any[] = [];
    for (const pos of ['forwards', 'defensemen', 'goalies']) {
      if (data[pos]) {
        players.push(...data[pos]);
      }
    }
    return players;
  } catch (e) {
    return [];
  }
}

async function main() {
  console.log('='.repeat(60));
  console.log('FIXING NHL PLAYER TEAM ASSIGNMENTS');
  console.log('='.repeat(60) + '\n');

  // Get our canonical teams
  const canonicalTeams = await prisma.canonicalTeam.findMany({
    where: { league: 'nhl' },
    select: { id: true, abbr: true }
  });
  const teamByAbbr = new Map(canonicalTeams.map(t => [t.abbr, t.id]));

  let totalUpdated = 0;
  let totalProcessed = 0;

  for (const team of NHL_TEAMS) {
    const teamId = teamByAbbr.get(team.abbr);
    if (!teamId) {
      console.log(`  [SKIP] No canonical team for ${team.abbr}`);
      continue;
    }

    const roster = await fetchNHLRoster(team.id);
    console.log(`Processing ${team.abbr}: ${roster.length} players`);

    for (const player of roster) {
      const fullName = `${player.firstName?.default || ''} ${player.lastName?.default || ''}`.trim();
      if (!fullName) continue;

      const normalized = normalizePlayerName(fullName);
      totalProcessed++;

      // Update player's team if they exist
      const result = await prisma.canonicalPlayer.updateMany({
        where: {
          league: 'nhl',
          normalizedName: normalized,
          OR: [
            { teamId: null },
            { teamId: { not: teamId } }
          ]
        },
        data: {
          teamId,
          position: player.positionCode || null
        }
      });

      if (result.count > 0) {
        totalUpdated += result.count;
      }
    }

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

  console.log(`\nProcessed ${totalProcessed} players, updated ${totalUpdated} team assignments`);

  // Report remaining without teams
  const remaining = await prisma.canonicalPlayer.count({
    where: { league: 'nhl', teamId: null }
  });
  const total = await prisma.canonicalPlayer.count({ where: { league: 'nhl' } });
  console.log(`NHL players without team: ${remaining}/${total} (${((remaining/total)*100).toFixed(1)}%)`);

  await prisma.$disconnect();
}

main().catch(e => {
  console.error('Failed:', e);
  process.exit(1);
});
