from datetime import datetime
from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field, field_validator


class ProductCategoryResponse(BaseModel):
    """嵌入到下拉里用的轻量结构。"""

    model_config = ConfigDict(from_attributes=True)
    id: int
    slug: str
    name: str
    description: str | None = None
    icon: str | None = None
    sort_order: int
    status: str
    is_featured: bool
    featured_label: str = "推荐"


class ProductCategoryCreate(BaseModel):
    slug: str = Field(..., min_length=1, max_length=64, pattern=r"^[a-z0-9][a-z0-9_-]*$")
    name: str = Field(..., min_length=1, max_length=100)
    description: str | None = None
    icon: str | None = Field(None, max_length=64)
    sort_order: int = 0
    status: Literal["active", "hidden"] = "active"
    is_featured: bool = False
    featured_label: str = Field("推荐", max_length=24)

    @field_validator("featured_label", mode="before")
    @classmethod
    def coerce_featured_label(cls, v: Any) -> str:
        if v is None:
            return "推荐"
        value = str(v).strip()
        return value or "推荐"


class ProductCategoryUpdate(BaseModel):
    name: str | None = Field(None, min_length=1, max_length=100)
    description: str | None = None
    icon: str | None = Field(None, max_length=64)
    sort_order: int | None = None
    status: Literal["active", "hidden"] | None = None
    is_featured: bool | None = None
    featured_label: str | None = Field(None, max_length=24)

    @field_validator("featured_label", mode="before")
    @classmethod
    def coerce_featured_label(cls, v: Any) -> str | None:
        if v is None:
            return None
        value = str(v).strip()
        return value or "推荐"


class ProductGroupCreate(BaseModel):
    category_id: int
    parent_id: int | None = None
    slug: str = Field(..., min_length=1, max_length=64, pattern=r"^[a-z0-9][a-z0-9_-]*$")
    name: str = Field(..., min_length=1, max_length=100)
    headline: str | None = Field(None, max_length=200)
    description: str | None = None
    icon: str | None = Field(None, max_length=64)
    network_type: str | None = Field(None, max_length=32)
    sort_order: int = 0
    requires_real_name: bool = False
    area: int | None = None
    node: int | None = None
    os_options: list[Any] = Field(default_factory=list)


class ProductGroupUpdate(BaseModel):
    category_id: int | None = None
    parent_id: int | None = None
    name: str | None = Field(None, min_length=1, max_length=100)
    headline: str | None = Field(None, max_length=200)
    description: str | None = None
    icon: str | None = Field(None, max_length=64)
    network_type: str | None = Field(None, max_length=32)
    sort_order: int | None = None
    requires_real_name: bool | None = None
    area: int | None = None
    node: int | None = None
    os_options: list[Any] | None = None


class ProductGroupOsOptionsPageUpdate(BaseModel):
    offset: int = Field(0, ge=0)
    limit: int = Field(20, ge=1, le=200)
    items: list[Any] = Field(default_factory=list)


class ProductGroupVerificationRuleUpdate(BaseModel):
    requires_real_name: bool
    apply_to_products: bool = True


class ProductGroupResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: int
    category_id: int
    parent_id: int | None
    slug: str
    name: str
    headline: str | None
    description: str | None
    icon: str | None
    network_type: str | None
    sort_order: int
    requires_real_name: bool
    area: int | None
    node: int | None
    os_options: list[Any] = Field(default_factory=list)
    created_at: datetime
    updated_at: datetime

    @field_validator("os_options", mode="before")
    @classmethod
    def coerce_os_options(cls, v: Any) -> list:
        return v if isinstance(v, list) else []
