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, ReviewDetailsResponse
from pydantic import BaseModel


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


class SellerResponseRequest(BaseModel):
    response_text: str
    seller_id: str


@router.post(
    "/",
    response_model=ReviewResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Review",
    description="Creates a new review for a completed order. Validates that the order exists, the reviewer and seller are valid users, and enforces the business rule of one review per order. Returns 404 if order or users not found, 409 if a review already exists for the order.",
)
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 filtering by order_id, reviewer_id, seller_id, rating, and is_verified_purchase. 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),
    order_id: Optional[str] = None,
    reviewer_id: Optional[str] = None,
    seller_id: Optional[str] = None,
    rating: Optional[int] = Query(None, ge=1, le=5),
    is_verified_purchase: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    return handler.list_reviews(db, limit, offset, order_id, reviewer_id, seller_id, rating, is_verified_purchase)


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


@router.get(
    "/{review_id}/details",
    response_model=ReviewDetailsResponse,
    summary="Get Review Details",
    description="Retrieves detailed review information including order details, reviewer profile, and seller profile. Uses eager loading to prevent N+1 queries. Returns 404 if the review does not exist.",
)
def get_review_details_route(review_id: str, db: Session = Depends(get_db)):
    return handler.get_review_details(db, review_id)


@router.put(
    "/{review_id}",
    response_model=ReviewResponse,
    summary="Update Review",
    description="Updates an existing review. Validates foreign key references if order_id, reviewer_id, or seller_id are changed. Returns 404 if the review or referenced entities do not exist.",
)
def update_review_route(review_id: str, data: ReviewUpdate, db: Session = Depends(get_db)):
    return handler.update_review(db, review_id, data)


@router.delete(
    "/{review_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Review",
    description="Permanently deletes a review. Returns 404 if the review does not exist.",
)
def delete_review_route(review_id: str, db: Session = Depends(get_db)):
    return handler.delete_review(db, review_id)


@router.post(
    "/{review_id}/respond",
    response_model=ReviewResponse,
    summary="Seller Responds to Review",
    description="Allows a seller to respond to a review. Validates that the seller_id matches the review's seller_id. Updates seller_response and seller_response_at fields. Returns 403 if the seller is not authorized, 404 if the review does not exist.",
)
def respond_to_review_route(
    review_id: str,
    request: SellerResponseRequest,
    db: Session = Depends(get_db)
):
    return handler.respond_to_review(db, review_id, request.response_text, request.seller_id)