"""MessagingMixin — agent-to-agent messaging, A2A protocol, and mailbox operations."""
from __future__ import annotations

from typing import Any
from uuid import uuid4

from logos_adk.a2a import A2ARequest, A2AResponse
from logos_adk.topology import validate_send


class MessagingMixin:
    """Agent-to-agent messaging, A2A protocol, and mailbox operations."""

    async def send(self, from_agent: str, to_agent: str, message: Any) -> None:
        """Send a message from one agent to another within the team.

        Raises:
            RoutingError: If the topology does not allow the send.
        """
        validate_send(from_agent, to_agent, self._topology)
        await self._mailboxes[to_agent].put(message)

    async def broadcast(self, from_agent: str, message: Any) -> None:
        """Broadcast a message from one agent to all allowed targets."""
        allowed = self._topology.get(from_agent, set())
        for target in sorted(allowed):
            await self._mailboxes[target].put(message)

    async def request_a2a(
        self,
        from_agent: str,
        to_agent: str,
        task: str,
        *,
        metadata: dict[str, Any] | None = None,
        conversation_id: str | None = None,
    ) -> A2AResponse:
        """Send a typed A2A request and wait for the protocol response."""
        validate_send(from_agent, to_agent, self._topology)
        validate_send(to_agent, from_agent, self._topology)
        request = A2ARequest(
            from_agent=from_agent,
            to_agent=to_agent,
            content=task,
            conversation_id=conversation_id or uuid4().hex,
            metadata=metadata or {},
            expects_response=True,
        )
        await self._mailboxes[to_agent].put(request)
        await self.run_rounds()
        response = self._pending_a2a_responses.pop(request.task_id, None)
        if response is None:
            raise RuntimeError(
                f"A2A request '{request.task_id}' from '{from_agent}' to '{to_agent}' did not produce a response"
            )
        return response

    def _build_a2a_prompt(self, request: A2ARequest) -> str:
        parts = [
            f"A2A request from agent '{request.from_agent}':",
            request.content,
        ]
        if request.metadata:
            parts.append(f"Metadata: {request.metadata}")
        return "\n\n".join(parts)

    def _serialize_a2a_response(self, response: A2AResponse) -> dict[str, Any]:
        return {
            "from_agent": response.from_agent,
            "to_agent": response.to_agent,
            "content": response.content,
            "conversation_id": response.conversation_id,
            "message_id": response.message_id,
        }
