import json

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer
from user.models import User
from urllib.parse import parse_qs


# class NewUserConsumer(WebsocketConsumer):
#     def connect(self):
#         # Extract user_id from query string
#         query_params = parse_qs(self.scope["query_string"].decode())
#         user_id = query_params.get("user_id", [None])[0]

#         if user_id:
#             try:
#                 user = User.objects.get(id=user_id)
#                 user.status = 1  # Online
#                 user.save()
#                 self.user = user
#             except User.DoesNotExist:
#                 self.close()
#                 return
#         else:
#             self.close()
#             return

#         self.room_name = 'new_user'
#         self.room_group_name = 'notification'

#         async_to_sync(self.channel_layer.group_add)(
#             self.room_group_name,
#             self.channel_name
#         )
#         self.accept()

#     def receive(self, text_data):
#         async_to_sync(self.channel_layer.group_send)(
#             self.room_group_name, {
#                 'type': 'new_user_notification',
#                 'message': json.loads(text_data).get('message', '')
#             }
#         )

#     def new_user_notification(self, event):
#         message = event['message']
#         self.send(text_data=json.dumps({
#             'message': message,
#             'status': 'new_user'
#         }))

#     def user_online(self, event):
#         message = event['message']
#         self.send(text_data=json.dumps({
#             'message': message,
#             'status': 'status_change'
#         }))

#     def disconnect(self, code):
#         if hasattr(self, 'user'):
#             self.user.status = 3  # Offline
#             self.user.save()

#         async_to_sync(self.channel_layer.group_discard)(
#             self.room_group_name,
#             self.channel_name
#         )



import json
from urllib.parse import parse_qs

from channels.generic.websocket import AsyncWebsocketConsumer
from user.models import User
from channels.db import database_sync_to_async


class NewUserConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        query_params = parse_qs(self.scope["query_string"].decode())
        self.user_id = query_params.get("user_id", [None])[0]
        self.user = None

        if self.user_id:
            self.user = await self.get_user(self.user_id)
            if self.user:
                await self.set_user_status(1)  # Online
            else:
                await self.close()
                return
        else:
            await self.close()
            return

        # Use user ID for group name
        self.room_group_name = f'user_{self.user_id}'

        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()

    async def disconnect(self, close_code):
        if self.user:
            await self.set_user_status(3)  # Offline

        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        message = json.loads(text_data)
        recipient_id = message.get('to')  # target user ID

        if not recipient_id:
            await self.send(text_data=json.dumps({"error": "No 'to' field in message"}))
            return

        recipient_group = f'user_{recipient_id}'

        await self.channel_layer.group_send(
            recipient_group,
            {
                "type": "signal_message",
                "message": message,
            }
        )

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

    @database_sync_to_async
    def get_user(self, user_id):
        try:
            return User.objects.get(id=user_id)
        except User.DoesNotExist:
            return None

    @database_sync_to_async
    def set_user_status(self, status):
        self.user.status = status
        self.user.save()
