"""Schemas Pydantic pour l'API Produits."""
from __future__ import annotations

from datetime import datetime
from enum import Enum
from typing import Generic, TypeVar

from pydantic import BaseModel, Field, field_validator

T = TypeVar("T")


class CategoryEnum(str, Enum):
    ELECTRONIQUE = "electronique"
    VETEMENT = "vetement"
    ALIMENTAIRE = "alimentaire"
    SPORT = "sport"
    MAISON = "maison"


class ProductCreate(BaseModel):
    name: str = Field(..., min_length=2, max_length=100, description="Nom du produit")
    price: float = Field(..., gt=0, description="Prix en euros")
    stock: int = Field(..., ge=0, description="Quantité en stock")
    category: CategoryEnum
    description: str | None = Field(None, max_length=500)

    @field_validator("name")
    @classmethod
    def name_title_case(cls, v: str) -> str:
        return v.strip().title()


class ProductUpdate(BaseModel):
    name: str | None = Field(None, min_length=2, max_length=100)
    price: float | None = Field(None, gt=0)
    stock: int | None = Field(None, ge=0)
    category: CategoryEnum | None = None
    description: str | None = None

    @field_validator("name")
    @classmethod
    def name_title_case(cls, v: str | None) -> str | None:
        return v.strip().title() if v else v


class ProductResponse(BaseModel):
    id: int
    name: str
    price: float
    stock: int
    category: CategoryEnum
    description: str | None
    created_at: datetime
    updated_at: datetime | None

    model_config = {"from_attributes": True}


class PaginatedResponse(BaseModel, Generic[T]):
    """Réponse paginée générique — fonctionne avec n'importe quel type T."""
    items: list[T]
    total: int
    page: int
    limit: int
    pages: int
    has_next: bool
    has_prev: bool

    @classmethod
    def create(cls, items: list[T], total: int, page: int, limit: int) -> PaginatedResponse[T]:
        import math
        pages = math.ceil(total / limit) if total > 0 else 1
        return cls(
            items=items,
            total=total,
            page=page,
            limit=limit,
            pages=pages,
            has_next=page < pages,
            has_prev=page > 1,
        )
