from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from threading import Timer

class WebSocketSender:
    """
    Manages WebSocket notifications for users with individual buffering timers.
    """
    def __init__(self):
        self._user_timers = {}   # Dictionary to store user-specific timers
        self._buffer_timeout = 0.1  # Debounce timeout in seconds

    def send_user_message(self, user_id, device_id):
        """
        Schedules a notification for a specific user with debouncing.
        """
        # print(f'>>> send message: {device_id}')
        # Cancel existing timer for this user if any
        if user_id in self._user_timers and self._user_timers[user_id]:
            self._user_timers[user_id].cancel()

        # Create new timer for this user
        self._user_timers[user_id] = Timer(
            self._buffer_timeout,
            self._send_message,
            args=[user_id, device_id]
        )
        self._user_timers[user_id].start()

    def _send_message(self, user_id, device_id):
        """
        Sends the WebSocket message for a specific user.
        """
        channel_layer = get_channel_layer()
        group_name = f"sync_{user_id}"

        print(f">>> send to group {group_name}, device_id={device_id}")
        # print(f'channel_layer = {channel_layer}')

        device_id = device_id if device_id else "std_msg_lol" # a not empty message is required!

        async_to_sync(channel_layer.group_send)(
            group_name,
            {"type": "sync.update", "message": device_id}
        )
        # Cleanup timer reference
        self._user_timers[user_id] = None

# Create a singleton instance
websocket_sender = WebSocketSender()
