from datetime import datetime
from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field

CycleLiteral = Literal[
    "hourly",
    "daily",
    "monthly",
    "quarterly",
    "semi_annually",
    "annually",
    "biennially",
    "triennially",
    "one_time",
]

ProductTypeLiteral = Literal["server", "hosting", "domain", "ssl", "license", "other"]
ProductStatusLiteral = Literal["draft", "active", "hidden", "deprecated"]
StockPolicyLiteral = Literal["unlimited", "tracked"]
ApiTypeLiteral = Literal["none", "dcim_cloud_image", "dcim_cloud_rid", "zjmf_finance", "plugin"]


class ProductPricingItem(BaseModel):
    cycle: CycleLiteral
    price: float = Field(..., ge=0, description="单位：元")
    original_price: float | None = Field(None, ge=0)
    setup_fee: float = Field(0, ge=0)
    is_enabled: bool = True
    sort_order: int = 0


class ProductPricingResponse(ProductPricingItem):
    model_config = ConfigDict(from_attributes=True)
    id: int


class ProductCreate(BaseModel):
    group_id: int
    sku: str = Field(..., min_length=1, max_length=64)
    name: str = Field(..., min_length=1, max_length=150)

    type: ProductTypeLiteral = "server"
    status: ProductStatusLiteral = "draft"

    vcpu: int | None = Field(None, ge=0, le=1024)
    cpu_model: str | None = Field(None, max_length=64)
    cpu_base_mhz: int | None = Field(None, ge=0, le=100000)
    cpu_turbo_mhz: int | None = Field(None, ge=0, le=100000)
    memory: str | None = Field(None, max_length=64)
    disk: str | None = Field(None, max_length=64)
    bandwidth: str | None = Field(None, max_length=64)

    features: str | None = None
    badges: str | None = None

    base_setup_fee: float = Field(0, ge=0)
    base_price: float = Field(0, ge=0)

    stock_policy: StockPolicyLiteral = "unlimited"
    stock: int = Field(0, ge=0)

    min_quantity: int = Field(1, ge=1)
    max_quantity: int = Field(0, ge=0)

    auto_provision: bool = False
    trial_enabled: bool = False
    trial_days: int = Field(0, ge=0)

    sort_order: int = 0
    is_featured: bool = False
    requires_real_name: bool = False

    cloud_server_id: int | None = None
    api_type: ApiTypeLiteral = "none"
    api_identifier: str | None = Field(None, max_length=128)
    provision_interface_id: int | None = None

    provision_config: list[Any] | None = None

    pricings: list[ProductPricingItem] = Field(default_factory=list)


class ProductUpdate(BaseModel):
    group_id: int | None = None
    sku: str | None = Field(None, min_length=1, max_length=64)
    name: str | None = Field(None, min_length=1, max_length=150)

    type: ProductTypeLiteral | None = None
    status: ProductStatusLiteral | None = None

    vcpu: int | None = Field(None, ge=0, le=1024)
    cpu_model: str | None = Field(None, max_length=64)
    cpu_base_mhz: int | None = Field(None, ge=0, le=100000)
    cpu_turbo_mhz: int | None = Field(None, ge=0, le=100000)
    memory: str | None = Field(None, max_length=64)
    disk: str | None = Field(None, max_length=64)
    bandwidth: str | None = Field(None, max_length=64)

    features: str | None = None
    badges: str | None = None

    base_setup_fee: float | None = Field(None, ge=0)
    base_price: float | None = Field(None, ge=0)

    stock_policy: StockPolicyLiteral | None = None
    stock: int | None = Field(None, ge=0)

    min_quantity: int | None = Field(None, ge=1)
    max_quantity: int | None = Field(None, ge=0)

    auto_provision: bool | None = None
    trial_enabled: bool | None = None
    trial_days: int | None = Field(None, ge=0)

    sort_order: int | None = None
    is_featured: bool | None = None
    requires_real_name: bool | None = None

    cloud_server_id: int | None = None
    api_type: ApiTypeLiteral | None = None
    api_identifier: str | None = Field(None, max_length=128)
    provision_interface_id: int | None = None

    provision_config: list[Any] | None = None

    pricings: list[ProductPricingItem] | None = None


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

    id: int
    group_id: int
    sku: str
    name: str
    type: str
    status: str

    vcpu: int | None
    cpu_model: str | None
    cpu_base_mhz: int | None
    cpu_turbo_mhz: int | None
    memory: str | None
    disk: str | None
    bandwidth: str | None

    features: str | None
    badges: str | None

    base_setup_fee: float
    base_price: float

    stock_policy: str
    stock: int

    min_quantity: int
    max_quantity: int

    auto_provision: bool
    trial_enabled: bool
    trial_days: int

    sort_order: int
    is_featured: bool
    requires_real_name: bool

    cloud_server_id: int | None
    api_type: str
    api_identifier: str | None
    provision_interface_id: int | None = None
    provision_config: list[Any] | None
    provision_plugin: dict[str, Any] | None = None
    provision_interface: dict[str, Any] | None = None
    product_page: dict[str, Any] | None = None

    pricings: list[ProductPricingResponse] = Field(default_factory=list)

    created_at: datetime
    updated_at: datetime


class CloudResourceItem(BaseModel):
    """上游列出来的镜像/区域/资源包条目，统一格式给前端。"""

    id: str
    label: str
    extra: str | None = None


class ProvisionInterfaceBase(BaseModel):
    name: str = Field(..., min_length=1, max_length=120)
    plugin_id: str = Field(..., min_length=1, max_length=80)
    config: dict[str, Any] = Field(default_factory=dict)
    enabled: bool = True
    sort_order: int = 0
    remark: str | None = None


class ProvisionInterfaceCreate(ProvisionInterfaceBase):
    pass


class ProvisionInterfaceUpdate(BaseModel):
    name: str | None = Field(None, min_length=1, max_length=120)
    plugin_id: str | None = Field(None, min_length=1, max_length=80)
    config: dict[str, Any] | None = None
    enabled: bool | None = None
    sort_order: int | None = None
    remark: str | None = None


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

    id: int
    name: str
    plugin_id: str
    plugin_name: str | None = None
    config: dict[str, Any] = Field(default_factory=dict)
    enabled: bool
    sort_order: int
    remark: str | None = None
    last_test_ok: bool | None = None
    last_test_message: str | None = None
    created_at: datetime
    updated_at: datetime
