"""WebRTC signaling handler over MQTT.

Processes SDP offers and ICE candidates from browsers/viewers arriving on
``devices/{deviceId}/signaling/request`` and publishes answers/candidates
back on ``devices/{deviceId}/signaling/response``.
"""

from __future__ import annotations

import logging
from typing import Any, Callable, Awaitable

from .client import MQTTManager

logger = logging.getLogger(__name__)

WebRTCOfferCallback = Callable[[dict[str, Any]], Awaitable[dict[str, Any] | None]]
ICECandidateCallback = Callable[[dict[str, Any]], Awaitable[None]]


class SignalingHandler:
    """Handles WebRTC signaling over MQTT topics."""

    def __init__(
        self,
        mqtt: MQTTManager,
        on_offer: WebRTCOfferCallback | None = None,
        on_ice_candidate: ICECandidateCallback | None = None,
    ) -> None:
        self._mqtt = mqtt
        self._on_offer = on_offer
        self._on_ice_candidate = on_ice_candidate
        mqtt.on_topic("signaling/request", self._handle_signaling_request)

    async def _handle_signaling_request(
        self, topic: str, payload: dict[str, Any]
    ) -> None:
        sig_type = payload.get("type", "")

        if sig_type == "offer":
            logger.info("Received WebRTC offer")
            if self._on_offer:
                answer = await self._on_offer(payload)
                if answer:
                    await self._mqtt.publish("signaling/response", answer)

        elif sig_type == "ice":
            logger.debug("Received ICE candidate")
            if self._on_ice_candidate:
                await self._on_ice_candidate(payload)

        else:
            logger.warning("Unknown signaling type: %s", sig_type)

    async def send_answer(self, sdp: str) -> None:
        """Send a WebRTC answer SDP to the browser."""
        await self._mqtt.publish("signaling/response", {
            "type": "answer",
            "sdp": sdp,
        })

    async def send_ice_candidate(self, candidate: dict[str, Any]) -> None:
        """Send an ICE candidate to the browser."""
        await self._mqtt.publish("signaling/response", {
            "type": "ice",
            "candidate": candidate,
        })
