"""Handle ESP-NOW ANNOUNCE uplink and push GROUPS to drivers."""

from __future__ import annotations

from models.device import Device, normalize_mac  # noqa: F401 — re-export for callers
from models.group import Group
from models.bridge_ws_client import get_bridge_client
from util.espnow_wire import mac_bytes_to_hex, pack_groups, parse_announce
from util.groups_for_device import groups_for_mac


async def handle_espnow_announce(peer_mac: bytes, packet: bytes) -> None:
    info = parse_announce(packet)
    if not info:
        return
    mac_hex = mac_bytes_to_hex(peer_mac)
    if not mac_hex:
        return

    devices = Device()
    did, persisted = devices.upsert_espnow_announced(
        mac_hex,
        info["name"],
        device_type=info.get("device_type", "led"),
        num_leds=info.get("num_leds"),
        color_order=info.get("color_order"),
        startup_mode=info.get("startup_mode"),
        brightness=info.get("brightness"),
    )
    if not did:
        return
    if persisted:
        print(f"[espnow] registered mac={did} name={info['name']!r}")

    groups = Group()
    gids = groups_for_mac(did, groups)
    groups_pkt = pack_groups(gids)

    client = get_bridge_client()
    if client is None:
        print("[espnow] bridge client not configured; groups not sent")
        return
    ok = await client.send_espnow(groups_pkt, peer_mac=peer_mac)
    if ok:
        print(f"[espnow] groups -> {did}: {gids}")
    else:
        print(f"[espnow] groups send failed for {did}")


async def push_groups_for_group_devices(gdoc: dict) -> None:
    """Refresh GROUPS on every MAC listed on a group document."""
    mac_list = gdoc.get("devices") if isinstance(gdoc.get("devices"), list) else []
    for mac in mac_list:
        m = normalize_mac(str(mac))
        if m:
            await push_groups_to_mac(m)


async def push_groups_to_mac(mac_hex: str) -> bool:
    """Re-send GROUPS packet to one device (after group membership change)."""
    mac = normalize_mac(mac_hex)
    if not mac:
        return False
    client = get_bridge_client()
    if client is None:
        return False
    groups = Group()
    gids = groups_for_mac(mac, groups)
    pkt = pack_groups(gids)
    return await client.send_espnow(pkt, peer_mac=bytes.fromhex(mac))
