from __future__ import annotations

import time
import uuid
from typing import Any, Dict, List

from .types import GroupInfoPayload, MessageEnvelope, MessageInfoPayload, SegPayload, UserInfoPayload


class MessageBuilder:
    """
    流式构建 MessageEnvelope 的助手工具，提供类型安全的构建方法。

    使用示例:
        msg = (
            MessageBuilder()
            .text("Hello")
            .image("http://example.com/1.png")
            .to_user("123", platform="qq")
            .build()
        )
    """

    def __init__(self) -> None:
        self._direction: str = "outgoing"
        self._message_info: MessageInfoPayload = {}
        self._segments: List[SegPayload] = []
        self._metadata: Dict[str, Any] | None = None
        self._timestamp_ms: int | None = None
        self._message_id: str | None = None

    def direction(self, value: str) -> "MessageBuilder":
        self._direction = value
        return self

    def message_id(self, value: str) -> "MessageBuilder":
        self._message_id = value
        return self

    def timestamp_ms(self, value: int | None = None) -> "MessageBuilder":
        self._timestamp_ms = value or int(time.time() * 1000)
        return self

    def metadata(self, value: Dict[str, Any]) -> "MessageBuilder":
        self._metadata = value
        return self

    def platform(self, value: str) -> "MessageBuilder":
        self._message_info["platform"] = value
        return self

    def from_user(self, user_id: str, *, platform: str | None = None, nickname: str | None = None, cardname: str | None = None, user_avatar: str | None = None) -> "MessageBuilder":
        if platform:
            self.platform(platform)
        user_info: UserInfoPayload = {"user_id": user_id}
        if nickname:
            user_info["user_nickname"] = nickname
        if cardname:
            user_info["user_cardname"] = cardname
        if user_avatar:
            user_info["user_avatar"] = user_avatar
        self._message_info["user_info"] = user_info
        return self

    def from_group(self, group_id: str, *, platform: str | None = None, name: str | None = None) -> "MessageBuilder":
        if platform:
            self.platform(platform)
        group_info: GroupInfoPayload = {"group_id": group_id}
        if name:
            group_info["group_name"] = name
        self._message_info["group_info"] = group_info
        return self

    def seg(self, type_: str, data: Any) -> "MessageBuilder":
        self._segments.append({"type": type_, "data": data})
        return self

    def text(self, content: str) -> "MessageBuilder":
        return self.seg("text", content)

    def image(self, url: str) -> "MessageBuilder":
        return self.seg("image", url)

    def reply(self, target_message_id: str) -> "MessageBuilder":
        return self.seg("reply", target_message_id)

    def raw_segment(self, segment: SegPayload) -> "MessageBuilder":
        self._segments.append(segment)
        return self

    def format_info(self, content_format: List[str], accept_format: List[str]) -> "MessageBuilder":
        self._message_info["format_info"] = {
            "content_format": content_format,
            "accept_format": accept_format,
        }
        return self

    def seg_list(self, segments: List[SegPayload]) -> "MessageBuilder":
        self._segments.extend(segments)
        return self
    
    def build(self) -> MessageEnvelope:
        """构建最终的消息信封"""
        # 设置 message_info 默认值
        if not self._segments:
            raise ValueError("需要至少添加一个消息段才能构建消息")
        if self._message_id is None:
            self._message_id = str(uuid.uuid4())
        info = self._message_info
        info.setdefault("message_id", self._message_id)
        info.setdefault("time", time.time())
        # 检查是否有group_info，并检查group_info中是否有platform
        if "group_info" in info.keys():
            group_info: GroupInfoPayload = info["group_info"]
            if "platform" in info and group_info.get("platform") is None:
                info["group_info"]["platform"] = info["platform"]
        
        # 检查是否有user_info，并检查user_info中是否有platform
        if "user_info" in info.keys():
            user_info: UserInfoPayload = info["user_info"] 
            if "platform" in info and user_info.get("platform") is None:
                info["user_info"]["platform"] = info["platform"]

        segments = [seg.copy() if isinstance(seg, dict) else seg for seg in self._segments]
        envelope: MessageEnvelope = {
            "direction": self._direction,  # type: ignore[assignment]
            "message_info": info,
            "message_segment": segments[0] if len(segments) == 1 else list(segments),
        }
        if self._metadata is not None:
            envelope["metadata"] = self._metadata
        if self._timestamp_ms is not None:
            envelope["timestamp_ms"] = self._timestamp_ms
        return envelope


__all__ = ["MessageBuilder"]
