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 (
    CartCreate, CartUpdate, CartResponse,
    CartitemCreate, CartitemUpdate, CartitemResponse,
    WishlistCreate, WishlistUpdate, WishlistResponse,
    WishlistitemCreate, WishlistitemUpdate, WishlistitemResponse,
    CartDetailResponse, WishlistDetailResponse
)

router = APIRouter(prefix="/shopping", tags=["Shopping"])


@router.post(
    "/carts",
    response_model=CartResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Cart",
    description="Creates a new shopping cart for a user. Returns 400 if the user does not exist or 409 if the user already has a cart.",
)
def create_cart_route(data: CartCreate, db: Session = Depends(get_db)):
    return handler.create_cart(db, data)


@router.get(
    "/carts/{cart_id}",
    response_model=CartResponse,
    summary="Get Cart",
    description="Retrieves a cart by ID. Returns 404 if the cart does not exist.",
)
def get_cart_route(cart_id: str, db: Session = Depends(get_db)):
    return handler.get_cart(db, cart_id)


@router.get(
    "/carts",
    response_model=List[CartResponse],
    summary="List Carts",
    description="Returns a paginated list of carts. Supports optional filtering by user_id.",
)
def list_carts_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_carts(db, limit, offset, user_id)


@router.put(
    "/carts/{cart_id}",
    response_model=CartResponse,
    summary="Update Cart",
    description="Updates a cart by ID. Returns 404 if the cart does not exist or 400 if the user does not exist.",
)
def update_cart_route(cart_id: str, data: CartUpdate, db: Session = Depends(get_db)):
    return handler.update_cart(db, cart_id, data)


@router.delete(
    "/carts/{cart_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Cart",
    description="Deletes a cart by ID. Returns 404 if the cart does not exist.",
)
def delete_cart_route(cart_id: str, db: Session = Depends(get_db)):
    return handler.delete_cart(db, cart_id)


@router.get(
    "/carts/{cart_id}/details",
    response_model=CartDetailResponse,
    summary="Get Cart Details",
    description="Retrieves detailed cart information including all cart items with their associated listings, cards, and sellers. Returns 404 if the cart does not exist.",
)
def get_cart_details_route(cart_id: str, db: Session = Depends(get_db)):
    return handler.get_cart_details(db, cart_id)


@router.post(
    "/cart-items",
    response_model=CartitemResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Cart Item",
    description="Adds a listing to a cart. Validates that the cart and listing exist and that sufficient quantity is available. Returns 400 if validation fails.",
)
def create_cartitem_route(data: CartitemCreate, db: Session = Depends(get_db)):
    return handler.create_cartitem(db, data)


@router.get(
    "/cart-items/{cartitem_id}",
    response_model=CartitemResponse,
    summary="Get Cart Item",
    description="Retrieves a cart item by ID. Returns 404 if the cart item does not exist.",
)
def get_cartitem_route(cartitem_id: str, db: Session = Depends(get_db)):
    return handler.get_cartitem(db, cartitem_id)


@router.get(
    "/cart-items",
    response_model=List[CartitemResponse],
    summary="List Cart Items",
    description="Returns a paginated list of cart items. Supports optional filtering by cart_id and listing_id.",
)
def list_cartitems_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    cart_id: Optional[str] = None,
    listing_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_cartitems(db, limit, offset, cart_id, listing_id)


@router.put(
    "/cart-items/{cartitem_id}",
    response_model=CartitemResponse,
    summary="Update Cart Item",
    description="Updates a cart item by ID. Validates that the cart and listing exist and that sufficient quantity is available. Returns 404 if the cart item does not exist or 400 if validation fails.",
)
def update_cartitem_route(cartitem_id: str, data: CartitemUpdate, db: Session = Depends(get_db)):
    return handler.update_cartitem(db, cartitem_id, data)


@router.delete(
    "/cart-items/{cartitem_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Cart Item",
    description="Removes a cart item by ID. Returns 404 if the cart item does not exist.",
)
def delete_cartitem_route(cartitem_id: str, db: Session = Depends(get_db)):
    return handler.delete_cartitem(db, cartitem_id)


