"""DataChannel handler for touch/key/clipboard control signals.

Parses control messages from the browser (touch, key, text, scroll, etc.)
and dispatches them. Also sends device state (clipboard, rotation, quality)
back to the browser.
"""

from __future__ import annotations

import json
import logging
from typing import Any, Callable, Awaitable

logger = logging.getLogger(__name__)


class DataChannelHandler:
    """Handles WebRTC DataChannel messages for device control."""

    def __init__(
        self,
        channel: Any,
        on_message: Callable[[dict[str, Any]], Awaitable[None]] | None = None,
    ) -> None:
        self._channel = channel
        self._on_message = on_message
        self._setup()

    def _setup(self) -> None:
        @self._channel.on("message")
        async def on_message(raw: str | bytes) -> None:
            try:
                if isinstance(raw, bytes):
                    raw = raw.decode()
                msg = json.loads(raw)
            except (json.JSONDecodeError, UnicodeDecodeError):
                logger.warning("Invalid DataChannel message")
                return

            if self._on_message:
                try:
                    await self._on_message(msg)
                except Exception:
                    logger.exception("DataChannel message handler error")

    async def send(self, data: dict[str, Any]) -> None:
        """Send a JSON message to the browser via DataChannel."""
        if self._channel.readyState == "open":
            self._channel.send(json.dumps(data))

    async def send_device_info(self, info: dict[str, Any]) -> None:
        await self.send({"type": "device_info", "device": info})

    async def send_clipboard(self, text: str) -> None:
        await self.send({"type": "clipboard", "text": text})

    async def send_rotation(self, rotation: int) -> None:
        await self.send({"type": "rotation", "value": rotation})

    async def send_quality_report(
        self, fps: int, latency_ms: int, bandwidth: int
    ) -> None:
        await self.send({
            "type": "quality_report",
            "fps": fps,
            "latencyMs": latency_ms,
            "bandwidth": bandwidth,
        })
