import re
from datetime import datetime

import requests


def get_team_player_leaders_data(team_id, espn_sport, league, debug_log, api_headers):
    """Get top player leaders for a team."""
    try:
        current_year = datetime.now().year

        athlete_names = {}
        roster_url = f"https://site.api.espn.com/apis/site/v2/sports/{espn_sport}/{league}/teams/{team_id}/roster?season={current_year}"
        debug_log(f"SportsGrid: Fetching roster for names from {roster_url}")
        try:
            roster_response = requests.get(roster_url, headers=api_headers, timeout=15)
            if roster_response.status_code == 200:
                roster_data = roster_response.json()
                for athlete in roster_data.get('athletes', []):
                    athlete_id = str(athlete.get('id', ''))
                    full_name = athlete.get('fullName', '')
                    if athlete_id and full_name:
                        athlete_names[athlete_id] = full_name
                debug_log(f"SportsGrid: Got {len(athlete_names)} athlete names")
        except Exception as e:
            debug_log(f"SportsGrid: Error fetching roster: {str(e)}")

        team_url = f"https://sports.core.api.espn.com/v2/sports/{espn_sport}/leagues/{league}/seasons/{current_year}/types/2/teams/{team_id}/statistics?enable=ranks"
        debug_log(f"SportsGrid: Fetching player leaders from {team_url}")

        response = requests.get(team_url, headers=api_headers, timeout=15)
        if response.status_code != 200:
            debug_log(f"SportsGrid: Failed to get player leaders, status {response.status_code}")
            return {}

        data = response.json()
        debug_log(f"SportsGrid: Player API response keys: {data.keys()}")

        team_data = data.get('team', {})
        if isinstance(team_data, dict) and '$ref' in team_data:
            ref_url = team_data.get('$ref', '')
            debug_log(f"SportsGrid: Following $ref to get team data: {ref_url}")
            ref_response = requests.get(ref_url, headers=api_headers, timeout=15)
            if ref_response.status_code == 200:
                team_data = ref_response.json()
                debug_log(f"SportsGrid: Team data after $ref: keys={team_data.keys()}")
            else:
                debug_log(f"SportsGrid: Failed to follow $ref, status {ref_response.status_code}")
                return {}

        debug_log(f"SportsGrid: Team data keys: {team_data.keys() if isinstance(team_data, dict) else type(team_data)}")
        debug_log(f"SportsGrid: Data top-level keys: {data.keys()}")

        leaders = team_data.get('leaders', []) if isinstance(team_data, dict) else []
        if isinstance(leaders, dict) and '$ref' in leaders:
            leaders_ref = leaders.get('$ref', '')
            debug_log(f"SportsGrid: Following leaders $ref: {leaders_ref}")
            leaders_response = requests.get(leaders_ref, headers=api_headers, timeout=15)
            if leaders_response.status_code == 200:
                leaders_data = leaders_response.json()
                debug_log(f"SportsGrid: Leaders $ref response keys: {leaders_data.keys()}")
                leaders = leaders_data.get('categories', [])
                debug_log(f"SportsGrid: Found {len(leaders)} leader categories from $ref")
            else:
                debug_log(f"SportsGrid: Failed to get leaders $ref, status {leaders_response.status_code}")
                leaders = []

        if not leaders:
            leaders = data.get('leaders', [])
            debug_log(f"SportsGrid: Checking top-level leaders: {len(leaders)} categories")

        if not leaders:
            splits = team_data.get('splits', {}) if isinstance(team_data, dict) else {}
            debug_log(f"SportsGrid: Splits keys: {splits.keys() if splits else 'None'}")
            categories = splits.get('categories', []) if splits else []
            if categories:
                debug_log(f"SportsGrid: Stats categories: {[c.get('name') for c in categories]}")

        stat_priority = {
            'pointsPerGame': 1,
            'assistsPerGame': 2,
            'reboundsPerGame': 3,
            'defensiveReboundsPerGame': 4,
            'offensiveReboundsPerGame': 5,
            'stealsPerGame': 6,
            'blocksPerGame': 7,
            'fieldGoalsMadePerGame': 8,
            'threePointersMadePerGame': 9,
            'freeThrowsMadePerGame': 10,
            'turnoversPerGame': 11,
            'foulsPerGame': 12,
        }
        stat_friendly_names = {
            'pointsPerGame': 'Points',
            'assistsPerGame': 'Assists',
            'reboundsPerGame': 'Rebounds',
            'defensiveReboundsPerGame': 'Def Reb',
            'offensiveReboundsPerGame': 'Off Reb',
            'stealsPerGame': 'Steals',
            'blocksPerGame': 'Blocks',
            'fieldGoalsMadePerGame': 'FG Made',
            'threePointersMadePerGame': '3PM',
            'freeThrowsMadePerGame': 'FT Made',
            'turnoversPerGame': 'Turnovers',
            'foulsPerGame': 'Fouls',
        }

        sorted_leaders = []
        if leaders:
            for category in leaders:
                if not isinstance(category, dict):
                    continue
                stat_name = category.get('name', '')
                priority = stat_priority.get(stat_name, 999)
                sorted_leaders.append((priority, category))
            sorted_leaders.sort(key=lambda x: x[0])

        player_leaders = []
        player_stat_map = {}
        for _priority, category in sorted_leaders:
            stat_name = category.get('name', '')
            stat_leaders = category.get('leaders', [])
            if not stat_leaders:
                continue
            top_player = stat_leaders[0]
            if not isinstance(top_player, dict):
                continue
            player_stat = top_player.get('displayValue', '')

            player_name = ''
            athlete_info = top_player.get('athlete', {})
            if isinstance(athlete_info, dict) and '$ref' in athlete_info:
                athlete_ref = athlete_info.get('$ref', '')
                match = re.search(r'/athletes/(\d+)', athlete_ref)
                if match:
                    athlete_id = match.group(1)
                    player_name = athlete_names.get(athlete_id, '')

            if player_stat and player_name and player_name not in player_stat_map:
                friendly_stat = stat_friendly_names.get(stat_name, stat_name)
                player_leaders.append((player_name, f"{player_stat} {friendly_stat}"))
                player_stat_map[player_name] = friendly_stat
                if len(player_leaders) >= 3:
                    break

        if not player_leaders:
            athletes = data.get('athletes', [])
            debug_log(f"SportsGrid: No leaders, checking top-level athletes. Count: {len(athletes)}")
            if athletes and isinstance(athletes[0], dict):
                first_athlete = athletes[0]
                debug_log(f"SportsGrid: First athlete keys: {first_athlete.keys()}")
                if 'statistics' in first_athlete:
                    debug_log(f"SportsGrid: First athlete stats: {first_athlete.get('statistics', {})}")

        debug_log(f"SportsGrid: Found {len(player_leaders)} player leaders: {player_leaders}")
        result = dict(player_leaders[:3])
        debug_log(f"SportsGrid: Player leaders (top 3): {result}")
        return result
    except Exception as e:
        debug_log(f"SportsGrid: Error in get_team_player_leaders: {str(e)}")
        return {}


