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 (
    GradingserviceCreate,
    GradingserviceUpdate,
    GradingserviceResponse,
    GradedcardCreate,
    GradedcardUpdate,
    GradedcardResponse,
    GradedcardDetailResponse,
)

router = APIRouter(prefix="/grading", tags=["Grading"])


# Gradingservice routes
@router.post(
    "/services",
    response_model=GradingserviceResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Grading Service",
    description="Creates a new grading service record. Returns 409 if a service with the same name or abbreviation already exists.",
)
def create_gradingservice_route(data: GradingserviceCreate, db: Session = Depends(get_db)):
    return handler.create_gradingservice(db, data)


@router.get(
    "/services/{gradingservice_id}",
    response_model=GradingserviceResponse,
    summary="Get Grading Service",
    description="Retrieves a single grading service by ID. Returns 404 if not found.",
)
def get_gradingservice_route(gradingservice_id: str, db: Session = Depends(get_db)):
    return handler.get_gradingservice(db, gradingservice_id)


@router.get(
    "/services",
    response_model=List[GradingserviceResponse],
    summary="List Grading Services",
    description="Returns a paginated list of grading services. Supports optional filtering by name and abbreviation.",
)
def list_gradingservices_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    name: Optional[str] = None,
    abbreviation: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_gradingservices(db, limit, offset, name, abbreviation)


@router.put(
    "/services/{gradingservice_id}",
    response_model=GradingserviceResponse,
    summary="Update Grading Service",
    description="Updates an existing grading service. Returns 404 if not found, 409 if name or abbreviation conflicts with another service.",
)
def update_gradingservice_route(
    gradingservice_id: str,
    data: GradingserviceUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_gradingservice(db, gradingservice_id, data)


@router.delete(
    "/services/{gradingservice_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Grading Service",
    description="Deletes a grading service by ID. Returns 404 if not found. Fails if graded cards reference this service.",
)
def delete_gradingservice_route(gradingservice_id: str, db: Session = Depends(get_db)):
    return handler.delete_gradingservice(db, gradingservice_id)


# Gradedcard routes
@router.post(
    "/graded-cards",
    response_model=GradedcardResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Graded Card",
    description="Creates a new graded card record for a listing. Returns 404 if listing or grading service not found, 409 if listing already has a graded card or certification number is duplicate.",
)
def create_gradedcard_route(data: GradedcardCreate, db: Session = Depends(get_db)):
    return handler.create_gradedcard(db, data)


@router.get(
    "/graded-cards/{gradedcard_id}",
    response_model=GradedcardResponse,
    summary="Get Graded Card",
    description="Retrieves a single graded card by ID. Returns 404 if not found.",
)
def get_gradedcard_route(gradedcard_id: str, db: Session = Depends(get_db)):
    return handler.get_gradedcard(db, gradedcard_id)


@router.get(
    "/graded-cards/{gradedcard_id}/details",
    response_model=GradedcardDetailResponse,
    summary="Get Graded Card Details",
    description="Retrieves a graded card with full grading service details. Returns 404 if not found.",
)
def get_gradedcard_details_route(gradedcard_id: str, db: Session = Depends(get_db)):
    return handler.get_gradedcard_details(db, gradedcard_id)


@router.get(
    "/graded-cards",
    response_model=List[GradedcardResponse],
    summary="List Graded Cards",
    description="Returns a paginated list of graded cards. Supports optional filtering by listing, grading service, grade, and certification number.",
)
def list_gradedcards_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    listing_id: Optional[str] = None,
    grading_service_id: Optional[str] = None,
    grade: Optional[str] = None,
    certification_number: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_gradedcards(db, limit, offset, listing_id, grading_service_id, grade, certification_number)


@router.put(
    "/graded-cards/{gradedcard_id}",
    response_model=GradedcardResponse,
    summary="Update Graded Card",
    description="Updates an existing graded card. Returns 404 if not found or referenced entities not found, 409 if listing already has another graded card or certification number conflicts.",
)
def update_gradedcard_route(
    gradedcard_id: str,
    data: GradedcardUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_gradedcard(db, gradedcard_id, data)


@router.delete(
    "/graded-cards/{gradedcard_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Graded Card",
    description="Deletes a graded card by ID. Returns 404 if not found.",
)
def delete_gradedcard_route(gradedcard_id: str, db: Session = Depends(get_db)):
    return handler.delete_gradedcard(db, gradedcard_id)