"""Fire-and-forget broadcast helpers.

Every function here swallows channel-layer errors: a Redis hiccup must NEVER
break a booking, a lock, or a login. Real-time updates are an enhancement,
not a dependency.
"""
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer


def _send(group, msg_type, payload):
    try:
        layer = get_channel_layer()
        if layer is None:
            return
        async_to_sync(layer.group_send)(group, {'type': msg_type, 'payload': payload})
    except Exception:
        pass  # never let realtime failures affect the request


def broadcast_seat_update(schedule_id, seat_numbers, status):
    """Tell everyone watching this trip's seat map that seats changed state."""
    _send(f'seats_{schedule_id}', 'seat_update',
          {'event': 'seat_update', 'schedule_id': schedule_id,
           'seats': list(seat_numbers), 'status': status})


def notify_operator(operator_id, event, payload=None):
    _send(f'operator_{operator_id}', 'portal_event',
          {'event': event, **(payload or {})})


def notify_admins(event, payload=None):
    _send('admin_portal', 'portal_event',
          {'event': event, **(payload or {})})
