# =============================================================================
# 企微IT智能服务台 — 消息 Pydantic Schema
# =============================================================================
# 说明：定义消息相关的请求/响应数据结构
# 支持消息类型：文本(text)/图片(image)/文件(file)/系统(system)
# =============================================================================

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

from pydantic import BaseModel, Field, field_validator


# --------------------------------------------------------------------------
# 消息类型和发送者类型的合法值
# --------------------------------------------------------------------------
VALID_MSG_TYPES = {"text", "image", "file", "system"}
VALID_SENDER_TYPES = {"employee", "agent", "ai", "system"}


# --------------------------------------------------------------------------
# 创建消息 Schema（坐席发送消息时使用）
# --------------------------------------------------------------------------
class MessageCreate(BaseModel):
    """创建消息请求 Schema。

    坐席发送消息时使用。
    支持文本消息和文件/图片消息。

    Attributes:
        content: 消息内容（文本消息为正文，文件消息为文件URL或描述）
        msg_type: 消息类型（默认 text，支持 image/file）
        media_url: 媒体文件URL（图片/文件消息时使用）
        file_name: 文件名（文件消息时使用）
        file_size: 文件大小（字节，文件消息时使用）
    """

    content: str = Field(..., min_length=1, description="消息内容")
    # 支持文本、图片、文件类型
    msg_type: str = Field(default="text", description="消息类型: text/image/file")
    # M1 新增：文件上传相关字段
    media_url: Optional[str] = Field(None, description="媒体文件URL（图片/文件消息时使用）")
    file_name: Optional[str] = Field(None, description="文件名")
    file_size: Optional[int] = Field(None, description="文件大小（字节）")
    # M1 新增：引用回复
    reply_to_id: Optional[str] = Field(None, description="引用回复：被回复的消息ID")

    @field_validator("msg_type")
    @classmethod
    def validate_msg_type(cls, v: str) -> str:
        """校验消息类型是否合法。"""
        if v not in VALID_MSG_TYPES:
            raise ValueError(f"无效的消息类型: {v}，合法值为: {VALID_MSG_TYPES}")
        return v


# --------------------------------------------------------------------------
# 企微回调消息 Schema（从企微接收到的消息）
# --------------------------------------------------------------------------
class WecomInboundMessage(BaseModel):
    """企微回调消息 Schema。

    解析企微回调 XML 后得到的结构化消息。

    Attributes:
        from_user_id: 发送者企微UserID
        content: 消息内容
        msg_type: 消息类型（text/image等）
        create_time: 消息创建时间戳
        agent_id: 应用AgentID
    """

    from_user_id: str = Field(..., description="发送者企微UserID")
    content: str = Field(default="", description="消息内容")
    msg_type: str = Field(default="text", description="消息类型")
    create_time: Optional[int] = Field(None, description="消息创建时间戳")
    agent_id: Optional[str] = Field(None, description="应用AgentID")


# --------------------------------------------------------------------------
# 消息响应 Schema（返回给前端的数据结构）
# --------------------------------------------------------------------------
class MessageResponse(BaseModel):
    """消息响应 Schema。

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

    Attributes:
        id: 消息ID
        conversation_id: 所属会话ID
        sender_type: 发送者类型
        sender_id: 发送者ID
        sender_name: 发送者姓名
        content: 消息内容
        msg_type: 消息类型
        media_url: 媒体文件URL
        file_name: 文件名
        file_size: 文件大小
        extra_data: 扩展元数据
        ai_suggestion: 是否为AI建议
        is_read: 是否已读
        created_at: 创建时间
    """

    id: str
    conversation_id: str
    sender_type: str
    sender_id: str
    sender_name: str
    content: str
    msg_type: str
    # M1 新增：媒体/文件相关字段
    media_url: Optional[str] = None
    file_name: Optional[str] = None
    file_size: Optional[int] = None
    extra_data: Optional[Dict[str, Any]] = None
    # M1 新增：引用回复
    reply_to_id: Optional[str] = None
    ai_suggestion: bool
    is_read: bool
    created_at: datetime
    # M2 新增：消息状态和可撤回时间
    status: str = "sent"
    recallable_until: Optional[datetime] = None

    model_config = {"from_attributes": True}


# --------------------------------------------------------------------------
# 消息列表响应 Schema
# --------------------------------------------------------------------------
class MessageListResponse(BaseModel):
    """消息列表响应 Schema。

    包含消息列表和是否还有更多消息的标志，
    用于向上加载历史消息。

    Attributes:
        items: 消息列表
        has_more: 是否还有更多历史消息
    """

    items: List[MessageResponse]
    has_more: bool
