"""Transport to LED drivers via ESP-NOW bridge WebSocket."""

import asyncio
from typing import Optional, Union

from models.bridge_ws_client import get_bridge_client
from util.espnow_wire import WIRE_MAGIC, pack_ws_downlink

BROADCAST_MAC_HEX = "ffffffffffff"


def _parse_mac(addr) -> Optional[bytes]:
    if addr is None or addr == "":
        return None
    if isinstance(addr, bytes) and len(addr) == 6:
        return addr
    if isinstance(addr, str):
        s = addr.strip().lower().replace(":", "").replace("-", "")
        if len(s) == 12:
            return bytes.fromhex(s)
    return None


class NullSender:
    """No bridge configured."""

    async def send(self, data, addr=None):
        return True


class BridgeWsSender:
    """Send binary ESP-NOW packets via bridge WebSocket client."""

    async def send(self, data: Union[bytes, str, dict], addr=None) -> bool:
        client = get_bridge_client()
        if client is None:
            return False
        if isinstance(data, (bytes, bytearray)):
            packet = bytes(data)
        else:
            return False
        if not packet or packet[0] != WIRE_MAGIC:
            return False
        peer = _parse_mac(addr)
        broadcast = peer is None or addr == BROADCAST_MAC_HEX
        return await client.send_espnow(
            packet,
            peer_mac=peer,
            broadcast=broadcast,
        )


_current_sender = None


def set_sender(sender):
    global _current_sender
    _current_sender = sender


def get_current_sender():
    return _current_sender


def get_sender(settings):
    url = str(settings.get("bridge_ws_url") or "").strip()
    if not url:
        print(
            "[startup] bridge disabled (set bridge_ws_url in settings.json, e.g. ws://192.168.4.1/ws)"
        )
        return NullSender()
    print(f"[startup] ESP-NOW via bridge WebSocket {url!r}")
    return BridgeWsSender()