@router.post(
    "/wishlists",
    response_model=WishlistResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Wishlist",
    description="Creates a new wishlist for a user. Returns 400 if the user does not exist.",
)
def create_wishlist_route(data: WishlistCreate, db: Session = Depends(get_db)):
    return handler.create_wishlist(db, data)


@router.get(
    "/wishlists/{wishlist_id}",
    response_model=WishlistResponse,
    summary="Get Wishlist",
    description="Retrieves a wishlist by ID. Returns 404 if the wishlist does not exist.",
)
def get_wishlist_route(wishlist_id: str, db: Session = Depends(get_db)):
    return handler.get_wishlist(db, wishlist_id)


@router.get(
    "/wishlists",
    response_model=List[WishlistResponse],
    summary="List Wishlists",
    description="Returns a paginated list of wishlists. Supports optional filtering by user_id and is_public.",
)
def list_wishlists_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = None,
    is_public: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    return handler.list_wishlists(db, limit, offset, user_id, is_public)


@router.put(
    "/wishlists/{wishlist_id}",
    response_model=WishlistResponse,
    summary="Update Wishlist",
    description="Updates a wishlist by ID. Returns 404 if the wishlist does not exist or 400 if the user does not exist.",
)
def update_wishlist_route(wishlist_id: str, data: WishlistUpdate, db: Session = Depends(get_db)):
    return handler.update_wishlist(db, wishlist_id, data)


@router.delete(
    "/wishlists/{wishlist_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Wishlist",
    description="Deletes a wishlist by ID. Returns 404 if the wishlist does not exist.",
)
def delete_wishlist_route(wishlist_id: str, db: Session = Depends(get_db)):
    return handler.delete_wishlist(db, wishlist_id)


@router.get(
    "/wishlists/{wishlist_id}/details",
    response_model=WishlistDetailResponse,
    summary="Get Wishlist Details",
    description="Retrieves detailed wishlist information including all wishlist items with their associated cards and card sets. Returns 404 if the wishlist does not exist.",
)
def get_wishlist_details_route(wishlist_id: str, db: Session = Depends(get_db)):
    return handler.get_wishlist_details(db, wishlist_id)


@router.post(
    "/wishlist-items",
    response_model=WishlistitemResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Wishlist Item",
    description="Adds a card to a wishlist. Validates that the wishlist and card exist. Returns 400 if validation fails.",
)
def create_wishlistitem_route(data: WishlistitemCreate, db: Session = Depends(get_db)):
    return handler.create_wishlistitem(db, data)


@router.get(
    "/wishlist-items/{wishlistitem_id}",
    response_model=WishlistitemResponse,
    summary="Get Wishlist Item",
    description="Retrieves a wishlist item by ID. Returns 404 if the wishlist item does not exist.",
)
def get_wishlistitem_route(wishlistitem_id: str, db: Session = Depends(get_db)):
    return handler.get_wishlistitem(db, wishlistitem_id)


@router.get(
    "/wishlist-items",
    response_model=List[WishlistitemResponse],
    summary="List Wishlist Items",
    description="Returns a paginated list of wishlist items. Supports optional filtering by wishlist_id and card_id.",
)
def list_wishlistitems_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    wishlist_id: Optional[str] = None,
    card_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_wishlistitems(db, limit, offset, wishlist_id, card_id)


@router.put(
    "/wishlist-items/{wishlistitem_id}",
    response_model=WishlistitemResponse,
    summary="Update Wishlist Item",
    description="Updates a wishlist item by ID. Validates that the wishlist and card exist. Returns 404 if the wishlist item does not exist or 400 if validation fails.",
)
def update_wishlistitem_route(wishlistitem_id: str, data: WishlistitemUpdate, db: Session = Depends(get_db)):
    return handler.update_wishlistitem(db, wishlistitem_id, data)


@router.delete(
    "/wishlist-items/{wishlistitem_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Wishlist Item",
    description="Removes a wishlist item by ID. Returns 404 if the wishlist item does not exist.",
)
def delete_wishlistitem_route(wishlistitem_id: str, db: Session = Depends(get_db)):
    return handler.delete_wishlistitem(db, wishlistitem_id)