from dataclasses import dataclass

import httpx

from bot.core.logger import logger

STEAM64_OFFSET = 76561197960265728
OPENDOTA_BASE = "https://api.opendota.com/api"


def parse_steam_id(raw: str) -> int:
    """Accept Steam32 or Steam64, return Steam32. Raises ValueError on bad input."""
    try:
        value = int(raw.strip())
    except ValueError:
        raise ValueError(f"Invalid Steam ID: {raw!r}")
    if value <= 0:
        raise ValueError("Steam ID must be a positive number")
    if value > STEAM64_OFFSET:
        value = value - STEAM64_OFFSET
    if value <= 0 or value > 0xFFFFFFFF:
        raise ValueError(f"Steam ID {raw!r} is out of valid range")
    return value


@dataclass
class RecentMatch:
    match_id: int
    start_time: int
    hero_id: int
    kills: int
    deaths: int
    assists: int


class OpenDotaClient:
    def __init__(self) -> None:
        self._client = httpx.AsyncClient(
            base_url=OPENDOTA_BASE,
            timeout=10.0,
            headers={"Accept": "application/json"},
        )

    async def get_recent_matches(self, steam32: int) -> list[RecentMatch]:
        try:
            resp = await self._client.get(f"/players/{steam32}/recentMatches")
            resp.raise_for_status()
            return [
                RecentMatch(
                    match_id=m["match_id"],
                    start_time=m.get("start_time", 0),
                    hero_id=m.get("hero_id", 0),
                    kills=m.get("kills", 0),
                    deaths=m.get("deaths", 0),
                    assists=m.get("assists", 0),
                )
                for m in resp.json()
            ]
        except httpx.HTTPError as e:
            logger.warning("OpenDota request failed for steam32=%s: %s", steam32, e, exc_info=True)
            return []
        except Exception:
            logger.warning("Unexpected error fetching matches for steam32=%s", steam32, exc_info=True)
            return []

    async def close(self) -> None:
        await self._client.aclose()
