from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from datetime import date
from utils.utils import get_db
from . import handler
from .schema import (
    FareclassCreate,
    FareclassUpdate,
    FareclassResponse,
    FlightCreate,
    FlightUpdate,
    FlightResponse,
    FlightDetailResponse,
    FlightSearchRequest,
    FlightStatusUpdateRequest,
    PassengerManifestResponse,
)

router = APIRouter(prefix="/flight-management", tags=["Flight Management"])


# Fareclass routes
@router.post(
    "/fare-classes",
    response_model=FareclassResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Fare Class",
    description="Creates a new fare class with pricing rules and baggage allowances. Returns 409 if a fare class with the same name already exists.",
)
def create_fareclass_route(data: FareclassCreate, db: Session = Depends(get_db)):
    return handler.create_fareclass(db, data)


@router.get(
    "/fare-classes",
    response_model=List[FareclassResponse],
    summary="List Fare Classes",
    description="Returns a paginated list of fare classes. Supports optional filtering by name search and class type.",
)
def list_fareclasses_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    search: Optional[str] = None,
    class_type: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_fareclasses(db, limit, offset, search, class_type)


@router.get(
    "/fare-classes/{fareclass_id}",
    response_model=FareclassResponse,
    summary="Get Fare Class",
    description="Returns details of a specific fare class by ID. Returns 404 if the fare class is not found.",
)
def get_fareclass_route(fareclass_id: str, db: Session = Depends(get_db)):
    return handler.get_fareclass(db, fareclass_id)


@router.put(
    "/fare-classes/{fareclass_id}",
    response_model=FareclassResponse,
    summary="Update Fare Class",
    description="Updates an existing fare class. Only provided fields are updated. Returns 404 if not found, 409 if the new name conflicts with an existing fare class.",
)
def update_fareclass_route(
    fareclass_id: str, data: FareclassUpdate, db: Session = Depends(get_db)
):
    return handler.update_fareclass(db, fareclass_id, data)


@router.delete(
    "/fare-classes/{fareclass_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Fare Class",
    description="Deletes a fare class by ID. Returns 404 if the fare class is not found.",
)
def delete_fareclass_route(fareclass_id: str, db: Session = Depends(get_db)):
    return handler.delete_fareclass(db, fareclass_id)


# Flight routes
@router.post(
    "/flights",
    response_model=FlightResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Flight",
    description="Creates a new scheduled flight. Validates that the route and aircraft exist, aircraft is active, departure is in the future, and arrival is after departure. Returns 400 for validation failures, 404 if route or aircraft not found.",
)
def create_flight_route(data: FlightCreate, db: Session = Depends(get_db)):
    return handler.create_flight(db, data)


@router.get(
    "/flights",
    response_model=List[FlightResponse],
    summary="List Flights",
    description="Returns a paginated list of flights. Supports optional filtering by status, aircraft, route, and date.",
)
def list_flights_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    status: Optional[str] = None,
    aircraft_id: Optional[str] = None,
    route_id: Optional[str] = None,
    date: Optional[date] = None,
    db: Session = Depends(get_db),
):
    return handler.list_flights(db, limit, offset, status, aircraft_id, route_id, date)


@router.get(
    "/flights/{flight_id}",
    response_model=FlightResponse,
    summary="Get Flight",
    description="Returns details of a specific flight by ID. Returns 404 if the flight is not found.",
)
def get_flight_route(flight_id: str, db: Session = Depends(get_db)):
    return handler.get_flight(db, flight_id)


@router.put(
    "/flights/{flight_id}",
    response_model=FlightResponse,
    summary="Update Flight",
    description="Updates an existing flight. Only provided fields are updated. Validates that flights with departed or arrived status cannot be edited. Returns 400 for validation failures, 404 if flight, route, or aircraft not found.",
)
def update_flight_route(
    flight_id: str, data: FlightUpdate, db: Session = Depends(get_db)
):
    return handler.update_flight(db, flight_id, data)


@router.delete(
    "/flights/{flight_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Flight",
    description="Deletes a flight by ID. Returns 404 if the flight is not found.",
)
def delete_flight_route(flight_id: str, db: Session = Depends(get_db)):
    return handler.delete_flight(db, flight_id)


@router.get(
    "/flights/{flight_id}/details",
    response_model=FlightDetailResponse,
    summary="Get Flight Details",
    description="Returns comprehensive flight details including route with origin and destination airports, aircraft information, bookings list, and assigned crew members with their roles. All related data is eagerly loaded in a single query.",
)
def get_flight_details_route(flight_id: str, db: Session = Depends(get_db)):
    return handler.get_flight_details(db, flight_id)


@router.get(
    "/flights/search",
    response_model=List[FlightResponse],
    summary="Search Flights",
    description="Searches for scheduled flights between two airports on a specific date. Returns flights with origin and destination airport codes matching the search criteria.",
)
def search_flights_route(
    origin: str = Query(..., max_length=3),
    destination: str = Query(..., max_length=3),
    date: date = Query(...),
    db: Session = Depends(get_db),
):
    search_params = FlightSearchRequest(origin=origin, destination=destination, date=date)
    return handler.search_flights(db, search_params)


@router.post(
    "/flights/{flight_id}/update-status",
    response_model=FlightResponse,
    summary="Update Flight Status",
    description="Updates the status of a flight. Automatically sets actual departure or arrival timestamps when transitioning to departed or arrived status. Returns 404 if flight not found.",
)
def update_flight_status_route(
    flight_id: str, status_data: FlightStatusUpdateRequest, db: Session = Depends(get_db)
):
    return handler.update_flight_status(db, flight_id, status_data)


@router.post(
    "/flights/{flight_id}/cancel",
    response_model=FlightResponse,
    summary="Cancel Flight",
    description="Cancels a flight and automatically cancels all associated bookings. Returns 400 if the flight is already departed, arrived, or cancelled. Returns 404 if flight not found.",
)
def cancel_flight_route(flight_id: str, db: Session = Depends(get_db)):
    return handler.cancel_flight_and_bookings(db, flight_id)


@router.get(
    "/flights/{flight_id}/passenger-manifest",
    response_model=List[PassengerManifestResponse],
    summary="Get Passenger Manifest",
    description="Returns a list of all passengers booked on a specific flight, including booking reference, passenger name, seat assignment, booking status, and fare class. Returns 404 if flight not found.",
)
def get_passenger_manifest_route(flight_id: str, db: Session = Depends(get_db)):
    return handler.get_passenger_manifest(db, flight_id)