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)
