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 (
    CancellationrequestCreate,
    CancellationrequestUpdate,
    CancellationrequestResponse,
    CancellationrequestDetailResponse,
    CancellationRequestStatus,
)

router = APIRouter(prefix="/cancellation-requests", tags=["Cancellation Requests"])


@router.post(
    "/",
    response_model=CancellationrequestResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Cancellation Request",
    description="Creates a new cancellation request for a booking. Validates that the booking exists, belongs to the customer, is not already cancelled, and that no pending or approved cancellation request exists. Returns 400 if validation fails, 404 if booking or customer not found, 409 if a conflicting cancellation request exists.",
)
def create_cancellation_request_route(
    data: CancellationrequestCreate,
    db: Session = Depends(get_db),
):
    return handler.create_cancellation_request(db, data)


@router.get(
    "/",
    response_model=List[CancellationrequestResponse],
    summary="List Cancellation Requests",
    description="Returns a paginated list of cancellation requests. Supports optional filters for status, customer_id, and booking_id. Results are ordered by creation date descending.",
)
def list_cancellation_requests_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    status_filter: Optional[CancellationRequestStatus] = Query(None),
    customer_id: Optional[str] = Query(None),
    booking_id: Optional[str] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.list_cancellation_requests(db, limit, offset, status_filter, customer_id, booking_id)


@router.get(
    "/{id}",
    response_model=CancellationrequestResponse,
    summary="Get Cancellation Request",
    description="Returns a single cancellation request by ID. Returns 404 if the cancellation request does not exist.",
)
def get_cancellation_request_route(
    id: str,
    db: Session = Depends(get_db),
):
    return handler.get_cancellation_request(db, id)


@router.get(
    "/{id}/details",
    response_model=CancellationrequestDetailResponse,
    summary="Get Cancellation Request Details",
    description="Returns detailed information about a cancellation request including related booking, customer, and processor information. Uses eager loading to minimize database queries. Returns 404 if the cancellation request does not exist.",
)
def get_cancellation_request_details_route(
    id: str,
    db: Session = Depends(get_db),
):
    return handler.get_cancellation_request_details(db, id)


@router.put(
    "/{id}",
    response_model=CancellationrequestResponse,
    summary="Update Cancellation Request",
    description="Updates an existing cancellation request. Validates that referenced booking, customer, and processor exist if those fields are being updated. Returns 400 if validation fails, 404 if the cancellation request or referenced entities do not exist.",
)
def update_cancellation_request_route(
    id: str,
    data: CancellationrequestUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_cancellation_request(db, id, data)


@router.delete(
    "/{id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Cancellation Request",
    description="Deletes a cancellation request. Only pending cancellation requests can be deleted. Returns 400 if the request is not pending, 404 if the cancellation request does not exist.",
)
def delete_cancellation_request_route(
    id: str,
    db: Session = Depends(get_db),
):
    return handler.delete_cancellation_request(db, id)


@router.post(
    "/{id}/approve",
    response_model=CancellationrequestResponse,
    summary="Approve Cancellation Request",
    description="Approves a pending cancellation request. Updates the status to approved, records the processor and processing date, and optionally stores admin notes. Returns 400 if the request is not pending, 404 if the cancellation request or processor does not exist.",
)
def approve_cancellation_request_route(
    id: str,
    processed_by: str = Query(..., description="User ID of the processor"),
    admin_notes: Optional[str] = Query(None, description="Optional admin notes"),
    db: Session = Depends(get_db),
):
    return handler.approve_cancellation_request(db, id, processed_by, admin_notes)


@router.post(
    "/{id}/reject",
    response_model=CancellationrequestResponse,
    summary="Reject Cancellation Request",
    description="Rejects a pending cancellation request. Updates the status to rejected, records the processor and processing date, and optionally stores admin notes. Returns 400 if the request is not pending, 404 if the cancellation request or processor does not exist.",
)
def reject_cancellation_request_route(
    id: str,
    processed_by: str = Query(..., description="User ID of the processor"),
    admin_notes: Optional[str] = Query(None, description="Optional admin notes"),
    db: Session = Depends(get_db),
):
    return handler.reject_cancellation_request(db, id, processed_by, admin_notes)