import json
from dataclasses import dataclass, asdict
from typing import Optional, Dict, Any


@dataclass
class PlatformMessage:
    """规范消息结构体 - 严格按照WebSocket文档v2格式"""
    # 必填字段
    type: str  # 消息类型："message" | "staff_list" | "ping" | "pong" | "transfer" | "connect_success" | "error"

    # 条件必填字段（根据消息类型）
    content: Optional[str] = None  # 消息内容
    msg_type: Optional[str] = None  # 消息实际类型："text" | "image" | "video" | "product_card" | "order_card"
    pin_image: Optional[str] = None  # 用户头像URL
    sender: Optional[Dict] = None  # 发送者信息，必须包含id字段
    store_id: Optional[str] = None  # 店铺ID

    # 可选字段
    receiver: Optional[Dict] = None  # 接收者信息
    data: Optional[Dict] = None  # 扩展数据（如客服列表、验证链接等）
    uuid: Optional[str] = None  # 心跳包UUID
    token: Optional[str] = None  # 认证令牌（心跳包可能需要）

    def __post_init__(self):
        """初始化后处理"""
        # 自动设置msg_type（仅对message类型）
        if self.type == "message" and self.msg_type is None and self.content:
            self.msg_type = self._detect_msg_type()

    def _detect_msg_type(self) -> str:
        """自动检测消息类型"""
        if not self.content:
            return "text"

        content = self.content.lower()

        # 图片检测
        if any(ext in content for ext in ['.jpg', '.jpeg', '.png', '.gif', '.webp']):
            return "image"

        # 视频检测
        if any(ext in content for ext in ['.mp4', '.avi', '.mov', '.wmv', '.flv']):
            return "video"

        # 订单卡片检测 - 支持多种格式
        if ("商品id：" in self.content and "订单号：" in self.content) or \
                ("商品ID：" in self.content and "订单号：" in self.content) or \
                ("咨询订单号：" in self.content and "商品ID：" in self.content):
            return "order_card"

        # 商品卡片检测
        if any(keyword in content for keyword in ['goods.html', 'item.html', 'item.jd.com', '商品卡片id：']):
            return "product_card"

        # 默认文本消息
        return "text"

    def to_json(self) -> str:
        """序列化为JSON字符串（用于存储）"""
        return json.dumps(self.to_dict(), ensure_ascii=False)

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典，过滤None值"""
        result = {}
        for key, value in asdict(self).items():
            if value is not None:
                result[key] = value
        return result

    @classmethod
    def from_json(cls, json_str: str):
        """从JSON字符串恢复结构体（用于读取）"""
        data = json.loads(json_str)
        return cls(**data)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        """从字典创建实例"""
        return cls(**data)

    @classmethod
    def create_text_message(cls, content: str, sender_id: str, store_id: str, pin_image: str = None):
        """创建文本消息"""
        return cls(
            type="message",
            content=content,
            msg_type="text",
            pin_image=pin_image,
            sender={"id": sender_id},
            store_id=store_id
        )

    @classmethod
    def create_image_message(cls, image_url: str, sender_id: str, store_id: str, pin_image: str = None):
        """创建图片消息"""
        return cls(
            type="message",
            content=image_url,
            msg_type="image",
            pin_image=pin_image,
            sender={"id": sender_id},
            store_id=store_id
        )

    @classmethod
    def create_video_message(cls, video_url: str, sender_id: str, store_id: str, pin_image: str = None):
        """创建视频消息"""
        return cls(
            type="message",
            content=video_url,
            msg_type="video",
            pin_image=pin_image,
            sender={"id": sender_id},
            store_id=store_id
        )

    @classmethod
    def create_order_card_message(cls, product_id: str, order_number: str, sender_id: str, store_id: str,
                                  pin_image: str = None):
        """创建订单卡片消息"""
        return cls(
            type="message",
            content=f"商品id：{product_id} 订单号：{order_number}",
            msg_type="order_card",
            pin_image=pin_image,
            sender={"id": sender_id},
            store_id=store_id
        )

    @classmethod
    def create_product_card_message(cls, product_url: str, sender_id: str, store_id: str, pin_image: str = None):
        """创建商品卡片消息"""
        return cls(
            type="message",
            content=product_url,
            msg_type="product_card",
            pin_image=pin_image,
            sender={"id": sender_id},
            store_id=store_id
        )

    @classmethod
    def create_staff_list_message(cls, staff_list: list, store_id: str):
        """创建客服列表消息"""
        return cls(
            type="staff_list",
            content="客服列表更新",
            data={"staff_list": staff_list},
            store_id=store_id
        )

    @classmethod
    def create_ping_message(cls, uuid_str: str, token: str = None):
        """创建心跳检测消息"""
        message = cls(
            type="ping",
            uuid=uuid_str
        )
        if token:
            message.token = token
        return message

    @classmethod
    def create_pong_message(cls, uuid_str: str):
        """创建心跳回复消息"""
        return cls(
            type="pong",
            uuid=uuid_str
        )