"""
Cache-chokepoint mot GolfAPI.io (ADR-064). ALL import-kode (org-scopet
`course` OG global `personal_course`) MÅ gå via get_or_fetch_golfapi_course()
her -- ALDRI kalle golfapi_client direkte fra en import-endepunkt. Sjekker
`golfapi_course`-cachen FØRST, kaller GolfAPI (course + coordinates, 2 kall)
KUN hvis banen mangler -- kritisk for det begrensede kall-budsjettet
(GolfAPIs avtale tillater eksplisitt permanent caching av hentet banedata,
"no need to call the API to fetch the same course multiple times").

Ren DB-glue rundt den transportlag-rene golfapi_client.py -- samme
ansvarsdeling som courses.py allerede har rundt teeoff_client.py.
"""

from . import golfapi_client

# GolfAPIs rå tallkoder -> TeeCups lesbare tekst-enum (golfapi_course_coordinate.poi_type).
_POI_TYPE_BY_CODE = {
    1: "green", 2: "green_bunker", 3: "fairway_bunker", 4: "water",
    5: "trees", 6: "marker_100", 7: "marker_150", 8: "marker_200",
    9: "dogleg", 10: "road", 11: "tee_front", 12: "tee_back",
}
_LOCATION_BY_CODE = {1: "front", 2: "middle", 3: "back"}
_SIDE_FW_BY_CODE = {1: "left", 2: "center", 3: "right"}


async def get_or_fetch_golfapi_course(conn, golfapi_course_id: str) -> None:
    """Idempotent -- no-op (0 API-kall) hvis banen allerede er cachet fra
    en TIDLIGERE import, uansett hvilken organisasjon/bruker som gjorde den."""
    already_cached = await conn.fetchval("SELECT 1 FROM golfapi_course WHERE course_id = $1", golfapi_course_id)
    if already_cached:
        return

    course = await golfapi_client.get_course(golfapi_course_id)
    coordinates = await golfapi_client.get_coordinates(golfapi_course_id)
    num_holes = int(course["numHoles"])

    async with conn.transaction():
        await conn.execute(
            """
            INSERT INTO golfapi_course
                (course_id, club_id, club_name, course_name, city, country,
                 num_holes, has_gps, num_coordinates, golfapi_updated_at)
            VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, to_timestamp($10))
            """,
            golfapi_course_id,
            course["clubID"],
            course["clubName"],
            course.get("courseName") or "Bane",
            course.get("city"),
            course.get("country"),
            num_holes,
            bool(int(course.get("hasGPS") or 0)),
            len(coordinates),
            int(course["timestampUpdated"]) if course.get("timestampUpdated") else None,
        )

        pars_men = course["parsMen"]
        indexes_men = course["indexesMen"]
        pars_women = course.get("parsWomen") or [None] * num_holes
        indexes_women = course.get("indexesWomen") or [None] * num_holes
        for i in range(num_holes):
            await conn.execute(
                """
                INSERT INTO golfapi_course_hole
                    (golfapi_course_id, hole_number, par_men, index_men, par_women, index_women)
                VALUES ($1, $2, $3, $4, $5, $6)
                """,
                golfapi_course_id, i + 1, pars_men[i], indexes_men[i], pars_women[i], indexes_women[i],
            )

        for t in course.get("tees", []):
            lengths = [t.get(f"length{n}") for n in range(1, num_holes + 1)]
            # Reelt funn (Larvik/Nesbyen, 2026-08-13): GolfAPI returnerer
            # tomme STRENGER ("") for manglende rating-felt på enkelte
            # baner -- IKKE bare for kvinner (opprinnelig antakelse, speilet
            # fra ADR-019s teeoff-import), Nesbyen manglet `slopeMen` også.
            # `.get(...) is not None` alene lot int()/numeric-kolonnene
            # krasje på disse. Normaliser "" -> None FØR bruk, for BEGGE
            # kjønn (migrasjon 068 gjorde course_rating_men/slope_men
            # nullable av samme grunn -- kolonnene tåler nå det cachen her
            # faktisk kan produsere).
            def _num(key: str):
                v = t.get(key)
                return None if v is None or v == "" else v

            slope_men = _num("slopeMen")
            slope_women = _num("slopeWomen")
            await conn.execute(
                """
                INSERT INTO golfapi_course_tee
                    (golfapi_course_id, golfapi_tee_id, name, color_hex, lengths_meters,
                     course_rating_men, slope_men, course_rating_women, slope_women,
                     course_rating_men_front9, course_rating_men_back9,
                     course_rating_women_front9, course_rating_women_back9)
                VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
                """,
                golfapi_course_id,
                t["teeID"],
                t.get("teeName") or "Tee",
                t.get("teeColor"),
                lengths,
                _num("courseRatingMen"),
                int(slope_men) if slope_men is not None else None,
                _num("courseRatingWomen"),
                int(slope_women) if slope_women is not None else None,
                _num("courseRatingMenFront9"),
                _num("courseRatingMenBack9"),
                _num("courseRatingWomenFront9"),
                _num("courseRatingWomenBack9"),
            )

        for c in coordinates:
            poi_type = _POI_TYPE_BY_CODE.get(int(c["poi"]))
            if poi_type is None:
                continue  # ukjent/fremtidig GolfAPI-POI-kode -- hopp over, ikke feil hele importen
            await conn.execute(
                """
                INSERT INTO golfapi_course_coordinate
                    (golfapi_course_id, hole_number, poi_type, location, side_fairway, latitude, longitude)
                VALUES ($1, $2, $3, $4, $5, $6, $7)
                """,
                golfapi_course_id,
                int(c["hole"]),
                poi_type,
                _LOCATION_BY_CODE.get(int(c["location"])) if c.get("location") is not None else None,
                _SIDE_FW_BY_CODE.get(int(c["sideFW"])) if c.get("sideFW") is not None else None,
                c["latitude"],
                c["longitude"],
            )
