#!/usr/bin/env python3
"""
Official League API Scrapers
Fetches data from free official league APIs:
- MLB Stats API (statsapi.mlb.com)
- NBA Stats (data.nba.com)
- NHL Records API (records.nhl.com)
"""
import requests
import psycopg2
import json
import os
from datetime import datetime, timezone, timedelta

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (compatible; EvenTheOdds/1.0)',
    'Accept': 'application/json',
}

def load_db_url():
    """Load database URL from environment"""
    env_paths = [
        '/var/www/html/eventheodds/.env',
        os.path.join(os.path.dirname(__file__), '..', '.env'),
    ]
    for env_path in env_paths:
        try:
            with open(env_path, 'r') as f:
                for line in f:
                    if line.startswith('SPORTS_DATABASE_URL='):
                        return line.split('=', 1)[1].strip().split('?')[0]
        except FileNotFoundError:
            continue
    return os.environ.get('SPORTS_DATABASE_URL', '').split('?')[0]


# ============================================================================
# MLB Stats API
# ============================================================================

def fetch_mlb_schedule(date_str=None):
    """Fetch MLB schedule from official API"""
    if not date_str:
        date_str = datetime.now().strftime('%Y-%m-%d')

    print(f"\n[MLB API] Fetching schedule for {date_str}...")
    url = f"https://statsapi.mlb.com/api/v1/schedule?sportId=1&date={date_str}"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code}")
            return []

        data = resp.json()
        games = []

        for date_entry in data.get('dates', []):
            for game in date_entry.get('games', []):
                games.append({
                    'gameId': game.get('gamePk'),
                    'gameDate': game.get('gameDate'),
                    'status': game.get('status', {}).get('detailedState'),
                    'homeTeam': game.get('teams', {}).get('home', {}).get('team', {}).get('name'),
                    'homeTeamId': game.get('teams', {}).get('home', {}).get('team', {}).get('id'),
                    'awayTeam': game.get('teams', {}).get('away', {}).get('team', {}).get('name'),
                    'awayTeamId': game.get('teams', {}).get('away', {}).get('team', {}).get('id'),
                    'homeScore': game.get('teams', {}).get('home', {}).get('score'),
                    'awayScore': game.get('teams', {}).get('away', {}).get('score'),
                    'venue': game.get('venue', {}).get('name'),
                    'league': 'mlb',
                    'source': 'mlb-stats-api',
                })

        print(f"  Found {len(games)} MLB games")
        return games

    except Exception as e:
        print(f"  Error: {e}")
        return []


def fetch_mlb_player_stats(player_id, season='2024'):
    """Fetch individual player stats from MLB API"""
    url = f"https://statsapi.mlb.com/api/v1/people/{player_id}/stats?stats=season&season={season}"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            return None

        data = resp.json()
        stats = data.get('stats', [])
        if stats:
            return stats[0].get('splits', [{}])[0].get('stat', {})
        return None

    except Exception as e:
        return None


def fetch_mlb_team_roster(team_id):
    """Fetch team roster from MLB API"""
    url = f"https://statsapi.mlb.com/api/v1/teams/{team_id}/roster"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            return []

        data = resp.json()
        players = []
        for player in data.get('roster', []):
            players.append({
                'playerId': player.get('person', {}).get('id'),
                'playerName': player.get('person', {}).get('fullName'),
                'position': player.get('position', {}).get('abbreviation'),
                'jerseyNumber': player.get('jerseyNumber'),
                'status': player.get('status', {}).get('description'),
            })
        return players

    except Exception as e:
        return []


def fetch_mlb_standings():
    """Fetch MLB standings"""
    print(f"\n[MLB API] Fetching standings...")
    url = "https://statsapi.mlb.com/api/v1/standings?leagueId=103,104"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            return []

        data = resp.json()
        standings = []

        for record in data.get('records', []):
            division = record.get('division', {}).get('name', '')
            for team in record.get('teamRecords', []):
                standings.append({
                    'team': team.get('team', {}).get('name'),
                    'teamId': team.get('team', {}).get('id'),
                    'division': division,
                    'wins': team.get('wins'),
                    'losses': team.get('losses'),
                    'winPct': team.get('winningPercentage'),
                    'gamesBack': team.get('gamesBack'),
                    'streak': team.get('streak', {}).get('streakCode'),
                    'runsScored': team.get('runsScored'),
                    'runsAllowed': team.get('runsAllowed'),
                    'league': 'mlb',
                })

        print(f"  Found {len(standings)} team standings")
        return standings

    except Exception as e:
        print(f"  Error: {e}")
        return []


# ============================================================================
# NBA Stats API
# ============================================================================

NBA_HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
    'Accept': 'application/json',
    'Accept-Language': 'en-US,en;q=0.9',
    'Origin': 'https://www.nba.com',
    'Referer': 'https://www.nba.com/',
}

