"""
Utgående, lesende HTTP-klient mot GolfAPI.io (ADR-064) -- tredje banekilde
for baner utenfor TeeOffs dekning (f.eks. Tjøme Golfklubb, bekreftet IKKE
i TeeOff 2026-08-12). Ren HTTP-modul -- ingen db/RLS-avhengighet, samme
isolasjonsprinsipp som teeoff_client.py/handicap_engine.py.

ULIKT teeoff: GolfAPI-kall koster ekte, begrenset budsjett (kjøpt 20 kall,
~2/bane -- 1 for /courses/{id}, 1 for /coordinates/{id}, søk koster 0.1).
Denne modulen gjør RÅ HTTP-kall og returnerer JSON uendret -- selve
cache-sjekken ("har vi denne banen fra før?") ligger i
_get_or_fetch_golfapi_course() i courses.py, IKKE her, slik at denne
modulen forblir en ren, testbar transportlag uten db-avhengighet.

Alltid measureUnit=m i kallene -- unngår yard/meter-fellen research
advarte om (internasjonale kilder returnerer ofte yards som standard).
"""

import httpx

from .config import settings

_BASE_URL = "https://golfapi.io/api/v2.3"
_TIMEOUT = httpx.Timeout(10.0, connect=5.0)


class GolfApiNotConfiguredError(Exception):
    """TEECUP_GOLFAPI_TOKEN er ikke satt i .env."""


class GolfApiUnavailableError(Exception):
    """GolfAPI svarte ikke (nede, timeout, uventet statuskode)."""


class GolfApiNotFoundError(Exception):
    """Banen/klubben finnes ikke hos GolfAPI (404)."""


def _headers() -> dict[str, str]:
    if not settings.GOLFAPI_TOKEN:
        raise GolfApiNotConfiguredError()
    return {"Authorization": f"Bearer {settings.GOLFAPI_TOKEN}"}


async def search_clubs(name: str | None = None, city: str | None = None, country: str | None = None) -> list[dict]:
    """Koster 0.1 API-kall. Returnerer rå `clubs`-array (hver med `courses[]`)."""
    params = {k: v for k, v in {"name": name, "city": city, "country": country}.items() if v}
    try:
        async with httpx.AsyncClient(timeout=_TIMEOUT) as client:
            res = await client.get(f"{_BASE_URL}/clubs", params=params, headers=_headers())
    except httpx.HTTPError as e:
        raise GolfApiUnavailableError(str(e)) from e
    if res.status_code != 200:
        raise GolfApiUnavailableError(f"uventet status {res.status_code}")
    return res.json().get("clubs", [])


async def get_course(course_id: str) -> dict:
    """Koster 1 API-kall. Full scorekortdata: par/SI per hull, alle tees
    med per-hull-lengde (meter) og rating/slope."""
    try:
        async with httpx.AsyncClient(timeout=_TIMEOUT) as client:
            res = await client.get(f"{_BASE_URL}/courses/{course_id}", params={"measureUnit": "m"}, headers=_headers())
    except httpx.HTTPError as e:
        raise GolfApiUnavailableError(str(e)) from e
    if res.status_code == 404:
        raise GolfApiNotFoundError(course_id)
    if res.status_code != 200:
        raise GolfApiUnavailableError(f"uventet status {res.status_code}")
    return res.json()


async def get_coordinates(course_id: str) -> list[dict]:
    """Koster 1 API-kall. Rå `coordinates`-array (poi/location/sideFW/hole/
    latitude/longitude, rå GolfAPI-tallkoder -- oversettes til TeeCups
    tekst-enum i courses.py, ikke her)."""
    try:
        async with httpx.AsyncClient(timeout=_TIMEOUT) as client:
            res = await client.get(f"{_BASE_URL}/coordinates/{course_id}", headers=_headers())
    except httpx.HTTPError as e:
        raise GolfApiUnavailableError(str(e)) from e
    if res.status_code == 404:
        raise GolfApiNotFoundError(course_id)
    if res.status_code != 200:
        raise GolfApiUnavailableError(f"uventet status {res.status_code}")
    return res.json().get("coordinates", [])