def get_team_season_leaders_data(
    sport,
    team_name,
    get_cached,
    set_cached,
    get_espn_core_sport_fn,
    team_color_overrides,
    get_team_player_leaders_fn,
    debug_log,
    log_error,
    api_headers,
):
    """Get season rankings/stat leaders for a team."""
    try:
        cached = get_cached(team_name, 'season_leaders')
        if cached is not None:
            return cached

        sport_info = get_espn_core_sport_fn(sport)
        if not sport_info:
            return {}

        espn_sport, league = sport_info
        current_year = datetime.now().year

        teams_url = f"https://sports.core.api.espn.com/v2/sports/{espn_sport}/leagues/{league}/seasons/{current_year}/teams"
        debug_log(f"SportsGrid: Finding team ID from {teams_url}")

        teams_response = requests.get(teams_url, headers=api_headers, timeout=15)
        if teams_response.status_code != 200:
            debug_log(f"SportsGrid: Teams API status: {teams_response.status_code}")
            return {}

        teams_data = teams_response.json()
        debug_log(f"SportsGrid: Teams API response keys: {teams_data.keys()}")

        teams_list = teams_data.get('teams', []) or teams_data.get('items', [])
        page_count = teams_data.get('pageCount', 1)
        current_page = teams_data.get('pageIndex', 1)
        debug_log(f"SportsGrid: Page info - current: {current_page}, total: {page_count}")

        if page_count > 1:
            debug_log(f"SportsGrid: Fetching all {page_count} pages of teams")
            for page in range(2, page_count + 1):
                page_url = f"{teams_url}?page={page}"
                page_response = requests.get(page_url, headers=api_headers, timeout=15)
                if page_response.status_code == 200:
                    page_data = page_response.json()
                    page_teams = page_data.get('teams', []) or page_data.get('items', [])
                    if page_teams:
                        teams_list.extend(page_teams)

        debug_log(f"SportsGrid: Teams list length: {len(teams_list)}")
        if teams_list:
            debug_log(f"SportsGrid: First team item: {teams_list[0]}")

        sample = []
        for team in teams_list[:5]:
            if team:
                sample.append(team.get('displayName') or team.get('name') or str(team))
        debug_log(f"SportsGrid: Teams data sample: {sample}")

        team_id = None
        team_color = ''
        team_alt_color = ''
        team_name_clean = team_name.lower().replace(' ', '').replace('.', '').replace('-', '').replace("'", "")
        debug_log(f"SportsGrid: Looking for team: '{team_name}' (cleaned: '{team_name_clean}')")

        all_team_names = []

        for team in teams_list:
            if not team:
                continue
            team_ref = team.get('$ref', '')
            if not team_ref:
                continue
            match = re.search(r'/teams/(\d+)', team_ref)
            if not match:
                continue
            test_id = match.group(1)
            team_detail_response = requests.get(team_ref, headers=api_headers, timeout=10)
            if team_detail_response.status_code != 200:
                continue
            team_detail = team_detail_response.json()
            team_display_name = team_detail.get('displayName', '') or team_detail.get('name', '')
            team_abbrev = team_detail.get('abbreviation', '').lower()
            all_team_names.append(f"{team_display_name} ({team_abbrev})")

        for team in teams_list:
            if not team:
                continue
            team_ref = team.get('$ref', '')
            if not team_ref:
                continue
            match = re.search(r'/teams/(\d+)', team_ref)
            if not match:
                continue
            test_id = match.group(1)
            team_detail_response = requests.get(team_ref, headers=api_headers, timeout=10)
            if team_detail_response.status_code != 200:
                continue
            team_detail = team_detail_response.json()
            team_display_name = team_detail.get('displayName', '') or team_detail.get('name', '')
            team_location = (
                team_detail.get('location', {}).get('name', '').lower().replace(' ', '').replace('-', '')
                if isinstance(team_detail.get('location'), dict)
                else ''
            )
            team_abbrev = team_detail.get('abbreviation', '').lower()

            if not team_display_name:
                continue

            name2 = team_display_name.lower().replace(' ', '').replace('.', '').replace('-', '').replace("'", "")
            abbrev_match = team_abbrev == team_name_clean or team_abbrev in team_name_clean
            full_name_match = team_name_clean == name2

            location_nickname_match = False
            if team_location:
                team_nickname = (
                    team_display_name.lower()
                    .replace(team_location.title(), '')
                    .replace(' ', '')
                    .replace('-', '')
                    .replace("'", "")
                )
                location_nickname_match = team_location in team_name_clean and team_nickname in team_name_clean

            partial_match = False
            matched_words = 0
            if len(team_name_clean) >= 4:
                ignore_words = ['la', 'ny', 'gs', 'no', 'utah', 'san', 'antonio', 'los', 'angeles', 'new', 'orleans', 'golden', 'state', 'warriors']
                key_words = [w for w in [team_name_clean[i:i + 3] for i in range(len(team_name_clean) - 2)] if w not in ignore_words]
                matched_words = sum(1 for kw in key_words if kw in name2)
                if matched_words >= 2 and key_words:
                    partial_match = matched_words >= min(2, len(key_words))
            strong_partial = matched_words >= 3 if partial_match else False

            if full_name_match or location_nickname_match or abbrev_match or strong_partial:
                team_id = test_id
                team_color = team_detail.get('color', '')
                team_alt_color = team_detail.get('alternateColor', '')
                debug_log(f"SportsGrid: Matched team: {team_display_name} (abbrev: {team_abbrev}, location: {team_location}) with ID {team_id}, color: {team_color}")
                break

        if not team_id:
            debug_log(f"SportsGrid: All teams checked: {all_team_names}")
            debug_log(f"SportsGrid: Could not find team ID for {team_name}")
            return {}

        season_type = 2
        stats_url = f"https://sports.core.api.espn.com/v2/sports/{espn_sport}/leagues/{league}/seasons/{current_year}/types/{season_type}/teams/{team_id}/statistics"
        debug_log(f"SportsGrid: Fetching team stats from {stats_url}")

        stats_response = requests.get(stats_url, headers=api_headers, timeout=15)
        if stats_response.status_code != 200:
            debug_log(f"SportsGrid: Failed to get team stats, status {stats_response.status_code}")
            return {}

        stats_data = stats_response.json()
        debug_log(f"SportsGrid: Stats API response keys: {stats_data.keys()}")

        splits = stats_data.get('splits', {})
        categories = splits.get('categories', [])

        leaders = {}
        for category in categories:
            stats = category.get('stats', [])
            for stat in stats:
                stat_name = stat.get('name', '')
                display_value = stat.get('displayValue', '')
                short_name = stat.get('shortDisplayName', '')

                should_include = False
                if sport == 'nba':
                    should_include = stat_name in ['points', 'rebounds', 'assists', 'steals', 'blocks', 'turnovers', 'pace', 'pointDifferential']
                elif sport == 'nfl':
                    should_include = stat_name in ['pointsFor', 'pointsAgainst', 'pointDifferential', 'totalYards', 'passYards', 'rushYards']
                elif sport == 'mlb':
                    should_include = stat_name in ['runs', 'runsAllowed', 'runDifferential', 'homeRuns', 'era', 'whip']
                elif sport == 'ncaabase':
                    should_include = stat_name in ['runs', 'runsAllowed', 'runDifferential', 'homeRuns', 'era', 'whip']
                elif sport == 'nhl':
                    should_include = stat_name in ['goalsFor', 'goalsAgainst', 'goalDifferential', 'powerPlayPct', 'penaltyKillPct']
                elif sport in ['mls', 'premierleague', 'laliga', 'bundesliga', 'seriea', 'ligue1', 'championsleague']:
                    should_include = stat_name in ['goalsFor', 'goalsAgainst', 'goalDifferential', 'cleanSheets', 'possessionPct']

                if should_include and short_name:
                    rank_val = stat.get('rankDisplayValue', '')
                    if rank_val:
                        display = f"#{rank_val}"
                    else:
                        display = stat.get('perGameDisplayValue', '') or display_value
                    if display:
                        leaders[stat_name] = {'name': short_name, 'value': display}

        if leaders:
            debug_log(f"SportsGrid: Found season stats for {team_name}: {leaders}")

        debug_log(f"SportsGrid: Final season leaders result: {leaders}")

        player_leaders = get_team_player_leaders_fn(team_name, team_id, espn_sport, league)
        if player_leaders:
            leaders['player_leaders'] = player_leaders

        if team_color:
            team_name_key = team_name.lower().replace(' ', '').replace('.', '').replace('-', '').replace("'", "")
            override_color = team_color_overrides.get(team_name_key, '')
            if override_color:
                leaders['team_color'] = override_color
                debug_log(f"SportsGrid: Overriding team color for {team_name} from {team_color} to {override_color}")
            else:
                leaders['team_color'] = team_color
            leaders['team_alt_color'] = team_alt_color

        set_cached(team_name, 'season_leaders', leaders)
        return leaders
    except Exception as e:
        log_error(f"SportsGrid: Error in get_team_season_leaders: {str(e)}")
        return {}
