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 (
    ReservationCreate,
    ReservationUpdate,
    ReservationResponse,
    ReservationDetailResponse,
)

router = APIRouter(prefix="/reservations", tags=["Reservations"])


@router.post(
    "/",
    response_model=ReservationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Reservation",
    description="Creates a new reservation with temporary seat locks for 15 minutes. Validates that the user does not have an active reservation for the same schedule, all seats are available, and the schedule is in the future. Returns 409 if the user already has an active reservation or if any seat is unavailable.",
)
def create_reservation_route(data: ReservationCreate, db: Session = Depends(get_db)):
    return handler.create_reservation(db, data)


@router.get(
    "/",
    response_model=List[ReservationResponse],
    summary="List Reservations",
    description="Returns a paginated list of reservations. Supports optional filters by user_id, schedule_id, and status.",
)
def list_reservations_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = Query(None),
    schedule_id: Optional[str] = Query(None),
    status: Optional[str] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.list_reservations(db, limit, offset, user_id, schedule_id, status)


@router.get(
    "/active",
    response_model=List[ReservationResponse],
    summary="List Active Reservations",
    description="Returns a paginated list of all active reservations. Used by admin to monitor current reservation locks.",
)
def get_active_reservations_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    db: Session = Depends(get_db),
):
    return handler.get_active_reservations(db, limit, offset)


@router.get(
    "/{reservation_id}",
    response_model=ReservationResponse,
    summary="Get Reservation",
    description="Returns a single reservation by ID. Returns 404 if the reservation does not exist.",
)
def get_reservation_route(reservation_id: str, db: Session = Depends(get_db)):
    return handler.get_reservation(db, reservation_id)


@router.get(
    "/{reservation_id}/details",
    response_model=ReservationDetailResponse,
    summary="Get Reservation Details",
    description="Returns detailed reservation information including user details, schedule with bus and route information, and all reserved seats with their types and numbers. Returns 404 if the reservation does not exist.",
)
def get_reservation_details_route(reservation_id: str, db: Session = Depends(get_db)):
    return handler.get_reservation_details(db, reservation_id)


@router.put(
    "/{reservation_id}",
    response_model=ReservationResponse,
    summary="Update Reservation",
    description="Updates an existing reservation. Validates that referenced user_id and schedule_id exist if provided. Returns 404 if the reservation does not exist.",
)
def update_reservation_route(
    reservation_id: str, data: ReservationUpdate, db: Session = Depends(get_db)
):
    return handler.update_reservation(db, reservation_id, data)


@router.delete(
    "/{reservation_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Reservation",
    description="Deletes a reservation and releases all associated seats back to available status. Updates the schedule available_seats count. Returns 400 if the reservation is already confirmed. Returns 404 if the reservation does not exist.",
)
def delete_reservation_route(reservation_id: str, db: Session = Depends(get_db)):
    return handler.delete_reservation(db, reservation_id)


@router.post(
    "/expire-batch",
    status_code=status.HTTP_200_OK,
    summary="Expire Reservations Batch",
    description="Background job endpoint that finds all expired reservations, updates their status to expired, releases all associated seats back to available, and updates schedule available_seats counts. Returns the count of expired reservations.",
)
def expire_reservations_batch_route(db: Session = Depends(get_db)):
    return handler.expire_reservations_batch(db)


@router.post(
    "/{reservation_id}/release",
    status_code=status.HTTP_200_OK,
    summary="Release Reservation Manually",
    description="Admin endpoint to manually release an active reservation, updating its status to cancelled and releasing all associated seats back to available. Returns 400 if the reservation is not active. Returns 404 if the reservation does not exist.",
)
def release_reservation_manually_route(reservation_id: str, db: Session = Depends(get_db)):
    return handler.release_reservation_manually(db, reservation_id)