import json
from channels.generic.websocket import WebsocketConsumer
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from products.models import Products, ProductCategory, ProductSubCategory, SKU
from chatbot.models import Chat_Data
import asyncio
from asgiref.sync import sync_to_async
from django.apps import apps
from django.core.paginator import Paginator




class ChatConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        await self.accept()
        data = await self.get_welcome_message()


        # await self.send( text_data = json.dumps({"ada" : data}))
        if data["status"] == "True":
            if data["option_type"] == "Custom":
                option_list = []
                for i in data["options"]:
                    option_list.append({"uuid": str(i.uuid), "option_name": i.option_name})
                data["options"] = option_list


        return await self.send(text_data = json.dumps(data))
        pass
    async def disconnect(self):
        pass
    async def receive(self, text_data):
        if self.scope.get('user_id') is not None:
            data = json.loads(text_data)

            option_id = data.get("option_id", "")
            if not option_id:
                await self.send(text_data= json.dumps([{"msg": "not recongnized"}]))
            chat_id = data.get("chat_id", "")
            option_table = data.get("option_table", "")
            option_column = data.get("option_column", "")

            msg = await self.get_related_message(option_id, chat_id, option_table, option_column)
            return await self.send(text_data=json.dumps(msg))

    @sync_to_async
    def get_welcome_message(self):
        data = Chat_Data.objects.filter(chat_type = "Welcome Message").first()
        if not data:
            return {"status": "False", "message": "Welcome Message not defined"}

        if data.option_type == "Custom":
            return {'status': "True",'chat_id': str(data.chat_id), 'chat_name':data.chat_name, 'chat_type':data.chat_type,'option_type':data.option_type, 'options': list(data.options.all())}
        else:
            model = next(
                model for model in apps.get_models()
                if model._meta.db_table.lower().split("_")[1] == data.option_table.lower() # model current table
            )

            if not model:
                return {"status":"False", "message": "invalid table"}

            # Filter using dynamic column name

            try:

                rows = model.objects.all()[:5].values("uuid", str(data.option_column))  # Dynamic column filtering, #current column
                paginator = Paginator(rows, 5)
                page = paginator.get_page(1)
                data_list = []
                for i in page:
                    data_list.append({'uuid': str(i["uuid"]), str(data.option_column): str(i[data.option_column])})

                return {'status': 'True','chat_id': str(data.chat_id), 'chat_name': str(data.chat_name),'chat_type':data.chat_type, 'option_type': str(data.option_type), 'options': data_list,'option_table': str(data.option_table), 'option_column':str(data.option_column)}
            except Exception as e:
                return {"status":"False", "message": str(e)}


    @sync_to_async
    def get_related_message(self, option_id, chat_id, option_table, option_column):
        data = Chat_Data.objects.filter(related_chat = chat_id).first()
        if not data:
            return {"status": "False", "message": "Related Chat not found"}
        if data.chat_type == "End Message":
            return {'status': 'True','chat_id': str(data.chat_id), 'chat_name': data.chat_name, 'chat_type': data.chat_type}
        if data.option_type == "Custom":
            return {'status': 'True','chat_id': str(data.chat_id), 'chat_name':data.chat_name, 'chat_type':data.chat_type,'option_type':data.option_type, 'options': list(data.options.all())}
        else:
            model = next(
                model for model in apps.get_models()
                if model._meta.db_table.lower().split("_")[1] == data.option_table.lower() # model current table
            )

            if not model:
                return {"status":"False", "message": "invalid table"}
            foreign_column = ""
            flag = "id"
            for wy in model._meta.get_fields():
                if wy.name == "uuid":
                    flag = "uuid"

                if wy.get_internal_type() == "ForeignKey":
                    if wy.related_model._meta.db_table.split("_")[1] == option_table: # check foreign key related to previous chat table
                        # previous chat table
                        foreign_column = wy.name
                        break

            # Filter using dynamic column name
            try:
                rows = model.objects.filter(**{foreign_column: option_id}).values(flag, data.option_column)  # Dynamic column filtering, #current column
                paginator = Paginator(rows, 5)
                page = paginator.get_page(1)
                data_list = []
                for i in page:
                    data_list.append({'uuid': str(i["uuid"]), str(data.option_column): str(i[data.option_column])})
                return {'chat_id': str(data.chat_id), 'chat_name': data.chat_name, 'chat_type':data.chat_type,'option_type': data.option_type, 'options': data_list,'option_table': data.option_table, 'option_column':data.option_column, "total_pages": paginator.num_pages}
            except Exception as e:
                return {"status":"False", "message": str(e)}




