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 DocumentCreate, DocumentUpdate, DocumentResponse, DocumentDetailResponse, DocumentTypeEnum

router = APIRouter(prefix="/documents", tags=["Documents"])

@router.post(
    "/",
    response_model=DocumentResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Document",
    description="Creates a new document record. Validates that the uploader user exists and that at least one of booking_id or customer_id is provided. If booking_id is provided, validates that the booking exists. If customer_id is provided, validates that the customer exists. Returns 400 if validation fails.",
)
def create_document_route(data: DocumentCreate, db: Session = Depends(get_db)):
    return handler.create_document(db, data)

@router.get(
    "/",
    response_model=List[DocumentResponse],
    summary="List Documents",
    description="Returns a paginated list of documents. Supports optional filtering by booking_id, customer_id, document_type, and uploaded_by. Results are ordered by creation date descending.",
)
def list_documents_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    booking_id: Optional[str] = None,
    customer_id: Optional[str] = None,
    document_type: Optional[DocumentTypeEnum] = None,
    uploaded_by: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_documents(
        db,
        limit,
        offset,
        booking_id=booking_id,
        customer_id=customer_id,
        document_type=document_type.value if document_type else None,
        uploaded_by=uploaded_by
    )

@router.get(
    "/{document_id}",
    response_model=DocumentResponse,
    summary="Get Document",
    description="Returns a single document by ID. Returns 404 if the document does not exist.",
)
def get_document_route(document_id: str, db: Session = Depends(get_db)):
    return handler.get_document(db, document_id)

@router.get(
    "/{document_id}/details",
    response_model=DocumentDetailResponse,
    summary="Get Document Details",
    description="Returns detailed information about a document including uploader name, booking number, and customer name. Uses eager loading to fetch related entities efficiently. Returns 404 if the document does not exist.",
)
def get_document_details_route(document_id: str, db: Session = Depends(get_db)):
    return handler.get_document_details(db, document_id)

@router.put(
    "/{document_id}",
    response_model=DocumentResponse,
    summary="Update Document",
    description="Updates an existing document. All fields are optional. If booking_id or customer_id are provided, validates that they exist. Returns 404 if the document does not exist, 400 if validation fails.",
)
def update_document_route(
    document_id: str,
    data: DocumentUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_document(db, document_id, data)

@router.delete(
    "/{document_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Document",
    description="Deletes a document by ID. Returns 404 if the document does not exist.",
)
def delete_document_route(document_id: str, db: Session = Depends(get_db)):
    return handler.delete_document(db, document_id)

@router.get(
    "/booking/{booking_id}/documents",
    response_model=List[DocumentResponse],
    summary="Get Booking Documents",
    description="Returns all documents associated with a specific booking. Returns 404 if the booking does not exist.",
)
def get_booking_documents_route(booking_id: str, db: Session = Depends(get_db)):
    return handler.get_booking_documents(db, booking_id)

@router.get(
    "/customer/{customer_id}/documents",
    response_model=List[DocumentResponse],
    summary="Get Customer Documents",
    description="Returns all documents associated with a specific customer. Returns 404 if the customer does not exist.",
)
def get_customer_documents_route(customer_id: str, db: Session = Depends(get_db)):
    return handler.get_customer_documents(db, customer_id)