"""Sub-agente: Estilo de vida náutico.

Fuentes: Overpass API (marinas, boat ramps, playas, acceso al agua).
"""

from __future__ import annotations

import math
import time
import requests
from data_fetchers.base import USER_AGENT

OVERPASS_URL = "https://overpass-api.de/api/interpreter"


def run(lat: float, lon: float, address: str) -> dict:
    result = {
        "marinas": [],
        "boat_ramps": [],
        "beaches": [],
        "nearest_marina": None,
        "nearest_beach": None,
        "nearest_boat_ramp": None,
        "ocean_access": False,
        "waterway_nearby": False,
        "sources": ["OpenStreetMap/Overpass"],
        "errors": [],
    }

    try:
        data = _overpass_nautical(lat, lon)
        result.update(data)
    except Exception as e:
        result["errors"].append(f"Overpass lifestyle: {e}")

    return result


def _overpass_nautical(lat: float, lon: float, radius_m: int = 16000) -> dict:
    """Consulta amenidades náuticas en radio de ~10 millas."""
    query = f"""
    [out:json][timeout:35];
    (
      node["leisure"="marina"](around:{radius_m},{lat},{lon});
      way["leisure"="marina"](around:{radius_m},{lat},{lon});
      node["leisure"="slipway"](around:{radius_m},{lat},{lon});
      way["leisure"="slipway"](around:{radius_m},{lat},{lon});
      node["natural"="beach"](around:{radius_m},{lat},{lon});
      way["natural"="beach"](around:{radius_m},{lat},{lon});
      node["waterway"="river"](around:3200,{lat},{lon});
      node["natural"="water"](around:3200,{lat},{lon});
      way["natural"="coastline"](around:8000,{lat},{lon});
    );
    out body center;
    """
    time.sleep(1)
    r = requests.post(OVERPASS_URL, data={"data": query},
                      headers={"User-Agent": USER_AGENT}, timeout=40)
    r.raise_for_status()
    elements = r.json().get("elements", [])

    marinas, boat_ramps, beaches = [], [], []
    waterway_nearby = False
    ocean_access = False

    for el in elements:
        tags = el.get("tags", {})
        name = tags.get("name", "Sin nombre")

        # Obtener coords
        if "center" in el:
            el_lat = el["center"]["lat"]
            el_lon = el["center"]["lon"]
        else:
            el_lat = el.get("lat", lat)
            el_lon = el.get("lon", lon)

        dist = _haversine(lat, lon, el_lat, el_lon)

        leisure = tags.get("leisure", "")
        natural = tags.get("natural", "")
        waterway = tags.get("waterway", "")

        if leisure == "marina":
            entry = {
                "name": name,
                "dist_miles": round(dist, 2),
                "fuel": tags.get("fuel", "unknown"),
                "pump_out": tags.get("pump_out", "unknown"),
                "depth": tags.get("maxdraught", tags.get("depth", "unknown")),
            }
            marinas.append(entry)
        elif leisure == "slipway":
            boat_ramps.append({"name": name, "dist_miles": round(dist, 2)})
        elif natural == "beach":
            beaches.append({"name": name, "dist_miles": round(dist, 2)})
        elif natural == "coastline":
            ocean_access = True
        elif waterway in ("river", "canal") or natural in ("water", "bay"):
            waterway_nearby = True

    marinas.sort(key=lambda x: x["dist_miles"])
    boat_ramps.sort(key=lambda x: x["dist_miles"])
    beaches.sort(key=lambda x: x["dist_miles"])

    return {
        "marinas": marinas[:10],
        "boat_ramps": boat_ramps[:10],
        "beaches": beaches[:10],
        "nearest_marina": marinas[0] if marinas else None,
        "nearest_beach": beaches[0] if beaches else None,
        "nearest_boat_ramp": boat_ramps[0] if boat_ramps else None,
        "ocean_access": ocean_access,
        "waterway_nearby": waterway_nearby,
    }


def _haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
    R = 3958.8
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = math.sin(dlat/2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon/2)**2
    return R * 2 * math.asin(math.sqrt(a))


def score(data: dict) -> int:
    """Score 0-100 para lifestyle náutico."""
    s = 30  # base

    nearest_marina = data.get("nearest_marina")
    if nearest_marina:
        d = nearest_marina["dist_miles"]
        if d <= 1:
            s += 30
        elif d <= 3:
            s += 20
        elif d <= 5:
            s += 12
        elif d <= 10:
            s += 6

    nearest_beach = data.get("nearest_beach")
    if nearest_beach:
        d = nearest_beach["dist_miles"]
        if d <= 1:
            s += 20
        elif d <= 3:
            s += 12
        elif d <= 5:
            s += 6

    if data.get("ocean_access"):
        s += 10
    if data.get("waterway_nearby"):
        s += 5

    boat_ramps = len(data.get("boat_ramps", []))
    s += min(10, boat_ramps * 2)

    return min(100, max(0, s))
