"""
Yoro API views (plain Django — no DRF dependency).
"""

from __future__ import annotations

from django.http import JsonResponse
from django.views.decorators.http import require_GET

from yoro import codec
from yoro.constants import DOMAINS


@require_GET
def encode_view(request):
    """Encode lat/lon to Altius Code.

    ``GET /api/v1/yoro/encode/?lat=6.8&lon=-5.3&domain=CI&precision=12``
    """
    try:
        lat = float(request.GET["lat"])
        lon = float(request.GET["lon"])
    except (KeyError, ValueError, TypeError):
        return JsonResponse({"error": "lat and lon are required"}, status=400)

    domain = codec.domain_for_country(request.GET.get("domain", "CI"))
    precision = int(request.GET.get("precision", 12))

    code_str = codec.encode(lat, lon, precision=precision, domain=domain)
    decoded = codec.decode(code_str)
    resolution_m = codec.resolution(decoded["precision"], domain=domain)

    return JsonResponse({
        "code": code_str,
        "lat": decoded["lat"],
        "lon": decoded["lon"],
        "precision": decoded["precision"],
        "resolution_m": resolution_m,
        "bounds": decoded["bounds"],
    })


@require_GET
def decode_view(request):
    """Decode an Altius Code to coordinates and cell bounds.

    ``GET /api/v1/yoro/decode/?code=CI-4H7A3B``
    """
    code_str = request.GET.get("code", "")
    if not code_str or "-" not in code_str:
        return JsonResponse(
            {"error": "code parameter required (format: XX-XXXXX)"}, status=400
        )

    try:
        decoded = codec.decode(code_str)
    except ValueError as e:
        return JsonResponse({"error": str(e)}, status=400)

    resolution_m = codec.resolution(decoded["precision"], domain=decoded["domain"])
    nbrs = codec.neighbors(code_str)

    return JsonResponse({
        "code": code_str.upper(),
        "lat": decoded["lat"],
        "lon": decoded["lon"],
        "precision": decoded["precision"],
        "domain": decoded["domain"],
        "resolution_m": resolution_m,
        "bounds": decoded["bounds"],
        "neighbors": nbrs,
    })


@require_GET
def precisions_view(request):
    """List canonical precision levels for a domain.

    ``GET /api/v1/yoro/precisions/?domain=CI&max_length=10``
    """
    domain = codec.domain_for_country(request.GET.get("domain", "CI"))
    max_length = int(request.GET.get("max_length", 10))

    try:
        levels = codec.precision_levels(domain=domain, max_code_length=max_length)
    except ValueError as e:
        return JsonResponse({"error": str(e)}, status=400)

    return JsonResponse({"domain": domain, "levels": levels})


@require_GET
def domains_view(request):
    """List all available Yoro domains.

    ``GET /api/v1/yoro/domains/``
    """
    result = {}
    for key, dom in DOMAINS.items():
        result[key] = {
            "name": dom["name"],
            "bounds": {
                "lat_min": dom["lat_min"],
                "lat_max": dom["lat_max"],
                "lon_min": dom["lon_min"],
                "lon_max": dom["lon_max"],
            },
        }
    return JsonResponse({"domains": result})
