"""ESPN game model."""

# pylint: disable=too-many-arguments,duplicate-code
import datetime
import logging
from typing import Any, Dict

import pytest_is_running
from dateutil.parser import parse
from scrapesession.scrapesession import ScrapeSession  # type: ignore

from ...cache import MEMORY
from ..game_model import VERSION as GAME_VERSION
from ..game_model import GameModel, localize
from ..google.google_news_model import create_google_news_models
from ..league import League
from ..odds_model import OddsModel
from ..season_type import SeasonType
from ..team_model import VERSION as TEAM_VERSION
from ..team_model import TeamModel
from ..umpire_model import UmpireModel
from ..venue_model import VERSION as VENUE_VERSION
from ..venue_model import VenueModel
from ..x.x_social_model import create_x_social_model
from .espn_bookie_model import create_espn_bookie_model
from .espn_odds_model import MONEYLINE_KEY, create_espn_odds_model
from .espn_player_model import create_espn_player_model
from .espn_team_model import ID_KEY, create_espn_team_model
from .espn_umpire_model import create_espn_umpire_model
from .espn_venue_model import create_espn_venue_model


def _create_espn_team(
    competitor: Dict[str, Any],
    odds_dict: Dict[str, Any],
    session: ScrapeSession,
    dt: datetime.datetime,
    league: League,
    positions_validator: dict[str, str],
) -> TeamModel:
    if competitor["type"] == "athlete":
        player = create_espn_player_model(
            session=session,
            player=competitor,
            dt=dt,
            positions_validator=positions_validator,
        )
        if "winner" not in competitor:
            competitor_response = session.get(competitor["$ref"])
            competitor_response.raise_for_status()
            competitor.update(competitor_response.json())
        try:
            return TeamModel(
                identifier=player.identifier,
                name=player.name,
                location=None,
                players=[player],
                odds=[],
                points=int(competitor["winner"]),
                ladder_rank=None,
                news=create_google_news_models(player.name, session, dt, league),
                social=create_x_social_model(player.identifier, session, dt),
                field_goals=None,
                coaches=[],
                lbw=None,
                end_dt=None,
                runs=None,
                wickets=None,
                overs=None,
                balls=None,
                byes=None,
                leg_byes=None,
                wides=None,
                no_balls=None,
                penalties=None,
                balls_per_over=None,
                fours=None,
                sixes=None,
                catches=None,
                catches_dropped=None,
                tackles_inside_50=None,
                total_possessions=None,
                uncontested_marks=None,
                disposal_efficiency=None,
                centre_clearances=None,
                stoppage_clearances=None,
                goal_accuracy=None,
                rushed_behinds=None,
                touched_behinds=None,
                left_behinds=None,
                left_posters=None,
                right_behinds=None,
                right_posters=None,
                total_interchange_count=None,
                interchange_count_q1=None,
                interchange_count_q2=None,
                interchange_count_q3=None,
                interchange_count_q4=None,
                game_winning_goals=None,
                headed_goals=None,
                inaccurate_crosses=None,
                inaccurate_long_balls=None,
                inaccurate_passes=None,
                inaccurate_through_balls=None,
                left_footed_shots=None,
                longball_percentage=None,
                offsides=None,
                penalty_kick_goals=None,
                penalty_kick_percentage=None,
                penalty_kick_shots=None,
                penalty_kicks_missed=None,
                possession_percentage=None,
                possession_time=None,
                right_footed_shots=None,
                shoot_out_goals=None,
                shoot_out_misses=None,
                shoot_out_percentage=None,
                shot_assists=None,
                shot_percentage=None,
                shots_headed=None,
                shots_off_target=None,
                shots_on_post=None,
                shots_on_target=None,
                through_ball_percentage=None,
                total_crosses=None,
                total_goals=None,
                total_long_balls=None,
                total_passes=None,
                total_shots=None,
                total_through_balls=None,
                draws=None,
                sub_outs=None,
                suspensions=None,
                time_ended=None,
                time_started=None,
                win_percentage=None,
                wins=None,
                won_corners=None,
                yellow_cards=None,
                clean_sheet=None,
                crosses_caught=None,
                goals_conceded=None,
                partial_clean_sheet=None,
                penalty_kick_conceded=None,
                penalty_kick_save_percentage=None,
                penalty_kicks_faced=None,
                penalty_kicks_saved=None,
                punches=None,
                saves=None,
                shoot_out_kicks_faced=None,
                shoot_out_kicks_saved=None,
                shoot_out_save_percentage=None,
                shots_faced=None,
                smothers=None,
                unclaimed_crosses=None,
                accurate_crosses=None,
                accurate_long_balls=None,
                accurate_passes=None,
                accurate_through_balls=None,
                cross_percentage=None,
                free_kick_goals=None,
                free_kick_percentage=None,
                free_kick_shots=None,
                game_winning_assists=None,
                blocked_shots=None,
                effective_clearances=None,
                effective_tackles=None,
                ineffective_tackles=None,
                interceptions=None,
                tackle_percentage=None,
                appearances=None,
                average_rating_from_correspondent=None,
                average_rating_from_data_feed=None,
                average_rating_from_editor=None,
                average_rating_from_user=None,
                did_not_play=None,
                fouls_committed=None,
                fouls_suffered=None,
                goal_difference=None,
                losses=None,
                lost_corners=None,
                minutes=None,
                own_goals=None,
                pass_percentage=None,
                red_cards=None,
                starts=None,
                sub_ins=None,
                pitch_count=None,
                strikes=None,
                strike_pitch_ratio=None,
                games_played=None,
                team_games_played=None,
                double_plays=None,
                opportunities=None,
                errors=None,
                passed_balls=None,
                outfield_assists=None,
                pickoffs=None,
                putouts=None,
                outs_on_field=None,
                triple_plays=None,
                balls_in_zone=None,
                extra_bases=None,
                outs_made=None,
                catcher_third_innings_played=None,
                catcher_caught_stealing=None,
                catcher_stolen_bases_allowed=None,
                catcher_earned_runs=None,
                is_qualified_catcher=None,
                is_qualified_pitcher=None,
                successful_chances=None,
                total_chances=None,
                full_innings_played=None,
                part_innings_played=None,
                fielding_percentage=None,
                range_factor=None,
                zone_rating=None,
                catcher_caught_stealing_percentage=None,
                catcher_era=None,
                def_warbr=None,
                perfect_games=None,
                wild_pitches=None,
                third_innings=None,
                team_earned_runs=None,
                shutouts=None,
                pickoff_attempts=None,
                run_support=None,
                pitches_as_starter=None,
                quality_starts=None,
                inherited_runners=None,
                inherited_runners_scored=None,
                opponent_total_bases=None,
                is_qualified_saves=None,
                full_innings=None,
                part_innings=None,
                blown_saves=None,
                innings=None,
                era=None,
                whip=None,
                caught_stealing_percentage=None,
                pitches_per_start=None,
                pitches_per_inning=None,
                run_support_average=None,
                opponent_average=None,
                opponent_slug_average=None,
                opponent_on_base_percentage=None,
                opponent_ops=None,
                save_percentage=None,
                strikeouts_per_nine_innings=None,
                strikeout_to_walk_ratio=None,
                tough_losses=None,
                cheap_wins=None,
                save_opportunities_per_win=None,
                runs_created=None,
                batting_average=None,
                pinch_average=None,
                slug_average=None,
                secondary_average=None,
                on_base_percentage=None,
                ops=None,
                ground_to_fly_ratio=None,
                runs_created_per_27_outs=None,
                batter_rating=None,
                at_bats_per_home_run=None,
                stolen_base_percentage=None,
                pitches_per_plate_appearance=None,
                isolated_power=None,
                walk_to_strikeout_ratio=None,
                walks_per_plate_appearance=None,
                secondary_average_minus_batting_average=None,
                runs_produced=None,
                runs_ratio=None,
                patience_ratio=None,
                balls_in_play_average=None,
                mlb_rating=None,
                offensive_wins_above_replacement=None,
                wins_above_replacement=None,
                earned_runs=None,
                batters_hit=None,
                sacrifice_bunts=None,
                save_opportunities=None,
                finishes=None,
                balks=None,
                batters_faced=None,
                holds=None,
                complete_games=None,
                hit_by_pitch=None,
                ground_balls=None,
                strikeouts=None,
                rbis=None,
                sac_hits=None,
                hits=None,
                stolen_bases=None,
                walks=None,
                catcher_interference=None,
                gidps=None,
                sacrifice_flies=None,
                at_bats=None,
                home_runs=None,
                grand_slam_home_runs=None,
                runners_left_on_base=None,
                triples=None,
                game_winning_rbis=None,
                intentional_walks=None,
                doubles=None,
                fly_balls=None,
                caught_stealing=None,
                pitches=None,
                games_started=None,
                pinch_at_bats=None,
                pinch_hits=None,
                player_rating=None,
                is_qualified=None,
                is_qualified_steals=None,
                total_bases=None,
                plate_appearances=None,
                projected_home_runs=None,
                extra_base_hits=None,
                average_game_score=None,
                average_field_goals_attempted=None,
                average_three_point_field_goals_made=None,
                average_three_point_field_goals_attempted=None,
                average_free_throws_made=None,
                average_free_throws_attempted=None,
                average_points=None,
                average_offensive_rebounds=None,
                average_assists=None,
                average_turnovers=None,
                offensive_rebound_percentage=None,
                estimated_possessions=None,
                average_estimated_possessions=None,
                points_per_estimated_possessions=None,
                average_team_turnovers=None,
                average_total_turnovers=None,
                two_point_field_goals_made=None,
                two_point_field_goals_attempted=None,
                average_two_point_field_goals_made=None,
                average_two_point_field_goals_attempted=None,
                two_point_field_goal_percentage=None,
                shooting_efficiency=None,
                scoring_efficiency=None,
                average_48_field_goals_made=None,
                average_48_field_goals_attempted=None,
                average_48_three_point_field_goals_made=None,
                average_48_three_point_field_goals_attempted=None,
                average_48_free_throws_made=None,
                average_48_free_throws_attempted=None,
                average_48_points=None,
                average_48_offensive_rebounds=None,
                average_48_assists=None,
                average_48_turnovers=None,
                average_rebounds=None,
                average_fouls=None,
                average_flagrant_fouls=None,
                average_technical_fouls=None,
                average_ejections=None,
                average_disqualifications=None,
                assist_turnover_ratio=None,
                steal_foul_ratio=None,
                block_foul_ratio=None,
                average_team_rebounds=None,
                total_technical_fouls=None,
                team_assist_turnover_ratio=None,
                steal_turnover_ratio=None,
                average_48_rebounds=None,
                average_48_fouls=None,
                average_48_flagrant_fouls=None,
                average_48_technical_fouls=None,
                average_48_ejections=None,
                average_48_disqualifications=None,
                double_double=None,
                triple_double=None,
                field_goals_made=None,
                free_throws_made=None,
                three_point_percentage=None,
                three_point_field_goals_made=None,
                team_turnovers=None,
                total_turnovers=None,
                points_in_paint=None,
                brick_index=None,
                fast_break_points=None,
                average_field_goals_made=None,
                turnover_points=None,
                average_defensive_rebounds=None,
                average_blocks=None,
                average_steals=None,
                average_48_defensive_rebounds=None,
                average_48_blocks=None,
                average_48_steals=None,
                largest_lead=None,
                disqualifications=None,
                flagrant_fouls=None,
                fouls=None,
                ejections=None,
                technical_fouls=None,
                vorp=None,
                average_minutes=None,
                nba_rating=None,
                fourth_down_attempts=None,
                fourth_down_conversion_percentage=None,
                fourth_down_conversions=None,
                possession_time_seconds=None,
                redzone_attempt_points=None,
                redzone_attempts=None,
                redzone_conversions=None,
                redzone_efficiency_percentage=None,
                redzone_end_downs=None,
                redzone_end_game=None,
                redzone_end_half=None,
                redzone_field_goal_percentage=None,
                redzone_field_goal_points=None,
                redzone_field_goals=None,
                redzone_field_goals_missed=None,
                redzone_fumble=None,
                redzone_interception=None,
                redzone_scoring_percentage=None,
                redzone_total_points=None,
                redzone_touchdown_pass=None,
                redzone_touchdown_percentage=None,
                redzone_touchdown_points=None,
                redzone_touchdown_rush=None,
                redzone_touchdowns=None,
                third_down_attempts=None,
                third_down_conversion_percentage=None,
                third_down_conversions=None,
                timeouts_used=None,
                total_penalties=None,
                total_penalty_yards=None,
                total_plays=None,
                total_drives=None,
                turn_over_differential=None,
                punt_returns_started_inside_the_10=None,
                punt_returns_started_inside_the_20=None,
                punt_return_touchdowns=None,
                punt_return_yards=None,
                special_team_fumble_returns=None,
                special_team_fumble_return_yards=None,
                yards_per_kick_return=None,
                yards_per_punt_return=None,
                yards_per_return=None,
                average_punt_return_yards=None,
                gross_average_punt_yards=None,
                long_punt=None,
                net_average_punt_yards=None,
                punts=None,
                punts_blocked=None,
                punts_blocked_percentage=None,
                punts_inside_10=None,
                punts_inside_10_percentage=None,
                punts_inside_20=None,
                punts_inside_20_percentage=None,
                punts_over_50=None,
                punt_yards=None,
                defensive_points=None,
                kick_extra_points=None,
                kick_extra_points_made=None,
                misc_points=None,
                return_touchdowns=None,
                total_two_point_conversions=None,
                first_downs=None,
                first_downs_passing=None,
                first_downs_penalty=None,
                first_downs_per_game=None,
                first_downs_rushing=None,
                kickoff_return_yards=None,
                kickoffs=None,
                kickoff_yards=None,
                long_field_goal_attempt=None,
                long_field_goal_made=None,
                long_kickoff=None,
                total_kicking_points=None,
                touchback_percentage=None,
                touchbacks=None,
                def_fumble_returns=None,
                def_fumble_return_yards=None,
                fumble_recoveries=None,
                fumble_recovery_yards=None,
                kick_return_fair_catches=None,
                kick_return_fair_catch_percentage=None,
                kick_return_fumbles=None,
                kick_return_fumbles_lost=None,
                kick_returns=None,
                kick_return_touchdowns=None,
                kick_return_yards=None,
                long_kick_return=None,
                long_punt_return=None,
                misc_fumble_returns=None,
                misc_fumble_return_yards=None,
                opp_fumble_recoveries=None,
                opp_fumble_recovery_yards=None,
                opp_special_team_fumble_returns=None,
                opp_special_team_fumble_return_yards=None,
                punt_return_fair_catches=None,
                punt_return_fair_catch_percentage=None,
                punt_return_fumbles=None,
                punt_return_fumbles_lost=None,
                punt_returns=None,
                interception_yards=None,
                average_kickoff_return_yards=None,
                average_kickoff_yards=None,
                extra_point_attempts=None,
                extra_point_percentage=None,
                extra_points_blocked=None,
                extra_points_blocked_percentage=None,
                extra_points_made=None,
                fair_catches=None,
                fair_catch_percentage=None,
                field_goal_attempts=None,
                field_goal_attempts_1_19=None,
                field_goal_attempts_20_29=None,
                field_goal_attempts_30_39=None,
                field_goal_attempts_40_49=None,
                field_goal_attempts_50_59=None,
                field_goal_attempts_60_99=None,
                field_goal_attempts_50=None,
                field_goal_attempt_yards=None,
                field_goals_blocked=None,
                field_goals_blocked_percentage=None,
                field_goals_made_1_19=None,
                field_goals_made_20_29=None,
                field_goals_made_30_39=None,
                field_goals_made_40_49=None,
                field_goals_made_50_59=None,
                field_goals_made_60_99=None,
                field_goals_made_50=None,
                field_goals_made_yards=None,
                field_goals_missed_yards=None,
                kickoff_ob=None,
                kickoff_returns=None,
                kickoff_return_touchdowns=None,
                two_point_rec_conversions=None,
                two_point_reception=None,
                two_point_reception_attempts=None,
                yards_per_reception=None,
                assist_tackles=None,
                average_interception_yards=None,
                average_sack_yards=None,
                average_stuff_yards=None,
                blocked_field_goal_touchdowns=None,
                blocked_punt_touchdowns=None,
                defensive_touchdowns=None,
                hurries=None,
                kicks_blocked=None,
                long_interception=None,
                misc_touchdowns=None,
                passes_batted_down=None,
                passes_defended=None,
                qb_hits=None,
                two_point_returns=None,
                sacks_assisted=None,
                sacks_unassisted=None,
                sack_yards=None,
                safeties=None,
                solo_tackles=None,
                stuff_yards=None,
                tackles_for_loss=None,
                tackles_yards_lost=None,
                yards_allowed=None,
                points_allowed=None,
                one_point_safeties_made=None,
                missed_field_goal_return_td=None,
                blocked_punt_ez_rec_td=None,
                interception_touchdowns=None,
                yards_per_game=None,
                yards_per_pass_attempt=None,
                net_yards_per_pass_attempt=None,
                quarterback_rating=None,
                espn_rb_rating=None,
                long_rushing=None,
                rushing_attempts=None,
                rushing_big_plays=None,
                rushing_first_downs=None,
                rushing_fumbles=None,
                rushing_fumbles_lost=None,
                rushing_touchdowns=None,
                rushing_yards=None,
                rushing_yards_per_game=None,
                stuffs=None,
                stuff_yards_lost=None,
                two_point_rush_conversions=None,
                two_point_rush=None,
                two_point_rush_attempts=None,
                yards_per_rush_attempt=None,
                espn_wr_rating=None,
                long_reception=None,
                receiving_big_plays=None,
                receiving_first_downs=None,
                receiving_fumbles=None,
                receiving_fumbles_lost=None,
                receiving_targets=None,
                receiving_touchdowns=None,
                receiving_yards=None,
                receiving_yards_after_catch=None,
                receiving_yards_at_catch=None,
                receiving_yards_per_game=None,
                receptions=None,
                interception_percentage=None,
                long_passing=None,
                misc_yards=None,
                net_passing_yards=None,
                net_passing_yards_per_game=None,
                net_total_yards=None,
                net_yards_per_game=None,
                passing_attempts=None,
                passing_big_plays=None,
                passing_first_downs=None,
                passing_fumbles=None,
                passing_fumbles_lost=None,
                passing_touchdown_percentage=None,
                passing_touchdowns=None,
                passing_yards=None,
                passing_yards_after_catch=None,
                passing_yards_at_catch=None,
                passing_yards_per_game=None,
                qb_rating=None,
                sacks=None,
                sack_yards_lost=None,
                net_passing_attempts=None,
                total_offensive_plays=None,
                total_points=None,
                total_points_per_game=None,
                total_touchdowns=None,
                total_yards=None,
                total_yards_from_scrimmage=None,
                two_point_pass_convs=None,
                two_point_pass=None,
                two_point_pass_attempts=None,
                yards_from_scrimmage_per_game=None,
                yards_per_completion=None,
                fumbles=None,
                fumbles_lost=None,
                fumbles_forced=None,
                fumbles_recovered_yards=None,
                offensive_two_point_returns=None,
                offensive_fumbles_touchdowns=None,
                defensive_fumbles_touchdowns=None,
                average_gain=None,
                completion_percentage=None,
                completions=None,
                espn_qb_rating=None,
                power_play_time_on_ice=None,
                short_handed_time_on_ice=None,
                even_strength_time_on_ice=None,
                shifts=None,
                shot_differential=None,
                goal_differential=None,
                pim_differential=None,
                rating=None,
                ytd_goals=None,
                shots_in_first_period=None,
                shots_in_second_period=None,
                shots_in_third_period=None,
                shots_ot=None,
                shots_total=None,
                shots_missed=None,
                points_per_game=None,
                power_play_goals=None,
                power_play_assists=None,
                power_play_opportunities=None,
                power_play_percentage=None,
                short_handed_goals=None,
                short_handed_assists=None,
                shootout_attempts=None,
                shootout_shot_percentage=None,
                empty_net_goals_for=None,
                shooting_percentage=None,
                total_face_offs=None,
                faceoffs_won=None,
                faceoffs_lost=None,
                faceoff_percentage=None,
                unassisted_goals=None,
                giveaways=None,
                penalty_minutes=None,
                goals_against=None,
                shots_against=None,
                penalty_kill_percentage=None,
                power_play_goals_against=None,
                short_handed_goals_against=None,
                shootout_saves=None,
                shootout_shots_against=None,
                times_short_handed=None,
                empty_net_goals_against=None,
                takeaways=None,
                even_strength_saves=None,
                power_play_saves=None,
                short_handed_saves=None,
                time_on_ice=None,
                total_giveaways=None,
                total_takeaways=None,
                fantasy_rating=None,
                second_chance_points=None,
                plus_minus=None,
                set_one_points=None,
                set_two_points=None,
                set_three_points=None,
                set_four_points=None,
                set_five_points=None,
                version=TEAM_VERSION,
            )
        except KeyError as exc:
            logging.error(competitor)
            logging.error(str(exc))

    team_dict = competitor
    if "team" in competitor:
        team_response = session.get(competitor["team"]["$ref"])
        team_response.raise_for_status()
        team_dict = team_response.json()
        team_dict.update(competitor)

    odds: list[OddsModel] = []
    if odds_dict:
        if "homeAway" in competitor:
            odds_key = competitor["homeAway"] + "TeamOdds"
            odds = [  # pyright: ignore
                create_espn_odds_model(
                    x[odds_key],
                    create_espn_bookie_model(x["provider"]),
                )
                for x in odds_dict["items"]
                if odds_key in x and MONEYLINE_KEY in x[odds_key]
            ]

    roster_dict = {}
    if "roster" in competitor:
        roster_response = session.get(competitor["roster"]["$ref"])
        roster_response.raise_for_status()
        roster_dict = roster_response.json()

    score_dict = {}
    if "score" in competitor:
        score_response = session.get(competitor["score"]["$ref"])
        score_response.raise_for_status()
        score_dict = score_response.json()

    statistics_dict = {}
    if "statistics" in competitor:
        statistics_response = session.get(competitor["statistics"]["$ref"])
        statistics_response.raise_for_status()
        statistics_dict = statistics_response.json()

    return create_espn_team_model(
        session,
        team_dict,
        roster_dict,
        odds,
        score_dict,
        dt,
        league,
        positions_validator,
        statistics_dict=statistics_dict,
    )


