import json

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from channels.layers import get_channel_layer
from collections import defaultdict
import threading

class UserConsumer(WebsocketConsumer):
    def connect(self):
        self.user_id = self.scope["url_route"]["kwargs"]["user_id"]
        self.group_name = f"sync_{self.user_id}"

        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.group_name, self.channel_name
        )

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.group_name, self.channel_name
        )

    # Receive message from WebSocket
    def receive(self, data):
        # text_data_json = json.loads(text_data)
        # message = text_data_json["message"]
        print(f'received: {data}')

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.group_name, {"type": "sync.update", "message": data} # sync.update calls the method below
        )

    # Receive message from room group
    def sync_update(self, event):
        message = event["message"]
        # print(f'event = {event}')

        # Send message to WebSocket
        self.send(text_data=message)

class StatusConsumer(WebsocketConsumer):
    # Class variable to track connections
    connections = defaultdict(int)
    connections_lock = threading.Lock()

    def connect(self):
        self.accept()
        with self.connections_lock:
            StatusConsumer.connections[self.channel_name] = 1
        self.send_status_update()

    def disconnect(self, close_code):
        with self.connections_lock:
            StatusConsumer.connections.pop(self.channel_name, None)
        self.send_status_update()

    def send_status_update(self):
        channel_layer = get_channel_layer()
        async_to_sync(channel_layer.group_send)(
            "status_group",
            {
                "type": "status_message",
                "message": {
                    "active_connections": len(StatusConsumer.connections),
                    "channel_layer_type": channel_layer.__class__.__name__
                }
            }
        )

    def receive(self, text_data):
        # Handle any incoming messages if needed
        pass

    def status_message(self, event):
        self.send(text_data=json.dumps(event["message"]))

# class ChatConsumer(WebsocketConsumer):
#     def connect(self):
#         self.room_name = 'main'
#         self.room_group_name = f"chat_{self.room_name}"

#         # Join room group
#         async_to_sync(self.channel_layer.group_add)(
#             self.room_group_name, self.channel_name
#         )

#         self.accept()

#     def disconnect(self, close_code):
#         # Leave room group
#         async_to_sync(self.channel_layer.group_discard)(
#             self.room_group_name, self.channel_name
#         )

#     # Receive message from WebSocket
#     def receive(self, text_data):
#         # text_data_json = json.loads(text_data)
#         # message = text_data_json["message"]
#         print(f'received {text_data}')

#         # Send message to room group
#         # chat.message calls the chat_message method
#         async_to_sync(self.channel_layer.group_send)(
#             self.room_group_name, {"type": "chat.message", "message": text_data}
#         )

#     # Receive message from room group
#     def chat_message(self, event):
#         message = event["message"]

#         # Send message to WebSocket
#         self.send(text_data=message)
