import json

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async

from accounts.models import Users
from utils.firebase import send_notification

from .models import Chat


class ChatConsumer(AsyncWebsocketConsumer):

    async def connect(self):

        self.sender_id = self.scope["url_route"]["kwargs"]["sender"]
        self.receiver_id = self.scope["url_route"]["kwargs"]["receiver"]
        self.work_id = self.scope["url_route"]["kwargs"]["work_id"]
        self.work_sub_category_id = self.scope["url_route"]["kwargs"]["work_sub_category_id"]

        self.room_name = (
            f"chat_"
            f"{min(int(self.sender_id), int(self.receiver_id))}_"
            f"{max(int(self.sender_id), int(self.receiver_id))}_"
            f"{self.work_id}_"
            f"{self.work_sub_category_id}"
        )

        await self.channel_layer.group_add(
            self.room_name,
            self.channel_name
        )

        await self.accept()

        print("CONNECTED:", self.room_name)

    async def disconnect(self, close_code):

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

        print("DISCONNECTED:", self.room_name)

    async def receive(self, text_data):

        try:
            data = json.loads(text_data)

            chat = await self.save_chat(data)

            await self.send_chat_notification(chat)

            response = {
                "id": chat.id,
                "sender": chat.sender_id,
                "receiver": chat.receiver_id,
                "message": chat.message,
                "message_type": chat.message_type,
                "created_at": str(chat.created_at),
            }

            await self.channel_layer.group_send(
                self.room_name,
                {
                    "type": "chat_message",
                    "message": response,
                },
            )

        except Exception as e:
            print("Receive Error:", str(e))

    async def chat_message(self, event):

        await self.send(
            text_data=json.dumps(event["message"])
        )

    @database_sync_to_async
    def save_chat(self, data):

        return Chat.objects.create(
            sender_id=self.sender_id,
            receiver_id=self.receiver_id,
            work_id=self.work_id,
            work_sub_category_id=self.work_sub_category_id,
            message=data["message"],
            message_type=data.get("message_type", 0),
            status=0,
        )
    

    @database_sync_to_async
    def send_chat_notification(self, chat):
        print("asdadadadad")
        try:

            sender = Users.objects.get(id=chat.sender_id)
            receiver = Users.objects.get(id=chat.receiver_id)
            print(receiver.fcm_token)
            if not receiver.fcm_token:
                return

            data = send_notification(
                title=sender.name,
                message=chat.message,
                token=receiver.fcm_token,
                data={
                    "type": "chat",
                    "sender_id": str(sender.id),
                    "receiver_id": str(receiver.id),
                    "work_id": str(chat.work_id),
                    "work_sub_category_id": str(chat.work_sub_category_id),
                }
            )
            print(data)

        except Exception as e:
            print("Notification Error:", str(e))