def _create_venue(
    competition: dict[str, Any],
    session: ScrapeSession,
    dt: datetime.datetime,
    version: str,
) -> VenueModel | None:
    venue = None
    if "venue" in competition:
        venue = create_espn_venue_model(
            venue=competition["venue"], session=session, dt=dt, version=version
        )
    if venue is None and "venues" in competition:
        venues = competition["venues"]
        if venues:
            venue_url = competition["venues"][0]["$ref"]
            venue_response = session.get(venue_url)
            venue_response.raise_for_status()
            venue = create_espn_venue_model(
                venue=venue_response.json(), session=session, dt=dt, version=version
            )
    return venue  # pyright: ignore


def _create_teams(
    competition: dict[str, Any],
    session: ScrapeSession,
    venue: VenueModel | None,
    dt: datetime.datetime,
    league: League,
    positions_validator: dict[str, str],
) -> tuple[list[TeamModel], int | None, datetime.datetime | None, list[UmpireModel]]:
    # pylint: disable=too-many-locals
    teams = []
    attendance = None
    end_dt = None
    umpires = []
    odds_dict = {}
    if "odds" in competition:
        odds_response = session.get(competition["odds"]["$ref"])
        odds_response.raise_for_status()
        odds_dict = odds_response.json()

    for competitor in competition.get("competitors", []):
        if competitor[ID_KEY] in {"-1", "-2", "0"}:
            continue
        teams.append(
            _create_espn_team(
                competitor, odds_dict, session, dt, league, positions_validator
            )
        )
    attendance = competition.get("attendance")
    if "situation" in competition:
        situation_url = competition["situation"]["$ref"]
        situation_response = session.get(situation_url)
        situation_response.raise_for_status()
        situation = situation_response.json()
        if "lastPlay" in situation:
            last_play_response = session.get(situation["lastPlay"]["$ref"])
            last_play_response.raise_for_status()
            last_play = last_play_response.json()
            if "wallclock" in last_play:
                end_dt = parse(last_play["wallclock"])
    if venue is not None and end_dt is not None:
        end_dt = localize(venue, end_dt)

    if "officials" in competition:
        officials_response = session.get(competition["officials"]["$ref"])
        officials_response.raise_for_status()
        officials_dict = officials_response.json()
        for official in officials_dict["items"]:
            umpires.append(
                create_espn_umpire_model(session=session, url=official["$ref"], dt=dt)
            )

    return teams, attendance, end_dt, umpires


