from fastapi import APIRouter, Depends, HTTPException, status
from app.schemas.addresses import AddressCreate, AddressResponse
from app.core.deps import get_current_user, require_role
from app.core.supabase_client import supabase_admin
from app.services.simulation import get_colonias

router = APIRouter(prefix="/addresses", tags=["addresses"])


def _resolve_route_id(colonia: str) -> str:
    """Deriva routeId desde colonias-rutas.json; lanza 404 si la colonia no existe."""
    mapping = get_colonias()
    match = next(
        (c for c in mapping if c.get("colonia", "").lower() == colonia.lower()), None
    )
    if not match:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Colonia '{colonia}' no encontrada. Usa GET /colonias para ver las opciones.",
        )
    return match["routeId"]


@router.post("", response_model=AddressResponse, status_code=status.HTTP_201_CREATED)
def create_address(
    body: AddressCreate,
    current_user: dict = Depends(require_role("citizen", "admin")),
):
    """Alta de domicilio. El routeId se deriva automáticamente de la colonia elegida."""
    route_id = _resolve_route_id(body.colonia)

    insert_data: dict = {
        "user_id": current_user["user_id"],
        "label": body.label,
        "calle": body.calle,
        "colonia": body.colonia,
        "route_id": route_id,
        "verified": False,
    }
    if body.lat is not None:
        insert_data["lat"] = body.lat
    if body.lng is not None:
        insert_data["lng"] = body.lng

    result = (
        supabase_admin.table("addresses")
        .insert(insert_data)
        .execute()
    )

    if not result.data:
        raise HTTPException(status_code=500, detail="No se pudo guardar el domicilio")

    return result.data[0]


@router.get("", response_model=list[AddressResponse])
def list_addresses(current_user: dict = Depends(get_current_user)):
    """
    Lista de domicilios.
    - Ciudadano: solo sus propios (filtro por user_id en código + RLS en BD).
    - Admin: todos los domicilios.
    """
    if current_user["role"] == "admin":
        result = supabase_admin.table("addresses").select("*").execute()
    else:
        result = (
            supabase_admin.table("addresses")
            .select("*")
            .eq("user_id", current_user["user_id"])
            .execute()
        )

    return result.data or []


@router.get("/{address_id}", response_model=AddressResponse)
def get_address(
    address_id: str,
    current_user: dict = Depends(get_current_user),
):
    """Detalle de un domicilio. El ciudadano solo puede ver los suyos."""
    result = (
        supabase_admin.table("addresses")
        .select("*")
        .eq("id", address_id)
        .maybe_single()
        .execute()
    )

    if not result.data:
        raise HTTPException(status_code=404, detail="Domicilio no encontrado")

    address = result.data
    if current_user["role"] != "admin" and address["user_id"] != current_user["user_id"]:
        raise HTTPException(status_code=403, detail="No tienes acceso a este domicilio")

    return address


@router.get("/{address_id}/unit")
def get_address_unit(
    address_id: str,
    current_user: dict = Depends(get_current_user),
):
    """
    Devuelve la unidad asignada al domicilio (a través de su ruta).
    Cadena: addresses.route_id → routes.truck_id → units.
    El ciudadano sólo puede consultar sus propios domicilios.
    """
    addr_res = (
        supabase_admin.table("addresses")
        .select("id, user_id, route_id")
        .eq("id", address_id)
        .maybe_single()
        .execute()
    )
    if not addr_res.data:
        raise HTTPException(status_code=404, detail="Domicilio no encontrado")

    address = addr_res.data
    if current_user["role"] != "admin" and address["user_id"] != current_user["user_id"]:
        raise HTTPException(status_code=403, detail="No tienes acceso a este domicilio")

    route_id = address.get("route_id")
    if not route_id:
        raise HTTPException(
            status_code=404,
            detail="El domicilio no tiene una ruta asociada",
        )

    route_res = (
        supabase_admin.table("routes")
        .select("id, truck_id")
        .eq("id", route_id)
        .maybe_single()
        .execute()
    )
    if not route_res.data or route_res.data.get("truck_id") is None:
        raise HTTPException(
            status_code=404,
            detail="La ruta asignada no tiene unidad activa",
        )

    truck_id = route_res.data["truck_id"]
    unit_res = (
        supabase_admin.table("units")
        .select("id, plate, status")
        .eq("id", truck_id)
        .maybe_single()
        .execute()
    )
    if not unit_res.data:
        raise HTTPException(status_code=404, detail="Unidad no encontrada")

    return unit_res.data
