# chat/consumers.py
import json

from account.models import UserProfile

from channels.db import database_sync_to_async
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async, async_to_sync


class ChatConsumer(AsyncWebsocketConsumer):
    # -- CONNECT --
    async def connect(self):
        self.chat_id = self.scope["url_route"]["kwargs"]["chat_id"]
        self.chat_name = f"chat_{self.chat_id}"

        user = self.scope["user"]

        if not user.is_authenticated:
            await self.close(code=4401)  # unauthorized
            return

        #join chat group
        async_to_sync(self.channel_layer.group_add)(
            self.chat_name,
        )

        

        await self.accept()

    # -- DISCONNECT --
    async def disconnect(self, close_code):
        async_to_sync(self.channel_layer.group_discard)(
            self.chat_name
        )

        self.disconnect()
        pass

    # -- RECIVE --
    async def receive(self, data):
        if data["type"] == "new_chat_message":

            message = data["message"]

            # Send message to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "chat.message", "message": message}
            )

        elif data["type"] == "new_reply_chat_message":
            message = data["message"]
            reply_to_id = data["reply_to_id"]

            # Send message to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "reply.chat.message", "message": message, "reply_to_id": reply_to_id}
            )

        elif data["type"] == "edit_chat_message":
            message = data["message"]

            # Send message to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "edit.message", "message": message}
            )

        elif data["type"] == "delete_chat_message":
            message_id = data["message_id"]

            # Send message to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "delete.message", "message_id": message_id}
            )
        
        elif data["type"] == "typing":
            is_typing = data["is_typing"]

            # Send typing status to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "typing.status", "user": self.scope["user"].username, "is_typing": is_typing}
            )

        elif data["type"] == "stop_typing":
            # Send stop typing status to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "stop.typing", "user": self.scope["user"].username}
            )

        elif data["type"] == "reaction":
            message_id = data["message_id"]
            emoji = data["emoji"]

            # Send reaction to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "message.reaction", "message_id": message_id, "emoji": emoji, "user": self.scope["user"].username}
            )

        elif data["type"] == "unreaction":
            message_id = data["message_id"]
            emoji = data["emoji"]

            # Send unreaction to room group
            async_to_sync(self.channel_layer.group_send)(
                self.chat_name, {"type": "message.unreaction", "message_id": message_id, "emoji": emoji, "user": self.scope["user"].username}
            )

        else:
            self.close(reason="Unsupported message type")


    # -- CUSTOM METHODS --

    def send_message_to_chat_group(self, event):
        message = event["message"]
        create_new_message()
        self.send(text_data=json.dumps({"message": message}))

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



# -- MESSAGES --
@database_sync_to_async
def create_new_message():
    return None

@database_sync_to_async
def create_new_reply_message():
    return None

@database_sync_to_async
def edit_message():
    return None

@database_sync_to_async
def delete_message():
    return None


# -- REACTIONS --
@database_sync_to_async
def react_to_message():
    return None

@database_sync_to_async
def unreact_to_message():
    return None