"""
推送接口通用schema

## 响应相关
1. BaseResponseSchema: 所有接口响应的基础schema
2. BasePushResponseSchema: 推送接口响应的基础schema，包含push_id
3. PushResultSchema: 查询推送结果的schema

## 请求相关
4. BaseCreateRequestSchema[T]: 创建资源的基础请求schema（泛型），业务数据在data字段
5. BaseUpdateRequestSchema[T]: 更新资源的基础请求schema（泛型），业务数据在data字段
6. BaseDeleteRequestSchema: 删除资源的基础请求schema，只需resource_id
7. BulkPushRequestSchema: 批量推送请求的schema

## 说明
- 所有元数据字段（timestamp, nonce, signature, uid, push_id）在请求体最外层
- push_id使用UUIDv7格式，支持时间排序，同时作为幂等键和查询键
- 业务数据嵌套在data字段中（删除操作除外，只需resource_id）
- 所有业务Schema必须继承BasePushData，确保包含project_type字段
- resource_id在外层，用于标识要操作的资源（更新/删除时必填）
- 使用泛型T可快速定义各业务的请求schema，T必须继承BasePushData
"""

from pydantic import BaseModel, Field
from typing import TypeVar, Generic, Optional, List, Dict, Any
from ..project.enums import ProjectType
from datetime import datetime
# from backend.modules.admin.approval.models import ApprovalStep


class ApprovalStep(BaseModel):
    """审批流程中的一个步骤"""
    step_id: str = Field(description="步骤的唯一ID")
    operator_id: Optional[str] = Field("",description="操作人ID")
    operator_name: str = Field(description="操作人姓名")
    action: str = Field(description="执行的动作，如 'submit', 'approve', 'reject'")
    comment: Optional[str] = Field(None, description="审批意见")
    created_at: datetime = Field(default_factory=datetime.utcnow, description="步骤的创建时间")
# 定义泛型
T = TypeVar('T', bound='BasePushData')

# ==================== 业务数据基类 ====================

class BasePushData(BaseModel):
    """
    所有推送业务数据的基类
    
    所有业务Schema必须继承此类，确保包含project_type字段
    """
    project_type: ProjectType = Field(..., description="项目类型：offshore_wind/pumped_storage/photovoltaic等")


# ==================== Mixin ====================

class SignatureMixin(BaseModel):
    """签名字段混入"""
    timestamp: int = Field(..., description="毫秒级 Unix 时间戳")
    nonce: str = Field(..., description="随机字符串，防止重放攻击")
    sign: str = Field(..., description="签名字符串")
    uid: str = Field(..., description="集团侧用户id")


class PushRequestMixin(BaseModel):
    """推送ID字段混入"""
    push_id: str = Field(..., description="推送ID，客户端生成的唯一标识（UUIDv7，支持时间排序）")
    steps : List[ApprovalStep] =Field(default_factory=list,description="当前数据的审批流程步骤") # 加入字段step用来记录审批流程

# ==================== 响应相关 ====================

class BaseResponseSchema(BaseModel):
    """所有接口响应的基础schema"""
    code: int = 200
    message: Optional[str] = "OK"
    data: Optional[T] = None


class BasePushResponseSchema(BaseModel):
    """推送接口响应的基础schema"""
    biz_id: str | None = Field(None, description="资源ID（create操作成功后返回新创建的ID，update/delete返回原ID）")


class PushResultSchema(BaseModel):
    """查询推送结果的schema"""
    push_id: str = Field(..., description="推送ID（客户端生成的UUIDv7）")
    status: str = Field(..., description="推送状态：queued/processing/success/failed")
    result: Dict[str, Any] | None = Field(None, description="处理结果（成功时包含created_id等信息）")
    error: str | None = Field(None, description="错误信息（失败时）")
    created_at: str = Field(..., description="推送创建时间（ISO 8601格式）")
    updated_at: str = Field(..., description="推送更新时间（ISO 8601格式）")


class PushIdsSchema(BaseModel):
    """支持从请求体接收的 push_ids 列表字符串（逗号拼接）"""
    push_ids: Optional[str] = Field(None, description="推送id字符串逗号拼接")


# ==================== 请求相关 ====================

class BaseCreateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]):
    """
    创建资源的基础请求schema（泛型）
    
    泛型T必须继承BasePushData，确保包含project_type字段
    
    使用示例:
        class ProjectInputSchema(BasePushData):
            name: str = Field(...)
            capacity: float = Field(...)
        
        class ProjectCreateRequest(BaseCreateRequestSchema[ProjectInputSchema]):
            pass
    """
    # 业务数据（嵌套）
    data: T = Field(..., description="业务数据")


class BaseUpdateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]):
    """
    更新资源的基础请求schema（泛型）
    
    泛型T必须继承BasePushData，确保包含project_type字段
    resource_id在外层，用于标识要更新的资源
    
    使用示例:
        class ProjectInputSchema(BasePushData):
            name: str = Field(...)
            capacity: float = Field(...)
        
        class ProjectUpdateRequest(BaseUpdateRequestSchema[ProjectInputSchema]):
            pass
    """
    # 资源标识
    biz_id: str = Field(..., description="要更新的资源ID,类型id,如project传project_id,unit传unit_id")
    
    # 业务数据（嵌套）
    data: T = Field(..., description="业务数据（只需包含要更新的字段）")


class BaseDeleteRequestSchema(SignatureMixin, PushRequestMixin, BaseModel):
    """
    删除资源的基础请求schema
    
    使用示例:
        class ProjectDeleteRequest(BaseDeleteRequestSchema):
            pass
    """

    # 资源标识
    biz_id: str = Field(..., description="要删除的资源ID")


class BulkPushItem(PushRequestMixin, BaseModel):
    """
    批量推送中的单个项目
    
    注意：
    - action为create时：data必填，resource_id留空
    - action为update时：data和resource_id都必填
    - action为delete时：resource_id必填，data留空
    - data必须继承BasePushData，确保包含project_type字段
    """
    action: str = Field(..., description="操作类型：create/update/delete")
    resource_id: str | None = Field(None, description="资源ID（update/delete时必填，create时留空）")
    data: BasePushData | None = Field(None, description="业务数据（create/update时必填，delete时留空，必须包含project_type字段）")


class BulkPushItemResult(BaseModel):
    """批量推送中单个项目的处理结果"""
    push_id: str = Field(..., description="推送ID（对应请求中的push_id）")
    status: str = Field(..., description="处理状态：queued/processing/success/failed")
    resource_id: str | None = Field(None, description="资源ID（create成功时返回新ID，update/delete返回原ID）")
    error: str | None = Field(None, description="错误信息（失败时）")


class BulkPushRequestSchema(SignatureMixin, BaseModel):
    """
    批量推送请求的schema
    
    一次请求可推送多条数据，每条都有独立的幂等键和操作类型
    """
    # 批量数据
    items: List[BulkPushItem] = Field(..., description="批量推送的数据列表")


class BulkPushResponseSchema(BaseResponseSchema):
    """批量推送响应的schema"""
    batch_id: str = Field(..., description="批量推送的批次ID")
    total: int = Field(..., description="总数量")
    results: List[BulkPushItemResult] = Field(..., description="每条数据的处理结果，包含push_id和resource_id")
