from math import asin, cos, radians, sin, sqrt

from core.config import settings


def haversine_km(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
    r = 6371.0
    dlat = radians(lat2 - lat1)
    dlon = radians(lon2 - lon1)
    a = sin(dlat / 2) ** 2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2) ** 2
    return 2 * r * asin(sqrt(a))


def compute_route_deviation(trace: list[tuple[float, float]], route: list[tuple[float, float]]) -> dict:
    if not trace or not route:
        return {
            "distance_from_route_km": 0.0,
            "off_route_points": 0,
            "off_route_duration_minutes": 0.0,
            "unexpected_stop_minutes": 0.0,
        }

    threshold = settings.route_deviation_km_threshold
    off_route_points = 0
    max_min_dist = 0.0
    for lat, lon in trace:
        nearest = min(haversine_km(lat, lon, rlat, rlon) for rlat, rlon in route)
        max_min_dist = max(max_min_dist, nearest)
        if nearest > threshold:
            off_route_points += 1

    off_route_duration = float(off_route_points) * 1.0
    unexpected_stop = max(0.0, off_route_duration - 5.0)

    return {
        "distance_from_route_km": round(max_min_dist, 5),
        "off_route_points": off_route_points,
        "off_route_duration_minutes": round(off_route_duration, 2),
        "unexpected_stop_minutes": round(unexpected_stop, 2),
    }
