from fastapi import APIRouter, Depends, HTTPException from app.services import simulation from app.core.deps import get_current_user from app.core.supabase_client import supabase_admin router = APIRouter(tags=["eta"]) @router.get("/eta") def get_eta( address_id: str, current_user: dict = Depends(get_current_user), ): """ ETA para el ciudadano. - Recibe `address_id` (domicilio del usuario autenticado). - Valida que el domicilio pertenezca al usuario (túnel de privacidad). - Devuelve SOLO texto: nunca coordenadas ni routeId completo. """ result = ( supabase_admin.table("addresses") .select("route_id, user_id") .eq("id", address_id) .maybe_single() .execute() ) if not result.data: raise HTTPException(status_code=404, detail="Domicilio no encontrado") address = result.data # Túnel: ciudadano solo puede consultar sus propios domicilios 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") # HACKATHON FALLBACK: Deducir route_id desde la colonia si es nulo en BD if not route_id: col_res = supabase_admin.table("addresses").select("colonia").eq("id", address_id).maybe_single().execute() if col_res.data: col = col_res.data.get("colonia", "").lower() if "centro" in col: route_id = "RUTA-01" elif "arboledas" in col: route_id = "RUTA-03" elif "juanico" in col: route_id = "RUTA-04" elif "olivos" in col: route_id = "RUTA-05" elif "seco" in col: route_id = "RUTA-12" elif "insurgentes" in col: route_id = "RUTA-13" if not route_id: raise HTTPException(status_code=404, detail="Ruta no asignada") # ── VALIDACIÓN EN VIVO: Revisar si la unidad física se descompuso ── try: route_res = supabase_admin.table("routes").select("truck_id, status").eq("id", route_id).maybe_single().execute() if route_res.data: truck_id = route_res.data.get("truck_id") db_status = route_res.data.get("status") # HACKATHON: Si la RUTA-01 no tiene camión asignado (o la tabla rutas está vacía), forzamos verificación con unidad 101 if not truck_id and route_id == "RUTA-01": truck_id = 101 if truck_id: unit_res = supabase_admin.table("units").select("status").eq("id", truck_id).maybe_single().execute() if unit_res.data and unit_res.data.get("status") in ["inactive", "maintenance"]: if route_id == "RUTA-01": return { "mensaje": "El camión de tu ruta ha presentado una falla. El servicio matutino se suspende y se retomará en la tarde.", "status": "diferida" } else: return { "mensaje": "El camión de tu ruta fue enviado a taller o inhabilitado. El servicio podría sufrir retrasos.", "status": "diferida" } if db_status in ["diferida", "reasignada"]: return { "mensaje": "Tu recolección ha sido reasignada a otra unidad. El servicio se reanudará en breve.", "status": db_status } except Exception as e: print(f"Error al validar estado de unidad en ETA: {e}") pos = simulation.get_route_position(route_id) status = simulation.get_route_status(route_id) if pos is None: raise HTTPException(status_code=503, detail="Simulación no disponible") if pos < 4: mensaje = "El camión va en camino a tu sector" elif pos == 4: mensaje = "Llega en aproximadamente 15 minutos — saca tus bolsas" elif pos < 8: mensaje = "Está atendiendo tu zona; prepara tus bolsas" else: mensaje = "Servicio del día finalizado. Mañana continuamos" # ⚠️ Nunca devolver coordenadas ni el routeId al ciudadano return {"mensaje": mensaje, "status": status}