def _create_espn_game_model(
    competition: dict[str, Any],
    week: int | None,
    game_number: int,
    session: ScrapeSession,
    league: League,
    year: int | None,
    season_type: SeasonType | None,
    positions_validator: dict[str, str],
    version: str,
) -> GameModel:
    dt = parse(competition["date"])
    venue = _create_venue(competition, session, dt, VENUE_VERSION)
    if venue is not None:
        dt = localize(venue, dt)
    teams, attendance, end_dt, umpires = _create_teams(
        competition, session, venue, dt, league, positions_validator
    )
    if league == League.ATP or league == League.WTA:
        teams = sorted(teams, key=lambda x: x.name)
    return GameModel(
        dt=dt,
        week=week,
        game_number=game_number,
        venue=venue,
        teams=teams,
        end_dt=end_dt,
        attendance=attendance,
        league=str(league),
        year=year,
        season_type=season_type,
        postponed=None,
        play_off=None,
        distance=None,
        dividends=[],
        pot=None,
        umpires=umpires,
        best_of=None,
        version=version,
    )


@MEMORY.cache(ignore=["session"])
def _cached_create_espn_game_model(
    competition: dict[str, Any],
    week: int | None,
    game_number: int,
    session: ScrapeSession,
    league: League,
    year: int | None,
    season_type: SeasonType | None,
    positions_validator: dict[str, str],
    version: str,
) -> GameModel:
    return _create_espn_game_model(
        competition=competition,
        week=week,
        game_number=game_number,
        session=session,
        league=league,
        year=year,
        season_type=season_type,
        positions_validator=positions_validator,
        version=version,
    )


def create_espn_game_model(
    competition: dict[str, Any],
    week: int | None,
    game_number: int,
    session: ScrapeSession,
    league: League,
    year: int | None,
    season_type: SeasonType | None,
    positions_validator: dict[str, str],
) -> GameModel:
    """Creates an ESPN game model."""
    dt = parse(competition["date"])
    if (
        not pytest_is_running.is_running()
        and dt.date() < datetime.datetime.now().date() - datetime.timedelta(days=7)
    ):
        return _cached_create_espn_game_model(
            competition=competition,
            week=week,
            game_number=game_number,
            session=session,
            league=league,
            year=year,
            season_type=season_type,
            positions_validator=positions_validator,
            version=GAME_VERSION,
        )
    with session.cache_disabled():
        return _create_espn_game_model(
            competition=competition,
            week=week,
            game_number=game_number,
            session=session,
            league=league,
            year=year,
            season_type=season_type,
            positions_validator=positions_validator,
            version=GAME_VERSION,
        )
