"""Message types for the Vastian inter-agent message bus."""

from __future__ import annotations

import uuid
from datetime import UTC, datetime
from enum import StrEnum

from pydantic import BaseModel, Field


class MessageType(StrEnum):
    """Classification of inter-agent messages."""

    TASK = "task"  # Assign work to an agent
    QUERY = "query"  # Ask an agent for information
    RESPONSE = "response"  # Reply to a query or task
    ESCALATION = "escalation"  # Can't handle — route up the chain
    STATUS_UPDATE = "status_update"  # Progress notification
    DOCUMENT_UPDATE = "document_update"  # An owned document was modified
    COUNCIL_CONVENE = "council_convene"  # Trigger a Mentor Council meeting
    COUNCIL_BRIEFING = "council_briefing"
    COUNCIL_CONTRIBUTION = "council_contribution"
    COUNCIL_SYNTHESIS = "council_synthesis"
    COUNCIL_ACTION = "council_action"  # Action item from council
    SYNC_REQUEST = "sync_request"  # Request a sync session
    BROADCAST = "broadcast"  # Network-wide announcement
    HEARTBEAT = "heartbeat"  # Agent health check


class Priority(StrEnum):
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    CRITICAL = "critical"


class Message(BaseModel):
    """A single message on the Vastian message bus."""

    id: str = Field(default_factory=lambda: uuid.uuid4().hex[:12])
    sender: str  # agent_id of sender
    recipient: str  # agent_id | team_id | "broadcast"
    type: MessageType
    payload: dict = Field(default_factory=dict)
    priority: Priority = Priority.NORMAL
    timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))
    thread_id: str | None = None  # conversation threading
    parent_id: str | None = None  # reply-to message id
    metadata: dict = Field(default_factory=dict)

    def reply(
        self, sender: str, payload: dict, msg_type: MessageType = MessageType.RESPONSE
    ) -> Message:
        """Create a reply message in the same thread."""
        return Message(
            sender=sender,
            recipient=self.sender,
            type=msg_type,
            payload=payload,
            priority=self.priority,
            thread_id=self.thread_id or self.id,
            parent_id=self.id,
        )
