"""Reverse geocoding usando Nominatim (OpenStreetMap)."""

import json
import urllib.request
import urllib.parse


def nominatim_reverse_geocode(lat: float, lon: float, lang: str = "es") -> dict:
    """Convierte coordenadas lat/lon a una dirección estructurada usando Nominatim.

    Args:
        lat: Latitud en grados decimales.
        lon: Longitud en grados decimales.
        lang: Código de idioma para la respuesta (ISO 639-1). Por defecto "es".

    Returns:
        Diccionario con campos normalizados de la dirección.

    Raises:
        RuntimeError: Si la petición HTTP falla o el servidor retorna error.
    """
    params = urllib.parse.urlencode({
        "format": "jsonv2",
        "lat": str(lat),
        "lon": str(lon),
        "accept-language": lang,
        "zoom": "18",
    })
    url = f"https://nominatim.openstreetmap.org/reverse?{params}"

    req = urllib.request.Request(
        url,
        headers={"User-Agent": "fn_registry/1.0"},
    )

    try:
        with urllib.request.urlopen(req, timeout=5) as resp:
            if resp.status != 200:
                raise RuntimeError(
                    f"nominatim_reverse_geocode: HTTP {resp.status} para lat={lat}, lon={lon}"
                )
            data = json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        raise RuntimeError(
            f"nominatim_reverse_geocode: HTTP {e.code} para lat={lat}, lon={lon}"
        ) from e
    except urllib.error.URLError as e:
        raise RuntimeError(
            f"nominatim_reverse_geocode: error de red — {e.reason}"
        ) from e

    address = data.get("address", {})

    city = (
        address.get("city")
        or address.get("town")
        or address.get("village")
        or ""
    )

    return {
        "display_name": data.get("display_name", ""),
        "street": address.get("road", ""),
        "house_number": address.get("house_number", ""),
        "neighbourhood": address.get("neighbourhood", ""),
        "city": city,
        "state": address.get("state", ""),
        "country": address.get("country", ""),
        "postcode": address.get("postcode", ""),
        "lat": float(data.get("lat", lat)),
        "lon": float(data.get("lon", lon)),
        "osm_type": data.get("osm_type", ""),
        "osm_id": int(data.get("osm_id", 0)),
    }
