"""Pydantic models for the football-data.org API v4 responses."""

from __future__ import annotations

from datetime import date, datetime

from pydantic import AliasGenerator, BaseModel, ConfigDict
from pydantic.alias_generators import to_camel


class _Base(BaseModel):
    model_config = ConfigDict(
        populate_by_name=True,
        alias_generator=AliasGenerator(validation_alias=to_camel),
    )


# ── Area ──────────────────────────────────────────────────────────────────────


class Area(_Base):
    id: int
    name: str
    code: str | None = None
    flag: str | None = None
    parent_area_id: int | None = None
    parent_area: str | None = None


class ChildArea(_Base):
    id: int
    name: str
    country_code: str | None = None
    flag: str | None = None
    parent_area_id: int | None = None
    parent_area: str | None = None


class AreaResponse(_Base):
    id: int
    name: str
    code: str | None = None
    flag: str | None = None
    parent_area_id: int | None = None
    parent_area: str | None = None
    child_areas: list[ChildArea] = []


class AreaListResponse(_Base):
    count: int
    areas: list[Area]


# ── Season ────────────────────────────────────────────────────────────────────


class Winner(_Base):
    id: int | None = None
    name: str | None = None
    short_name: str | None = None
    tla: str | None = None
    crest: str | None = None


class Season(_Base):
    id: int
    start_date: date | None = None
    end_date: date | None = None
    current_matchday: int | None = None
    winner: Winner | None = None
    stages: list[str] | None = None


# ── Competition ───────────────────────────────────────────────────────────────


class Competition(_Base):
    id: int
    name: str
    code: str | None = None
    type: str | None = None
    emblem: str | None = None
    area: Area | None = None


class CompetitionResponse(_Base):
    id: int
    name: str
    code: str | None = None
    type: str | None = None
    emblem: str | None = None
    area: Area | None = None
    current_season: Season | None = None
    seasons: list[Season] = []
    last_updated: datetime | None = None


class CompetitionListResponse(_Base):
    count: int
    competitions: list[CompetitionResponse]


# ── Team ──────────────────────────────────────────────────────────────────────


class Contract(_Base):
    start: str | None = None
    until: str | None = None


class Player(_Base):
    id: int
    name: str | None = None
    first_name: str | None = None
    last_name: str | None = None
    position: str | None = None
    date_of_birth: str | None = None
    nationality: str | None = None
    shirt_number: int | None = None
    market_value: str | None = None
    contract: Contract | None = None


class Coach(_Base):
    id: int | None = None
    name: str | None = None
    first_name: str | None = None
    last_name: str | None = None
    date_of_birth: str | None = None
    nationality: str | None = None
    contract: Contract | None = None


class TeamResponse(_Base):
    id: int
    name: str
    short_name: str | None = None
    tla: str | None = None
    crest: str | None = None
    area: Area | None = None
    address: str | None = None
    website: str | None = None
    founded: int | None = None
    club_colors: str | None = None
    venue: str | None = None
    coach: Coach | None = None
    squad: list[Player] = []
    running_competitions: list[Competition] = []
    last_updated: datetime | None = None


class TeamListResponse(_Base):
    count: int
    competition: Competition | None = None
    season: Season | None = None
    teams: list[TeamResponse]


# ── Standing ──────────────────────────────────────────────────────────────────


class TableEntry(_Base):
    position: int
    team: TeamResponse | None = None
    played_games: int | None = None
    form: str | None = None
    won: int | None = None
    draw: int | None = None
    lost: int | None = None
    points: int | None = None
    goals_for: int | None = None
    goals_against: int | None = None
    goal_difference: int | None = None


class Standing(_Base):
    stage: str | None = None
    type: str | None = None
    group: str | None = None
    table: list[TableEntry] = []


class StandingsResponse(_Base):
    competition: Competition | None = None
    season: Season | None = None
    standings: list[Standing] = []


# ── Match ─────────────────────────────────────────────────────────────────────


class ScoreDetail(_Base):
    home: int | None = None
    away: int | None = None


class Score(_Base):
    winner: str | None = None
    duration: str | None = None
    full_time: ScoreDetail | None = None
    half_time: ScoreDetail | None = None


class MatchTeam(_Base):
    id: int | None = None
    name: str | None = None
    short_name: str | None = None
    tla: str | None = None
    crest: str | None = None


class Referee(_Base):
    id: int | None = None
    name: str | None = None
    type: str | None = None
    nationality: str | None = None


class Goal(_Base):
    minute: int | None = None
    injury_time: int | None = None
    type: str | None = None
    team: MatchTeam | None = None
    scorer: Player | None = None
    assist: Player | None = None
    score: ScoreDetail | None = None


class Match(_Base):
    id: int
    area: Area | None = None
    competition: Competition | None = None
    season: Season | None = None
    utc_date: datetime | None = None
    status: str | None = None
    minute: int | None = None
    injury_time: int | None = None
    attendance: int | None = None
    venue: str | None = None
    matchday: int | None = None
    stage: str | None = None
    group: str | None = None
    last_updated: datetime | None = None
    home_team: MatchTeam | None = None
    away_team: MatchTeam | None = None
    score: Score | None = None
    goals: list[Goal] = []
    referees: list[Referee] = []


class ResultSet(_Base):
    count: int | None = None
    competitions: str | None = None
    first: str | None = None
    last: str | None = None
    played: int | None = None
    wins: int | None = None
    draws: int | None = None
    losses: int | None = None


class MatchListResponse(_Base):
    count: int | None = None
    result_set: ResultSet | None = None
    competition: Competition | None = None
    matches: list[Match] = []


class Head2HeadResponse(_Base):
    aggregates: dict | None = None  # type: ignore[type-arg]
    matches: list[Match] = []


# ── Scorers ───────────────────────────────────────────────────────────────────


class Scorer(_Base):
    player: Player | None = None
    team: TeamResponse | None = None
    played_matches: int | None = None
    goals: int | None = None
    assists: int | None = None
    penalties: int | None = None


class ScorersResponse(_Base):
    count: int | None = None
    competition: Competition | None = None
    season: Season | None = None
    scorers: list[Scorer] = []


# ── Person ────────────────────────────────────────────────────────────────────


class PersonResponse(_Base):
    id: int
    name: str | None = None
    first_name: str | None = None
    last_name: str | None = None
    date_of_birth: str | None = None
    nationality: str | None = None
    position: str | None = None
    shirt_number: int | None = None
    current_team: TeamResponse | None = None
    last_updated: datetime | None = None
