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_overflight import overflight as crud_overflight from app.schemas.overflight import Overflight, OverflightCreate, OverflightUpdate, OverflightStatus, OverflightStatusUpdate from app.models.ppr import User from app.core.utils import get_client_ip router = APIRouter() @router.get("/", response_model=List[Overflight]) async def get_overflights( request: Request, skip: int = 0, limit: int = 100, status: Optional[OverflightStatus] = 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 overflight records with optional filtering""" overflights = crud_overflight.get_multi( db, skip=skip, limit=limit, status=status, date_from=date_from, date_to=date_to ) return overflights @router.post("/", response_model=Overflight) async def create_overflight( request: Request, overflight_in: OverflightCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Create a new overflight record""" overflight = crud_overflight.create(db, obj_in=overflight_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": "overflight_created", "data": { "id": overflight.id, "registration": overflight.registration, "departure_airfield": overflight.departure_airfield, "destination_airfield": overflight.destination_airfield, "status": overflight.status.value } }) return overflight @router.get("/{overflight_id}", response_model=Overflight) async def get_overflight( overflight_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get a specific overflight record""" overflight = crud_overflight.get(db, overflight_id=overflight_id) if not overflight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Overflight record not found" ) return overflight @router.put("/{overflight_id}", response_model=Overflight) async def update_overflight( request: Request, overflight_id: int, overflight_in: OverflightUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update an overflight record""" db_overflight = crud_overflight.get(db, overflight_id=overflight_id) if not db_overflight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Overflight record not found" ) # Get user IP from request user_ip = request.client.host if request.client else None overflight = crud_overflight.update( db, db_obj=db_overflight, obj_in=overflight_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": "overflight_updated", "data": { "id": overflight.id, "registration": overflight.registration, "status": overflight.status.value } }) return overflight @router.patch("/{overflight_id}/status", response_model=Overflight) async def update_overflight_status( request: Request, overflight_id: int, status_update: OverflightStatusUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Update overflight status (ACTIVE -> INACTIVE for QSY)""" client_ip = get_client_ip(request) overflight = crud_overflight.update_status( db, overflight_id=overflight_id, status=status_update.status, timestamp=status_update.timestamp if hasattr(status_update, 'timestamp') else None, user=current_user.username, user_ip=client_ip ) if not overflight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Overflight record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "overflight_status_update", "data": { "id": overflight.id, "registration": overflight.registration, "status": overflight.status.value, "qsy_dt": overflight.qsy_dt.isoformat() if overflight.qsy_dt else None } }) return overflight @router.delete("/{overflight_id}", response_model=Overflight) async def cancel_overflight( request: Request, overflight_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_operator_user) ): """Cancel an overflight record""" client_ip = get_client_ip(request) overflight = crud_overflight.cancel( db, overflight_id=overflight_id, user=current_user.username, user_ip=client_ip ) if not overflight: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Overflight record not found" ) # Send real-time update if hasattr(request.app.state, 'connection_manager'): await request.app.state.connection_manager.broadcast({ "type": "overflight_cancelled", "data": { "id": overflight.id, "registration": overflight.registration } }) return overflight @router.get("/active/list", response_model=List[Overflight]) async def get_active_overflights( db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get currently active overflights""" overflights = crud_overflight.get_active_overflights(db) return overflights @router.get("/today/list", response_model=List[Overflight]) async def get_overflights_today( db: Session = Depends(get_db), current_user: User = Depends(get_current_read_user) ): """Get today's overflights""" overflights = crud_overflight.get_overflights_today(db) return overflights