# app/modules/cart/exceptions.py
"""
Cart module exceptions.

This module provides exception classes for cart operations including:
- Cart item management
- Quantity validation
- Inventory checks
"""

from app.exceptions.base import (
    BusinessLogicException,
    ResourceNotFoundException,
    ValidationException,
)

__all__ = [
    "CartItemNotFoundException",
    "EmptyCartException",
    "CartValidationException",
    "InsufficientInventoryForCartException",
    "InvalidCartQuantityException",
    "ProductNotAvailableForCartException",
]


class CartItemNotFoundException(ResourceNotFoundException):
    """Raised when a cart item is not found."""

    def __init__(self, product_id: int, session_id: str):
        super().__init__(
            resource_type="CartItem",
            identifier=str(product_id),
            message=f"Product {product_id} not found in cart",
            error_code="CART_ITEM_NOT_FOUND",
        )
        self.details.update({"product_id": product_id, "session_id": session_id})


class EmptyCartException(ValidationException):  # noqa: MOD025
    """Raised when trying to perform operations on an empty cart."""

    def __init__(self, session_id: str):
        super().__init__(message="Cart is empty", details={"session_id": session_id})
        self.error_code = "CART_EMPTY"


class CartValidationException(ValidationException):  # noqa: MOD025
    """Raised when cart data validation fails."""

    def __init__(
        self,
        message: str = "Cart validation failed",
        field: str | None = None,
        details: dict | None = None,
    ):
        super().__init__(
            message=message,
            field=field,
            details=details,
        )
        self.error_code = "CART_VALIDATION_FAILED"


class InsufficientInventoryForCartException(BusinessLogicException):
    """Raised when product doesn't have enough inventory for cart operation."""

    def __init__(
        self,
        product_id: int,
        product_name: str,
        requested: int,
        available: int,
    ):
        message = (
            f"Insufficient inventory for product '{product_name}'. "
            f"Requested: {requested}, Available: {available}"
        )
        super().__init__(
            message=message,
            error_code="INSUFFICIENT_INVENTORY_FOR_CART",
            details={
                "product_id": product_id,
                "product_name": product_name,
                "requested_quantity": requested,
                "available_quantity": available,
            },
        )


class InvalidCartQuantityException(ValidationException):
    """Raised when cart quantity is invalid."""

    def __init__(
        self, quantity: int, min_quantity: int = 1, max_quantity: int | None = None
    ):
        if quantity < min_quantity:
            message = f"Quantity must be at least {min_quantity}"
        elif max_quantity and quantity > max_quantity:
            message = f"Quantity cannot exceed {max_quantity}"
        else:
            message = f"Invalid quantity: {quantity}"

        super().__init__(
            message=message,
            field="quantity",
            details={
                "quantity": quantity,
                "min_quantity": min_quantity,
                "max_quantity": max_quantity,
            },
        )
        self.error_code = "INVALID_CART_QUANTITY"


class ProductNotAvailableForCartException(BusinessLogicException):  # noqa: MOD025
    """Raised when product is not available for adding to cart."""

    def __init__(self, product_id: int, reason: str):
        super().__init__(
            message=f"Product {product_id} cannot be added to cart: {reason}",
            error_code="PRODUCT_NOT_AVAILABLE_FOR_CART",
            details={
                "product_id": product_id,
                "reason": reason,
            },
        )