def fetch_nba_scoreboard(date_str=None):
    """Fetch NBA scoreboard/schedule"""
    if not date_str:
        date_str = datetime.now().strftime('%Y-%m-%d')

    print(f"\n[NBA API] Fetching scoreboard for {date_str}...")
    # Use the CDN endpoint
    url = f"https://cdn.nba.com/static/json/liveData/scoreboard/todaysScoreboard_00.json"

    try:
        resp = requests.get(url, headers=NBA_HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code}")
            return []

        data = resp.json()
        games = []

        for game in data.get('scoreboard', {}).get('games', []):
            games.append({
                'gameId': game.get('gameId'),
                'gameDate': game.get('gameTimeUTC'),
                'status': game.get('gameStatusText'),
                'homeTeam': game.get('homeTeam', {}).get('teamName'),
                'homeTeamCity': game.get('homeTeam', {}).get('teamCity'),
                'homeScore': game.get('homeTeam', {}).get('score'),
                'awayTeam': game.get('awayTeam', {}).get('teamName'),
                'awayTeamCity': game.get('awayTeam', {}).get('teamCity'),
                'awayScore': game.get('awayTeam', {}).get('score'),
                'period': game.get('period'),
                'gameClock': game.get('gameClock'),
                'league': 'nba',
                'source': 'nba-cdn',
            })

        print(f"  Found {len(games)} NBA games")
        return games

    except Exception as e:
        print(f"  Error: {e}")
        return []


def fetch_nba_player_stats(season='2024-25'):
    """Fetch NBA player stats from stats.nba.com"""
    print(f"\n[NBA API] Fetching player stats for {season}...")

    # This endpoint often requires specific headers
    url = f"https://stats.nba.com/stats/leaguedashplayerstats"
    params = {
        'Season': season,
        'SeasonType': 'Regular Season',
        'PerMode': 'PerGame',
        'LeagueID': '00',
    }

    nba_stats_headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'en-US,en;q=0.9',
        'Origin': 'https://www.nba.com',
        'Referer': 'https://www.nba.com/',
        'x-nba-stats-origin': 'stats',
        'x-nba-stats-token': 'true',
    }

    try:
        resp = requests.get(url, params=params, headers=nba_stats_headers, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code} (NBA stats.nba.com may block)")
            return []

        data = resp.json()
        headers = data.get('resultSets', [{}])[0].get('headers', [])
        rows = data.get('resultSets', [{}])[0].get('rowSet', [])

        players = []
        for row in rows:
            player = dict(zip(headers, row))
            players.append({
                'playerId': player.get('PLAYER_ID'),
                'playerName': player.get('PLAYER_NAME'),
                'team': player.get('TEAM_ABBREVIATION'),
                'gamesPlayed': player.get('GP'),
                'minutesPerGame': player.get('MIN'),
                'pointsPerGame': player.get('PTS'),
                'reboundsPerGame': player.get('REB'),
                'assistsPerGame': player.get('AST'),
                'stealsPerGame': player.get('STL'),
                'blocksPerGame': player.get('BLK'),
                'turnoversPerGame': player.get('TOV'),
                'fgPercent': player.get('FG_PCT'),
                'fg3Percent': player.get('FG3_PCT'),
                'ftPercent': player.get('FT_PCT'),
                'league': 'nba',
                'source': 'nba-stats-api',
            })

        print(f"  Found {len(players)} NBA players")
        return players

    except Exception as e:
        print(f"  Error: {e}")
        return []


# ============================================================================
# NHL API
# ============================================================================

def fetch_nhl_schedule(date_str=None):
    """Fetch NHL schedule from official API"""
    if not date_str:
        date_str = datetime.now().strftime('%Y-%m-%d')

    print(f"\n[NHL API] Fetching schedule for {date_str}...")
    url = f"https://api-web.nhle.com/v1/schedule/{date_str}"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code}")
            return []

        data = resp.json()
        games = []

        for game_week in data.get('gameWeek', []):
            for game in game_week.get('games', []):
                games.append({
                    'gameId': game.get('id'),
                    'gameDate': game.get('startTimeUTC'),
                    'gameType': game.get('gameType'),
                    'status': game.get('gameState'),
                    'homeTeam': game.get('homeTeam', {}).get('placeName', {}).get('default', ''),
                    'homeTeamAbbrev': game.get('homeTeam', {}).get('abbrev'),
                    'homeScore': game.get('homeTeam', {}).get('score'),
                    'awayTeam': game.get('awayTeam', {}).get('placeName', {}).get('default', ''),
                    'awayTeamAbbrev': game.get('awayTeam', {}).get('abbrev'),
                    'awayScore': game.get('awayTeam', {}).get('score'),
                    'venue': game.get('venue', {}).get('default'),
                    'league': 'nhl',
                    'source': 'nhl-api',
                })

        print(f"  Found {len(games)} NHL games")
        return games

    except Exception as e:
        print(f"  Error: {e}")
        return []


