"""Generic runtime channel backed by an external connector sidecar."""

from __future__ import annotations

import hashlib
from typing import Any

from beaver.foundation.events import OutboundMessage
from beaver.interfaces.channels.connections.sidecar_client import ConnectorSidecarClient


class ExternalConnectorChannel:
    def __init__(
        self,
        *,
        channel_id: str,
        platform_kind: str,
        connection_id: str,
        account_id: str,
        display_name: str,
        sidecar_client: ConnectorSidecarClient | Any,
    ) -> None:
        self.channel_id = channel_id
        self.kind = "external_connector"
        self.mode = "http"
        self.platform_kind = platform_kind
        self.connection_id = connection_id
        self.account_id = account_id
        self.display_name = display_name or channel_id
        self.sidecar_client = sidecar_client
        self.started = False

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

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

    async def send(self, message: OutboundMessage) -> None:
        identity = message.channel_identity
        if identity is None:
            raise ValueError("channel_identity is required for external connector sends")
        metadata = {
            "inboundMessageId": identity.message_id,
            "sessionId": message.session_id,
        }
        context_token = _context_token(message)
        if context_token:
            metadata["contextToken"] = context_token
        payload = {
            "requestId": _request_id(message),
            "connectionId": self.connection_id,
            "channelId": self.channel_id,
            "kind": self.platform_kind,
            "target": {
                "peerId": identity.peer_id,
                "peerType": identity.peer_type,
                "threadId": identity.thread_id,
            },
            "content": message.content,
            "metadata": metadata,
        }
        await self.sidecar_client.send(payload)


def _request_id(message: OutboundMessage) -> str:
    identity = message.channel_identity
    channel = message.channel or (identity.channel_id if identity else "unknown")
    session_id = message.session_id or (identity.session_id() if identity else "unknown")
    message_id = str(message.message_id or "").strip()
    if not message_id:
        basis = "|".join(
            [
                message.content,
                identity.message_id if identity and identity.message_id else "",
                identity.peer_id if identity else "",
                message.finish_reason,
            ]
        )
        message_id = hashlib.sha256(basis.encode("utf-8")).hexdigest()[:24]
    return f"out_{channel}:{session_id}:{message_id}"


def _context_token(message: OutboundMessage) -> str | None:
    inbound_metadata = message.metadata.get("inbound_metadata")
    if isinstance(inbound_metadata, dict):
        value = _clean_optional(inbound_metadata.get("contextToken") or inbound_metadata.get("context_token"))
        if value:
            return value
    return _clean_optional(message.metadata.get("contextToken") or message.metadata.get("context_token"))


def _clean_optional(value: Any) -> str | None:
    if value is None:
        return None
    text = str(value).strip()
    return text or None
