from pydantic import BaseModel, ConfigDict, Field, field_validator
from typing import Optional
from datetime import datetime
from decimal import Decimal


class CartBase(BaseModel):
    user_id: str


class CartCreate(CartBase):
    pass


class CartUpdate(BaseModel):
    user_id: Optional[str] = None


class CartResponse(CartBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CartitemBase(BaseModel):
    cart_id: str
    listing_id: str
    quantity: int
    price_snapshot: Decimal


class CartitemCreate(CartitemBase):
    @field_validator("quantity")
    @classmethod
    def validate_quantity(cls, v: int) -> int:
        if v < 1 or v > 999:
            raise ValueError("Quantity must be between 1 and 999")
        return v

    @field_validator("price_snapshot")
    @classmethod
    def validate_price_snapshot(cls, v: Decimal) -> Decimal:
        if v <= 0:
            raise ValueError("Price snapshot must be greater than 0")
        return v


class CartitemUpdate(BaseModel):
    cart_id: Optional[str] = None
    listing_id: Optional[str] = None
    quantity: Optional[int] = None
    price_snapshot: Optional[Decimal] = None

    @field_validator("quantity")
    @classmethod
    def validate_quantity(cls, v: Optional[int]) -> Optional[int]:
        if v is not None and (v < 1 or v > 999):
            raise ValueError("Quantity must be between 1 and 999")
        return v

    @field_validator("price_snapshot")
    @classmethod
    def validate_price_snapshot(cls, v: Optional[Decimal]) -> Optional[Decimal]:
        if v is not None and v <= 0:
            raise ValueError("Price snapshot must be greater than 0")
        return v


class CartitemResponse(CartitemBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class WishlistBase(BaseModel):
    user_id: str
    name: str
    is_public: bool = False


class WishlistCreate(WishlistBase):
    pass


class WishlistUpdate(BaseModel):
    user_id: Optional[str] = None
    name: Optional[str] = None
    is_public: Optional[bool] = None


class WishlistResponse(WishlistBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class WishlistitemBase(BaseModel):
    wishlist_id: str
    card_id: str
    price_alert_threshold: Optional[Decimal] = None
    notes: Optional[str] = None


class WishlistitemCreate(WishlistitemBase):
    @field_validator("price_alert_threshold")
    @classmethod
    def validate_price_alert_threshold(cls, v: Optional[Decimal]) -> Optional[Decimal]:
        if v is not None and v <= 0:
            raise ValueError("Price alert threshold must be greater than 0")
        return v


class WishlistitemUpdate(BaseModel):
    wishlist_id: Optional[str] = None
    card_id: Optional[str] = None
    price_alert_threshold: Optional[Decimal] = None
    notes: Optional[str] = None

    @field_validator("price_alert_threshold")
    @classmethod
    def validate_price_alert_threshold(cls, v: Optional[Decimal]) -> Optional[Decimal]:
        if v is not None and v <= 0:
            raise ValueError("Price alert threshold must be greater than 0")
        return v


class WishlistitemResponse(WishlistitemBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CartDetailListingResponse(BaseModel):
    id: str
    title: str
    price: Decimal

    model_config = ConfigDict(from_attributes=True)


class CartDetailCardResponse(BaseModel):
    id: str
    name: str

    model_config = ConfigDict(from_attributes=True)


class CartDetailSellerResponse(BaseModel):
    id: str
    email: str

    model_config = ConfigDict(from_attributes=True)


class CartDetailItemResponse(BaseModel):
    id: str
    quantity: int
    price_snapshot: Decimal
    listing: CartDetailListingResponse

    model_config = ConfigDict(from_attributes=True)


class CartDetailResponse(BaseModel):
    id: str
    user_id: str
    cart_items: list[CartDetailItemResponse]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class WishlistDetailCardSetResponse(BaseModel):
    id: str
    name: str

    model_config = ConfigDict(from_attributes=True)


class WishlistDetailCardResponse(BaseModel):
    id: str
    name: str
    card_set: WishlistDetailCardSetResponse

    model_config = ConfigDict(from_attributes=True)


class WishlistDetailItemResponse(BaseModel):
    id: str
    card: WishlistDetailCardResponse
    price_alert_threshold: Optional[Decimal]
    notes: Optional[str]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class WishlistDetailResponse(BaseModel):
    id: str
    user_id: str
    name: str
    is_public: bool
    wishlist_items: list[WishlistDetailItemResponse]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)