from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from utils.utils import get_db
from . import handler
from .schema import (
    AirportCreate,
    AirportUpdate,
    AirportResponse,
    RouteCreate,
    RouteUpdate,
    RouteResponse,
    RouteDetailResponse,
    RouteStatus
)

router = APIRouter(prefix="/airport-route-management", tags=["Airport & Route Management"])


@router.post(
    "/airports",
    response_model=AirportResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Airport",
    description="Creates a new airport record with unique IATA code. Returns 409 if the airport code already exists. Airport code must be exactly 3 uppercase letters."
)
def create_airport_route(data: AirportCreate, db: Session = Depends(get_db)):
    return handler.create_airport(db, data)


@router.get(
    "/airports",
    response_model=List[AirportResponse],
    summary="List Airports",
    description="Returns a paginated list of airports. Supports optional search filter on code, name, city, and country fields."
)
def list_airports_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    search: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_airports(db, limit, offset, search)


@router.get(
    "/airports/{id}",
    response_model=AirportResponse,
    summary="Get Airport By ID",
    description="Returns a single airport by its unique identifier. Returns 404 if the airport is not found."
)
def get_airport_route(id: str, db: Session = Depends(get_db)):
    return handler.get_airport(db, id)


@router.put(
    "/airports/{id}",
    response_model=AirportResponse,
    summary="Update Airport",
    description="Updates an existing airport record. Returns 404 if the airport is not found. Returns 409 if the new code conflicts with an existing airport."
)
def update_airport_route(id: str, data: AirportUpdate, db: Session = Depends(get_db)):
    return handler.update_airport(db, id, data)


@router.delete(
    "/airports/{id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Airport",
    description="Deletes an airport record. Returns 404 if the airport is not found. Returns 409 if the airport is referenced by any routes."
)
def delete_airport_route(id: str, db: Session = Depends(get_db)):
    return handler.delete_airport(db, id)


@router.post(
    "/routes",
    response_model=RouteResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Route",
    description="Creates a new route between two airports. Validates that origin and destination airports exist and are different. Returns 409 if a route between these airports already exists."
)
def create_route_route(data: RouteCreate, db: Session = Depends(get_db)):
    return handler.create_route(db, data)


@router.get(
    "/routes",
    response_model=List[RouteResponse],
    summary="List Routes",
    description="Returns a paginated list of routes. Supports optional filters for status, origin airport, and destination airport."
)
def list_routes_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    status_filter: Optional[RouteStatus] = Query(None, alias="status"),
    origin_airport_id: Optional[str] = None,
    destination_airport_id: Optional[str] = None,
    db: Session = Depends(get_db)
):
    return handler.list_routes(db, limit, offset, status_filter, origin_airport_id, destination_airport_id)


@router.get(
    "/routes/{id}",
    response_model=RouteResponse,
    summary="Get Route By ID",
    description="Returns a single route by its unique identifier. Returns 404 if the route is not found."
)
def get_route_route(id: str, db: Session = Depends(get_db)):
    return handler.get_route(db, id)


@router.get(
    "/routes/{id}/details",
    response_model=RouteDetailResponse,
    summary="Get Route Details",
    description="Returns detailed route information including origin and destination airport details. Returns 404 if the route is not found."
)
def get_route_details_route(id: str, db: Session = Depends(get_db)):
    return handler.get_route_details(db, id)


@router.put(
    "/routes/{id}",
    response_model=RouteResponse,
    summary="Update Route",
    description="Updates an existing route record. Validates that origin and destination airports exist and are different. Returns 404 if the route is not found. Returns 409 if the updated route conflicts with an existing route."
)
def update_route_route(id: str, data: RouteUpdate, db: Session = Depends(get_db)):
    return handler.update_route(db, id, data)


@router.delete(
    "/routes/{id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Route",
    description="Deletes a route record. Returns 404 if the route is not found. Returns 409 if the route has associated flights."
)
def delete_route_route(id: str, db: Session = Depends(get_db)):
    return handler.delete_route(db, id)