from fastapi import APIRouter, Depends, HTTPException, status from sqlmodel import Session, select from typing import List from datetime import datetime, timedelta from app.core.database import get_session from app.models.telemetry import Telemetry, TelemetryCreate, VehicleStatus from app.models.user import User from app.api.deps import get_current_user router = APIRouter(prefix="/api/telemetry", tags=["telemetry"]) @router.post("", response_model=Telemetry) async def create_telemetry_record( *, session: Session = Depends(get_session), telemetry_in: TelemetryCreate, current_user: User = Depends(get_current_user) ): """ Create a new telemetry record for the current driver. """ if current_user.role != "driver": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Only drivers can send telemetry data" ) db_telemetry = Telemetry( user_id=current_user.id, latitude=telemetry_in.latitude, longitude=telemetry_in.longitude, speed=telemetry_in.speed, heading=telemetry_in.heading, status=telemetry_in.status ) session.add(db_telemetry) session.commit() session.refresh(db_telemetry) return db_telemetry @router.get("/active", response_model=List[dict]) async def get_active_units( *, session: Session = Depends(get_session) ): """ Get the latest location of all active units (last 5 minutes). """ # Subquery to get the latest timestamp per user five_minutes_ago = datetime.utcnow() - timedelta(minutes=5) # This is a bit complex in SQLModel/SQLAlchemy for "latest record per group" # We'll use a simpler approach: get all records from last 5 mins and filter in python # or use a more efficient distinct on if supported. statement = ( select(Telemetry) .where(Telemetry.timestamp >= five_minutes_ago) .where(Telemetry.status == VehicleStatus.ACTIVE) .order_by(Telemetry.user_id, Telemetry.timestamp.desc()) ) results = session.exec(statement).all() # Filter to get only the latest unique user_id latest_units = {} for t in results: if t.user_id not in latest_units: # We also want the driver name and vehicle info user = session.get(User, t.user_id) latest_units[t.user_id] = { "user_id": t.user_id, "full_name": user.full_name if user else "Unknown", "latitude": t.latitude, "longitude": t.longitude, "speed": t.speed, "heading": t.heading, "timestamp": t.timestamp, "vehicle_type": user.driver_profile.vehicle_type if user and user.driver_profile else "unknown", "license_plate": user.driver_profile.license_plate if user and user.driver_profile else "unknown" } return list(latest_units.values())