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 (
    HotelCreate,
    HotelUpdate,
    HotelResponse,
    HotelDetailResponse,
    HotelamenityCreate,
    HotelamenityResponse,
    RoomtypeCreate,
    RoomtypeUpdate,
    RoomtypeResponse,
    TransportationCreate,
    TransportationUpdate,
    TransportationResponse,
    TransportType,
)

router = APIRouter(prefix="/service-providers", tags=["Service Provider Management"])


@router.post(
    "/hotels",
    response_model=HotelResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Hotel",
    description="Creates a new hotel record for a service provider. Validates that the service provider exists and returns 404 if not found.",
)
def create_hotel_route(data: HotelCreate, db: Session = Depends(get_db)):
    return handler.create_hotel(db, data)


@router.get(
    "/hotels/{hotel_id}",
    response_model=HotelResponse,
    summary="Get Hotel By ID",
    description="Retrieves a single hotel record by its unique identifier. Returns 404 if the hotel does not exist.",
)
def get_hotel_route(hotel_id: str, db: Session = Depends(get_db)):
    return handler.get_hotel(db, hotel_id)


@router.get(
    "/hotels",
    response_model=List[HotelResponse],
    summary="List Hotels",
    description="Returns a paginated list of hotels. Supports optional filters for service provider ID and active status.",
)
def list_hotels_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    service_provider_id: Optional[str] = None,
    is_active: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    return handler.list_hotels(db, limit, offset, service_provider_id, is_active)


@router.put(
    "/hotels/{hotel_id}",
    response_model=HotelResponse,
    summary="Update Hotel",
    description="Updates an existing hotel record. Only provided fields are updated. Returns 404 if the hotel or referenced service provider does not exist.",
)
def update_hotel_route(hotel_id: str, data: HotelUpdate, db: Session = Depends(get_db)):
    return handler.update_hotel(db, hotel_id, data)


@router.delete(
    "/hotels/{hotel_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete Hotel",
    description="Deletes a hotel record by ID. Cascades to delete associated room types and hotel amenities. Returns 404 if the hotel does not exist.",
)
def delete_hotel_route(hotel_id: str, db: Session = Depends(get_db)):
    handler.delete_hotel(db, hotel_id)


@router.get(
    "/hotels/{hotel_id}/details",
    response_model=HotelDetailResponse,
    summary="Get Hotel Details",
    description="Retrieves detailed hotel information including service provider details, room types, and amenities. All related data is eagerly loaded. Returns 404 if the hotel does not exist.",
)
def get_hotel_details_route(hotel_id: str, db: Session = Depends(get_db)):
    return handler.get_hotel_with_details(db, hotel_id)


@router.post(
    "/hotel-amenities",
    response_model=HotelamenityResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Hotel Amenity Association",
    description="Associates an amenity with a hotel. Validates that both the hotel and amenity exist. Returns 409 if the association already exists.",
)
def create_hotel_amenity_route(data: HotelamenityCreate, db: Session = Depends(get_db)):
    return handler.create_hotel_amenity(db, data)


@router.get(
    "/hotel-amenities/{hotel_amenity_id}",
    response_model=HotelamenityResponse,
    summary="Get Hotel Amenity By ID",
    description="Retrieves a single hotel amenity association by its unique identifier. Returns 404 if not found.",
)
def get_hotel_amenity_route(hotel_amenity_id: str, db: Session = Depends(get_db)):
    return handler.get_hotel_amenity(db, hotel_amenity_id)


@router.get(
    "/hotel-amenities",
    response_model=List[HotelamenityResponse],
    summary="List Hotel Amenities",
    description="Returns a paginated list of hotel amenity associations. Supports optional filter by hotel ID.",
)
def list_hotel_amenities_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    hotel_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_hotel_amenities(db, limit, offset, hotel_id)


@router.delete(
    "/hotel-amenities/{hotel_amenity_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete Hotel Amenity Association",
    description="Removes an amenity association from a hotel. Returns 404 if the association does not exist.",
)
def delete_hotel_amenity_route(hotel_amenity_id: str, db: Session = Depends(get_db)):
    handler.delete_hotel_amenity(db, hotel_amenity_id)


@router.post(
    "/room-types",
    response_model=RoomtypeResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Room Type",
    description="Creates a new room type for a hotel. Validates that the hotel exists and that capacity, price, and total rooms are positive. Returns 404 if the hotel does not exist.",
)
def create_room_type_route(data: RoomtypeCreate, db: Session = Depends(get_db)):
    return handler.create_room_type(db, data)


@router.get(
    "/room-types/{room_type_id}",
    response_model=RoomtypeResponse,
    summary="Get Room Type By ID",
    description="Retrieves a single room type record by its unique identifier. Returns 404 if not found.",
)
def get_room_type_route(room_type_id: str, db: Session = Depends(get_db)):
    return handler.get_room_type(db, room_type_id)


@router.get(
    "/room-types",
    response_model=List[RoomtypeResponse],
    summary="List Room Types",
    description="Returns a paginated list of room types. Supports optional filter by hotel ID.",
)
def list_room_types_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    hotel_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_room_types(db, limit, offset, hotel_id)


@router.put(
    "/room-types/{room_type_id}",
    response_model=RoomtypeResponse,
    summary="Update Room Type",
    description="Updates an existing room type record. Only provided fields are updated. Returns 404 if the room type or referenced hotel does not exist.",
)
def update_room_type_route(room_type_id: str, data: RoomtypeUpdate, db: Session = Depends(get_db)):
    return handler.update_room_type(db, room_type_id, data)


@router.delete(
    "/room-types/{room_type_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete Room Type",
    description="Deletes a room type record by ID. Returns 404 if the room type does not exist.",
)
def delete_room_type_route(room_type_id: str, db: Session = Depends(get_db)):
    handler.delete_room_type(db, room_type_id)


@router.post(
    "/transportations",
    response_model=TransportationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Transportation",
    description="Creates a new transportation service for a service provider. Validates that the service provider exists and that capacity is positive. Returns 404 if the service provider does not exist.",
)
def create_transportation_route(data: TransportationCreate, db: Session = Depends(get_db)):
    return handler.create_transportation(db, data)


@router.get(
    "/transportations/{transportation_id}",
    response_model=TransportationResponse,
    summary="Get Transportation By ID",
    description="Retrieves a single transportation record by its unique identifier. Returns 404 if not found.",
)
def get_transportation_route(transportation_id: str, db: Session = Depends(get_db)):
    return handler.get_transportation(db, transportation_id)


@router.get(
    "/transportations",
    response_model=List[TransportationResponse],
    summary="List Transportations",
    description="Returns a paginated list of transportation services. Supports optional filters for service provider ID, transport type, and active status.",
)
def list_transportations_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    service_provider_id: Optional[str] = None,
    transport_type: Optional[TransportType] = None,
    is_active: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    return handler.list_transportations(db, limit, offset, service_provider_id, transport_type, is_active)


@router.put(
    "/transportations/{transportation_id}",
    response_model=TransportationResponse,
    summary="Update Transportation",
    description="Updates an existing transportation record. Only provided fields are updated. Returns 404 if the transportation or referenced service provider does not exist.",
)
def update_transportation_route(transportation_id: str, data: TransportationUpdate, db: Session = Depends(get_db)):
    return handler.update_transportation(db, transportation_id, data)


@router.delete(
    "/transportations/{transportation_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete Transportation",
    description="Deletes a transportation record by ID. Returns 404 if the transportation does not exist.",
)
def delete_transportation_route(transportation_id: str, db: Session = Depends(get_db)):
    handler.delete_transportation(db, transportation_id)