def fetch_nhl_player_stats(season='20242025'):
    """Fetch NHL skater stats from official API"""
    print(f"\n[NHL API] Fetching skater stats for {season}...")

    # Skater stats leaders
    url = f"https://api-web.nhle.com/v1/skater-stats-leaders/{season}/2"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code}")
            return []

        data = resp.json()
        players = []

        # Process each category
        for category in ['points', 'goals', 'assists', 'plusMinus']:
            if category not in data:
                continue

            for player in data[category]:
                players.append({
                    'playerId': player.get('playerId'),
                    'playerName': f"{player.get('firstName', {}).get('default', '')} {player.get('lastName', {}).get('default', '')}",
                    'team': player.get('teamAbbrevs', ''),
                    'position': player.get('positionCode'),
                    'gamesPlayed': player.get('gamesPlayed'),
                    'goals': player.get('goals'),
                    'assists': player.get('assists'),
                    'points': player.get('points'),
                    'plusMinus': player.get('plusMinus'),
                    'category': category,
                    'league': 'nhl',
                    'source': 'nhl-api',
                })

        # Dedupe by playerId
        seen = {}
        for p in players:
            pid = p['playerId']
            if pid not in seen:
                seen[pid] = p
            else:
                for k, v in p.items():
                    if v is not None and seen[pid].get(k) is None:
                        seen[pid][k] = v

        unique_players = list(seen.values())
        print(f"  Found {len(unique_players)} NHL skaters")
        return unique_players

    except Exception as e:
        print(f"  Error: {e}")
        return []


def fetch_nhl_standings():
    """Fetch NHL standings"""
    print(f"\n[NHL API] Fetching standings...")
    url = "https://api-web.nhle.com/v1/standings/now"

    try:
        resp = requests.get(url, headers=HEADERS, timeout=30)
        if resp.status_code != 200:
            print(f"  Status: {resp.status_code}")
            return []

        data = resp.json()
        standings = []

        for team in data.get('standings', []):
            standings.append({
                'team': team.get('teamName', {}).get('default'),
                'teamAbbrev': team.get('teamAbbrev', {}).get('default'),
                'conference': team.get('conferenceName'),
                'division': team.get('divisionName'),
                'wins': team.get('wins'),
                'losses': team.get('losses'),
                'otLosses': team.get('otLosses'),
                'points': team.get('points'),
                'gamesPlayed': team.get('gamesPlayed'),
                'goalsFor': team.get('goalFor'),
                'goalsAgainst': team.get('goalAgainst'),
                'goalDifferential': team.get('goalDifferential'),
                'streakCode': team.get('streakCode'),
                'league': 'nhl',
            })

        print(f"  Found {len(standings)} NHL teams")
        return standings

    except Exception as e:
        print(f"  Error: {e}")
        return []


# ============================================================================
# Main
# ============================================================================

def save_to_json(data, filename):
    """Save data to JSON file"""
    output_dir = '/var/www/html/eventheodds/data'
    os.makedirs(output_dir, exist_ok=True)
    output_path = os.path.join(output_dir, filename)

    with open(output_path, 'w') as f:
        json.dump(data, f, indent=2, default=str)

    print(f"  Saved to {output_path}")


def main():
    print("=" * 60)
    print("OFFICIAL LEAGUE API SCRAPERS")
    print(f"Time: {datetime.now(timezone.utc).isoformat()}")
    print("=" * 60)

    all_data = {
        'timestamp': datetime.now(timezone.utc).isoformat(),
        'mlb': {},
        'nba': {},
        'nhl': {},
    }

    # MLB
    mlb_schedule = fetch_mlb_schedule()
    mlb_standings = fetch_mlb_standings()
    all_data['mlb'] = {
        'schedule': mlb_schedule,
        'standings': mlb_standings,
    }

    # NBA
    nba_scoreboard = fetch_nba_scoreboard()
    nba_players = fetch_nba_player_stats()
    all_data['nba'] = {
        'scoreboard': nba_scoreboard,
        'players': nba_players,
    }

    # NHL
    nhl_schedule = fetch_nhl_schedule()
    nhl_players = fetch_nhl_player_stats()
    nhl_standings = fetch_nhl_standings()
    all_data['nhl'] = {
        'schedule': nhl_schedule,
        'players': nhl_players,
        'standings': nhl_standings,
    }

    # Save all data
    save_to_json(all_data, 'official_league_data.json')

    # Summary
    print(f"\n{'='*60}")
    print("SUMMARY:")
    print(f"  MLB: {len(mlb_schedule)} games, {len(mlb_standings)} standings")
    print(f"  NBA: {len(nba_scoreboard)} games, {len(nba_players)} players")
    print(f"  NHL: {len(nhl_schedule)} games, {len(nhl_players)} players, {len(nhl_standings)} standings")
    print("=" * 60)


if __name__ == '__main__':
    main()
