# =============================================================================
# 企微IT智能服务台 — 排障模板 Pydantic Schema
# =============================================================================
# 说明：定义排障模板的 CRUD 数据结构
# 包含：创建、更新、响应 Schema
# =============================================================================

from datetime import datetime
from typing import Any, Dict, List, Optional

from pydantic import BaseModel, Field, field_validator


# --------------------------------------------------------------------------
# 排障模板分类合法值
# --------------------------------------------------------------------------
VALID_TEMPLATE_CATEGORIES = {"vpn", "email", "system", "account"}


# --------------------------------------------------------------------------
# 创建排障模板 Schema
# --------------------------------------------------------------------------
class TroubleshootingTemplateCreate(BaseModel):
    """创建排障模板请求 Schema。

    Attributes:
        name: 模板名称
        category: 分类（vpn/email/system/account）
        path_steps: 排障步骤路径
        flowchart: 流程图定义
        is_active: 是否启用
    """

    name: str = Field(..., min_length=1, max_length=256, description="模板名称")
    category: str = Field(default="system", description="分类: vpn/email/system/account")
    path_steps: List[Dict[str, Any]] = Field(
        default_factory=list, description="排障步骤路径"
    )
    flowchart: Dict[str, Any] = Field(
        default_factory=dict, description="流程图定义"
    )
    is_active: bool = Field(default=True, description="是否启用")

    @field_validator("category")
    @classmethod
    def validate_category(cls, v: str) -> str:
        """校验分类是否合法。"""
        if v not in VALID_TEMPLATE_CATEGORIES:
            raise ValueError(f"无效的分类: {v}，合法值为: {VALID_TEMPLATE_CATEGORIES}")
        return v


# --------------------------------------------------------------------------
# 更新排障模板 Schema
# --------------------------------------------------------------------------
class TroubleshootingTemplateUpdate(BaseModel):
    """更新排障模板请求 Schema。

    所有字段可选，只更新传入的字段。

    Attributes:
        name: 模板名称
        category: 分类
        path_steps: 排障步骤路径
        flowchart: 流程图定义
        is_active: 是否启用
    """

    name: Optional[str] = Field(None, max_length=256, description="模板名称")
    category: Optional[str] = Field(None, description="分类: vpn/email/system/account")
    path_steps: Optional[List[Dict[str, Any]]] = Field(None, description="排障步骤路径")
    flowchart: Optional[Dict[str, Any]] = Field(None, description="流程图定义")
    is_active: Optional[bool] = Field(None, description="是否启用")

    @field_validator("category")
    @classmethod
    def validate_category(cls, v: Optional[str]) -> Optional[str]:
        """校验分类是否合法。"""
        if v is not None and v not in VALID_TEMPLATE_CATEGORIES:
            raise ValueError(f"无效的分类: {v}，合法值为: {VALID_TEMPLATE_CATEGORIES}")
        return v


# --------------------------------------------------------------------------
# 排障模板响应 Schema
# --------------------------------------------------------------------------
class TroubleshootingTemplateResponse(BaseModel):
    """排障模板响应 Schema。

    返回给前端的排障模板数据结构。
    使用 from_attributes=True 支持从 SQLAlchemy 模型直接转换。

    Attributes:
        id: 模板唯一标识
        name: 模板名称
        category: 分类
        path_steps: 排障步骤路径
        flowchart: 流程图定义
        is_active: 是否启用
        created_at: 创建时间
        updated_at: 更新时间
    """

    id: str
    name: str
    category: str
    path_steps: List[Dict[str, Any]] = Field(default_factory=list, description="排障步骤路径")
    flowchart: Dict[str, Any] = Field(default_factory=dict, description="流程图定义")
    is_active: bool
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


# --------------------------------------------------------------------------
# 排障模板列表响应 Schema
# --------------------------------------------------------------------------
class TroubleshootingTemplateListResponse(BaseModel):
    """排障模板列表响应 Schema。

    Attributes:
        items: 排障模板列表
        total: 总数
    """

    items: List[TroubleshootingTemplateResponse]
    total: int
