import uuid
from datetime import datetime
from decimal import Decimal
from typing import Any

from pydantic import BaseModel, ConfigDict, Field


class CategoryBase(BaseModel):
    title: str = Field(min_length=1, max_length=128)
    slug: str | None = Field(default=None, max_length=64)
    icon: str | None = Field(default=None, max_length=16)
    sort_order: int = 0
    enabled: bool = True


class CategoryCreate(CategoryBase):
    pass


class CategoryUpdate(BaseModel):
    title: str | None = Field(default=None, max_length=128)
    slug: str | None = Field(default=None, max_length=64)
    icon: str | None = Field(default=None, max_length=16)
    sort_order: int | None = None
    enabled: bool | None = None


class CategoryOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: uuid.UUID
    title: str
    slug: str
    icon: str | None = None
    sort_order: int
    enabled: bool


class ProductBase(BaseModel):
    category_id: uuid.UUID
    title: str = Field(min_length=1, max_length=160)
    slug: str | None = Field(default=None, max_length=96)
    description: str | None = None
    price: Decimal = Field(ge=0)
    discount_price: Decimal | None = Field(default=None, ge=0)
    currency: str = "IRT"
    flow: str
    icon: str | None = None
    image: str | None = None
    sort_order: int = 0
    enabled: bool = True
    data: dict[str, Any] = Field(default_factory=dict)


class ProductCreate(ProductBase):
    pass


class ProductUpdate(BaseModel):
    category_id: uuid.UUID | None = None
    title: str | None = Field(default=None, max_length=160)
    slug: str | None = Field(default=None, max_length=96)
    description: str | None = None
    price: Decimal | None = Field(default=None, ge=0)
    discount_price: Decimal | None = Field(default=None, ge=0)
    currency: str | None = None
    flow: str | None = None
    icon: str | None = None
    image: str | None = None
    sort_order: int | None = None
    enabled: bool | None = None
    data: dict[str, Any] | None = None


class ProductOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: uuid.UUID
    category_id: uuid.UUID
    title: str
    slug: str
    description: str | None = None
    price: Decimal
    discount_price: Decimal | None = None
    effective_price: Decimal
    currency: str
    flow: str
    icon: str | None = None
    image: str | None = None
    sort_order: int
    enabled: bool
    data: dict[str, Any]
    created_at: datetime


class CouponBase(BaseModel):
    code: str = Field(min_length=2, max_length=32)
    type: str = Field(default="percent", pattern="^(percent|fixed)$")
    value: Decimal = Field(gt=0)
    max_discount: Decimal | None = None
    minimum_order: Decimal = Decimal("0")
    usage_limit: int | None = None
    per_user_limit: int | None = None
    expires_at: datetime | None = None
    enabled: bool = True


class CouponCreate(CouponBase):
    pass


class CouponUpdate(BaseModel):
    code: str | None = None
    type: str | None = Field(default=None, pattern="^(percent|fixed)$")
    value: Decimal | None = None
    max_discount: Decimal | None = None
    minimum_order: Decimal | None = None
    usage_limit: int | None = None
    per_user_limit: int | None = None
    expires_at: datetime | None = None
    enabled: bool | None = None


class CouponOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: uuid.UUID
    code: str
    type: str
    value: Decimal
    max_discount: Decimal | None = None
    minimum_order: Decimal
    usage_limit: int | None = None
    per_user_limit: int | None = None
    used_count: int
    expires_at: datetime | None = None
    enabled: bool
    created_at: datetime
