from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, status, Request from sqlalchemy.orm import Session from datetime import date from app.api.deps import get_db, get_current_read_user, get_current_operator_user from app.crud.crud_local_flight import local_flight as crud_local_flight from app.schemas.local_flight import LocalFlight, LocalFlightCreate, LocalFlightUpdate, LocalFlightStatus, LocalFlightType, LocalFlightStatusUpdate from app.models.ppr import User from app.core.utils import get_client_ip router = APIRouter() @router.get("/", response_model=List[LocalFlight]) async def get_local_flights( request: Request, skip: int = 0, limit: int = 100, status: Optional[LocalFlightStatus] = None, flight_type: Optional[LocalFlightType] = None, date_from: Optional[date] = None, date_to: Optional[date] = None, db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get local flight records with optional filtering""" flights = crud_local_flight.get_multi( db, skip=skip, limit=limit, status=status, flight_type=flight_type, date_from=date_from, date_to=date_to ) return flights @router.post("/", response_model=LocalFlight) async def create_local_flight( request: Request, flight_in: LocalFlightCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Create a new local flight record (book out)""" flight = crud_local_flight.create(db, obj_in=flight_in, created_by=current_user.username) # Send real-time update via WebSocket if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "local_flight_booked_out", "data": { "id": flight.id, "registration": flight.registration, "flight_type": flight.flight_type.value, "status": flight.status.value } }) return flight @router.get("/{flight_id}", response_model=LocalFlight) async def get_local_flight( flight_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get a specific local flight record""" flight = crud_local_flight.get(db, flight_id=flight_id) if not flight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Local flight record not found" ) return flight @router.put("/{flight_id}", response_model=LocalFlight) async def update_local_flight( request: Request, flight_id: int, flight_in: LocalFlightUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update a local flight record""" db_flight = crud_local_flight.get(db, flight_id=flight_id) if not db_flight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Local flight record not found" ) # Get user IP from request user_ip = request.client.host if request.client else None flight = crud_local_flight.update( db, db_obj=db_flight, obj_in=flight_in, user=current_user.username, user_ip=user_ip ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "local_flight_updated", "data": { "id": flight.id, "registration": flight.registration, "status": flight.status.value } }) return flight @router.patch("/{flight_id}/status", response_model=LocalFlight) async def update_local_flight_status( request: Request, flight_id: int, status_update: LocalFlightStatusUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update local flight status (LANDED, CANCELLED, etc.)""" client_ip = get_client_ip(request) flight = crud_local_flight.update_status( db, flight_id=flight_id, status=status_update.status, timestamp=status_update.timestamp, user=current_user.username, user_ip=client_ip ) if not flight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Local flight record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "local_flight_status_update", "data": { "id": flight.id, "registration": flight.registration, "status": flight.status.value, "landed_dt": flight.landed_dt.isoformat() if flight.landed_dt else None } }) return flight @router.delete("/{flight_id}", response_model=LocalFlight) async def cancel_local_flight( request: Request, flight_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Cancel a local flight record""" flight = crud_local_flight.cancel(db, flight_id=flight_id) if not flight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Local flight record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "local_flight_cancelled", "data": { "id": flight.id, "registration": flight.registration } }) return flight @router.get("/active/current", response_model=List[LocalFlight]) async def get_active_flights( db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get currently active (booked out) flights""" return crud_local_flight.get_active_flights(db) @router.get("/today/departures", response_model=List[LocalFlight]) async def get_today_departures( db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get today's departures (booked out or departed)""" return crud_local_flight.get_departures_today(db) @router.get("/today/booked-out", response_model=List[LocalFlight]) async def get_today_booked_out( db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get all flights booked out today""" return crud_local_flight.get_booked_out_today(db)