"""AgentMessage — Agent 间通信消息模型。"""

from __future__ import annotations

import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Any


@dataclass
class AgentMessage:
    """Agent 间通信消息。

    支持点对点（recipient 非空）和广播（recipient 为 None）两种模式。
    通过 correlation_id 实现请求-响应关联。
    """

    message_id: str = field(default_factory=lambda: str(uuid.uuid4())[:12])
    sender: str = ""
    recipient: str | None = None  # None = broadcast
    topic: str = ""
    payload: dict[str, Any] = field(default_factory=dict)
    timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
    correlation_id: str | None = None  # 请求-响应关联
    # --- 新增字段 ---
    content: Any = None  # 消息内容（与 payload 互补，payload 为 dict，content 可为任意类型）
    msg_type: str = "notify"  # "request" | "response" | "notify" | "negotiate"
    ttl_seconds: int = 300  # 消息存活时间（秒）

    def is_expired(self) -> bool:
        """检查消息是否已过期。"""
        if isinstance(self.timestamp, datetime):
            age = (datetime.now(timezone.utc) - self.timestamp).total_seconds()
            return age > self.ttl_seconds
        return False

    @property
    def is_broadcast(self) -> bool:
        return self.recipient is None

    def to_dict(self) -> dict[str, Any]:
        ts = self.timestamp
        if isinstance(ts, datetime):
            ts = ts.isoformat()
        return {
            "message_id": self.message_id,
            "sender": self.sender,
            "recipient": self.recipient,
            "topic": self.topic,
            "payload": self.payload,
            "timestamp": ts,
            "correlation_id": self.correlation_id,
            "content": self.content,
            "msg_type": self.msg_type,
            "ttl_seconds": self.ttl_seconds,
        }

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> AgentMessage:
        ts = data.get("timestamp", "")
        if isinstance(ts, str) and ts:
            try:
                ts = datetime.fromisoformat(ts)
            except (ValueError, TypeError):
                pass  # keep as string if parse fails
        return cls(
            message_id=data.get("message_id", ""),
            sender=data.get("sender", ""),
            recipient=data.get("recipient"),
            topic=data.get("topic", ""),
            payload=data.get("payload", {}),
            timestamp=ts,
            correlation_id=data.get("correlation_id"),
            content=data.get("content"),
            msg_type=data.get("msg_type", "notify"),
            ttl_seconds=data.get("ttl_seconds", 300),
        )
