#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：module.py
模块描述：测试模块 Pydantic 模式定义

作者：czj
创建日期：2026-07-09
最后修改：2026-07-09
"""

from datetime import datetime
from typing import Optional, List
from pydantic import BaseModel, Field, ConfigDict


def to_camel(string: str) -> str:
    """Convert snake_case to camelCase"""
    components = string.split('_')
    return components[0] + ''.join(x.title() for x in components[1:])


class ModuleBase(BaseModel):
    """
    模块基础模式

    包含模块的公共字段。
    """

    name: str = Field(..., min_length=1, max_length=100, description="模块名称")
    description: str = Field(default="", max_length=500, description="模块描述")
    icon: str = Field(default="folder", max_length=50, description="模块图标")
    module_type: str = Field(default="standard", description="模块类型: standard/custom")


class ModuleCreate(ModuleBase):
    """
    创建模块请求模式

    用于接收创建模块的请求数据。

    Example:
        >>> module_data = ModuleCreate(
        ...     name="登录模块",
        ...     description="用户登录相关功能测试"
        ... )
    """

    parent_id: Optional[str] = Field(None, description="父模块ID（支持层级结构）")


class ModuleUpdate(BaseModel):
    """
    更新模块请求模式

    用于接收更新模块的请求数据，所有字段可选。

    Example:
        >>> update_data = ModuleUpdate(name="新模块名称")
    """

    name: Optional[str] = Field(None, min_length=1, max_length=100, description="模块名称")
    description: Optional[str] = Field(None, max_length=500, description="模块描述")
    icon: Optional[str] = Field(None, max_length=50, description="模块图标")
    order: Optional[int] = Field(None, ge=0, description="排序序号")
    module_type: Optional[str] = Field(None, description="模块类型: standard/custom")
    parent_id: Optional[str] = Field(None, description="父模块ID（支持层级结构）")


class ModuleResponse(ModuleBase):
    """
    模块响应模式

    用于返回模块数据给客户端。
    序列化时自动转换为 camelCase 以匹配前端 TypeScript 类型。

    Attributes:
        id (str): 模块ID
        order (int): 排序序号
        created_at (datetime): 创建时间
        updated_at (datetime): 更新时间
        case_count (int): 用例数量（可选）
        pass_rate (float): 通过率（可选）
    """

    model_config = ConfigDict(
        from_attributes=True,
        alias_generator=to_camel,
        populate_by_name=True,
    )

    id: str = Field(..., description="模块ID")
    order: int = Field(default=0, description="排序序号")
    parent_id: Optional[str] = Field(default=None, description="父模块ID")
    created_at: Optional[datetime] = Field(None, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")

    # 扩展字段（通过关联查询填充）
    case_count: Optional[int] = Field(default=0, description="用例数量")
    pass_rate: Optional[float] = Field(default=0.0, description="通过率")
    children: Optional[List["ModuleResponse"]] = Field(default=None, description="子模块列表（树形结构）")


class ModuleListResponse(BaseModel):
    """
    模块列表响应模式

    用于返回分页的模块列表。

    Attributes:
        total (int): 总数
        items (List[ModuleResponse]): 模块列表
    """

    model_config = ConfigDict(
        alias_generator=to_camel,
        populate_by_name=True,
    )

    total: int = Field(..., description="总数")
    items: List[ModuleResponse] = Field(default_factory=list, description="模块列表")


# 递归模型重建（ModuleResponse.children 引用自身）
ModuleResponse.model_rebuild()