"""In-memory channel adapter for tests and local gateway embedding."""

from __future__ import annotations

from typing import Any

from beaver.foundation.events import InboundMessage, MessageBus, OutboundMessage


class MemoryChannelAdapter:
    """A local channel that stores outbound messages in memory."""

    def __init__(self, bus: MessageBus, *, name: str = "memory") -> None:
        self.name = name
        self.bus = bus
        self.started = False
        self.sent_messages: list[OutboundMessage] = []

    async def start(self) -> None:
        self.started = True

    async def stop(self) -> None:
        self.started = False

    async def send(self, message: OutboundMessage) -> None:
        self.sent_messages.append(message)

    async def publish_text(
        self,
        content: str,
        *,
        session_id: str | None = None,
        user_id: str | None = None,
        title: str | None = None,
        execution_context: str | None = None,
        model: str | None = None,
        provider_name: str | None = None,
        embedding_model: str | None = None,
        metadata: dict[str, Any] | None = None,
    ) -> InboundMessage:
        """Publish a text message from this channel into the shared bus."""

        message = InboundMessage(
            channel=self.name,
            content=content,
            session_id=session_id,
            user_id=user_id,
            title=title,
            execution_context=execution_context,
            model=model,
            provider_name=provider_name,
            embedding_model=embedding_model,
            metadata=metadata or {},
        )
        await self.bus.publish_inbound(message)
        return message

    async def publish_external_text(
        self,
        content: str,
        *,
        chat_id: str,
        message_id: str | None = None,
        thread_id: str | None = None,
        raw_payload: dict[str, Any] | None = None,
        user_id: str | None = None,
        title: str | None = None,
    ) -> InboundMessage:
        """Publish an old-style channel payload through the new adapter contract.

        Real platform adapters should keep platform-specific fields here, build
        a stable Beaver session_id, and pass the normalized InboundMessage to
        the shared gateway bus.
        """

        session_parts = [self.name, chat_id]
        if thread_id:
            session_parts.append(thread_id)
        metadata = {
            "chat_id": chat_id,
            "message_id": message_id,
            "thread_id": thread_id,
            "raw_channel_payload": raw_payload or {},
        }
        return await self.publish_text(
            content,
            session_id=":".join(str(part) for part in session_parts if str(part)),
            user_id=user_id,
            title=title,
            metadata=metadata,
        )
