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 ReviewCreate, ReviewUpdate, ReviewResponse, ReviewDetailResponse

router = APIRouter(prefix="/reviews", tags=["Reviews"])


@router.post(
    "/",
    response_model=ReviewResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Review",
    description="Creates a new review for a completed booking. Validates that the booking exists, is completed, and does not already have a review. Returns 404 if booking, customer, tour package, or tour guide not found. Returns 400 if booking is not completed. Returns 409 if review already exists for the booking."
)
def create_review_route(data: ReviewCreate, db: Session = Depends(get_db)):
    return handler.create_review(db, data)


@router.get(
    "/",
    response_model=List[ReviewResponse],
    summary="List Reviews",
    description="Returns a paginated list of reviews. Supports optional filters for customer_id, tour_package_id, tour_guide_id, is_published, and is_verified. Results are ordered by creation date descending."
)
def list_reviews_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    customer_id: Optional[str] = None,
    tour_package_id: Optional[str] = None,
    tour_guide_id: Optional[str] = None,
    is_published: Optional[bool] = None,
    is_verified: Optional[bool] = None,
    db: Session = Depends(get_db)
):
    return handler.list_reviews(
        db,
        limit,
        offset,
        customer_id,
        tour_package_id,
        tour_guide_id,
        is_published,
        is_verified
    )


@router.get(
    "/{id}",
    response_model=ReviewResponse,
    summary="Get Review",
    description="Returns a single review by ID. Returns 404 if review not found."
)
def get_review_route(id: str, db: Session = Depends(get_db)):
    return handler.get_review(db, id)


@router.get(
    "/{id}/details",
    response_model=ReviewDetailResponse,
    summary="Get Review Details",
    description="Returns detailed review information including customer name, tour package name, tour guide name, and booking number. Uses eager loading to minimize database queries. Returns 404 if review not found."
)
def get_review_details_route(id: str, db: Session = Depends(get_db)):
    return handler.get_review_details(db, id)


@router.put(
    "/{id}",
    response_model=ReviewResponse,
    summary="Update Review",
    description="Updates an existing review. All fields are optional. Validates foreign key references if they are being updated. Returns 404 if review or any referenced entity not found."
)
def update_review_route(id: str, data: ReviewUpdate, db: Session = Depends(get_db)):
    return handler.update_review(db, id, data)


@router.delete(
    "/{id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Review",
    description="Deletes a review by ID. Returns 404 if review not found."
)
def delete_review_route(id: str, db: Session = Depends(get_db)):
    return handler.delete_review(db, id)


@router.post(
    "/{id}/publish",
    response_model=ReviewResponse,
    summary="Publish Review",
    description="Publishes a review making it visible to the public. Returns 400 if review is already published. Returns 404 if review not found."
)
def publish_review_route(id: str, db: Session = Depends(get_db)):
    return handler.publish_review(db, id)


@router.post(
    "/{id}/respond",
    response_model=ReviewResponse,
    summary="Respond To Review",
    description="Adds a management response to a published review and records the response timestamp. Returns 400 if review is not published. Returns 404 if review not found."
)
def respond_to_review_route(
    id: str,
    response_text: str = Query(..., min_length=1),
    db: Session = Depends(get_db)
):
    return handler.respond_to_review(db, id, response_text)