"""Historical domain models for persisted CRCON scoreboard data."""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime


@dataclass(frozen=True, slots=True)
class HistoricalServerDefinition:
    """Stable identity for one historical CRCON source."""

    slug: str
    display_name: str
    scoreboard_base_url: str
    server_number: int | None
    source_kind: str = "crcon-scoreboard-json"


@dataclass(frozen=True, slots=True)
class HistoricalMapRecord:
    """Normalized map metadata reused across historical matches."""

    external_map_id: str | None
    map_name: str | None
    pretty_name: str | None
    game_mode: str | None
    image_name: str | None


@dataclass(frozen=True, slots=True)
class HistoricalMatchRecord:
    """Normalized match identity and summary."""

    external_match_id: str
    server_slug: str
    created_at: datetime | None
    started_at: datetime | None
    ended_at: datetime | None
    map_name: str | None
    map_pretty_name: str | None
    map_external_id: str | None
    game_mode: str | None
    image_name: str | None
    allied_score: int | None
    axis_score: int | None


@dataclass(frozen=True, slots=True)
class HistoricalPlayerIdentity:
    """Stable player identity across historical match stats."""

    stable_player_key: str
    display_name: str
    steam_id: str | None
    source_player_id: str | None


@dataclass(frozen=True, slots=True)
class HistoricalPlayerMatchStats:
    """Metrics persisted per player and match."""

    stable_player_key: str
    match_player_ref: str | None
    team_side: str | None
    level: int | None
    kills: int | None
    deaths: int | None
    teamkills: int | None
    time_seconds: int | None
    kills_per_minute: float | None
    deaths_per_minute: float | None
    kill_death_ratio: float | None
    combat: int | None
    offense: int | None
    defense: int | None
    support: int | None


@dataclass(frozen=True, slots=True)
class HistoricalIngestionRunSummary:
    """Outcome metadata recorded for one ingestion execution."""

    mode: str
    started_at: datetime
    completed_at: datetime | None
    status: str
    pages_processed: int
    matches_seen: int
    matches_inserted: int
    matches_updated: int
    player_rows_inserted: int
    player_rows_updated: int


@dataclass(frozen=True, slots=True)
class HistoricalBackfillProgressSummary:
    """Persisted resume checkpoint and last attempt metadata per server."""

    server_slug: str
    mode: str
    next_page: int
    last_completed_page: int | None
    discovered_total_matches: int | None
    discovered_total_pages: int | None
    archive_exhausted: bool
    last_run_id: int | None
    last_run_status: str | None
    last_run_started_at: datetime | None
    last_run_completed_at: datetime | None
    last_error: str | None


@dataclass(frozen=True, slots=True)
class HistoricalSnapshotRecord:
    """Persisted precomputed historical snapshot ready for lightweight reads."""

    server_key: str
    snapshot_type: str
    metric: str | None
    window: str | None
    payload_json: str
    generated_at: datetime
    source_range_start: datetime | None
    source_range_end: datetime | None
    is_stale: bool
