from django.shortcuts import render, redirect, get_object_or_404
from .models import Chat_Data, Options, ColumnList, TableList, RelatedOptionTable, MapTables
from django.core.paginator import Paginator
from adminportal.views import check_user_role
from django.contrib.auth.decorators import user_passes_test
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from rest_framework.pagination import PageNumberPagination
from .forms import ChatForm, TableListForm, ColumnListForm, MapForm
from django.apps import apps
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .serializers import ChatDataSerializer, OptionsSerializer
from django.http import JsonResponse
from django.db import connection, transaction
from products.models import Products
from django.contrib import messages
import uuid
from django.core.mail import send_mail
from NavyaBackers.settings import EMAIL_HOST_USER
from accounts.models import UserLocation


# Create your views here.

@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_list(request):
    chat = Chat_Data.objects.order_by("-created_date")
    paginator = Paginator(chat, 6)
    page = request.GET.get("page")
    try:
        chat_data = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        chat_data = paginator.get_page(1)
    except EmptyPage:
        chat_data = paginator.get_page(paginator.num_pages)
    context = {"chat_data": chat_data, "chat_active": "active"}
    return render(request, "chat_data_list.html", context)


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_delete(request, chat_id):
    chat = Chat_Data.objects.filter(pk=chat_id)
    queryset = Chat_Data.objects.filter(related_chat=chat_id).first()
    if queryset:
        messages.warning(request,"Couldn't delete chat related to another chat!")
    else:
        if chat:
            chat.delete()
    return redirect("chat-list")


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_add(request):
    errors = []
    if request.method == "POST":
        form = ChatForm(request.POST)
        chat_type = request.POST.get("chat_type")  # Get chat type
        option_table_id = request.POST.get("option_table")
        option_column_id = request.POST.get("option_column")
        redirect_data = request.POST.get('redirect')

        # Convert UUID to a ColumnList instance
        try:
            option_column = ColumnList.objects.get(id=option_column_id) if option_column_id else None
        except ColumnList.DoesNotExist:
            option_column = None
        related_chat_id = request.POST.get("related_chat", None)  # ✅ Get the UUID, not a string

        # 🔍 Debugging: Print received form values
        # print(f"🔍 DEBUG: Received chat_type: {chat_type}")
        # print(f"🔍 DEBUG: Received related_chat_id: {related_chat_id}")
        # print(f"🔍 DEBUG: Received option_table_id: {option_table_id}")
        # print(f"🔍 DEBUG: Received option_column_id: {option_column_id}")

        # ✅ Initialize related_chat correctly
        related_chat = None
        if related_chat_id:
            try:
                related_chat = Chat_Data.objects.get(chat_id=related_chat_id)
                # print(f"✅ Found related_chat with UUID: {related_chat.chat_id}")
            except (Chat_Data.DoesNotExist, ValueError):
                # print(f"❌ ERROR: Invalid or missing related_chat UUID: {related_chat_id}")
                related_chat = None  # Avoid assigning an invalid value

        # ✅ Fetch Option Table and Option Column correctly
        option_table = TableList.objects.filter(id=option_table_id).first() if option_table_id else None

        # ✅ Convert UUID to ColumnList instance
        try:
            option_column = ColumnList.objects.get(id=option_column_id) if option_column_id else None
        except ColumnList.DoesNotExist:
            option_column = None

        # ✅ If chat_type is "Welcome Message", reset fields
        if chat_type == "Welcome Message":
            option_table = None
            option_column = None
            related_chat = None

        if form.is_valid():
            chat = form.save(commit=False)
            chat.option_table = option_table  # ✅ Store TableList instance
            chat.option_column = option_column  # ✅ Store ColumnList instance
            chat.related_chat = related_chat  # ✅ Store Chat_Data instance
            chat.redirect = redirect_data

            # 🔍 Debugging: Print the final values before saving
            # print(f"✅ Saving Chat: {chat.chat_name}")
            # print(f"✅ Stored Related Chat UUID: {chat.related_chat}")
            # print(f"✅ Stored Option Table: {chat.option_table}")
            # print(f"✅ Stored Option Column: {chat.option_column}")

            # logic to add the custom options
            # only if option type custom

            #before saving check whether validation issue in options



            option_type = request.POST.get("option_type")
            dynamic_field_list = []
            error_dict = {}
            if option_type == 'Custom':
                flag = 0
                for i in list(request.POST.keys()):
                    if i.startswith('dynamic_input'):
                        if request.POST.get(str(i)) == '':
                            error_dict[i] = "Field Required!"
                            flag = 1
                        dynamic_field_list.append({"name":i, "value":request.POST.get(str(i))})
                if flag == 1:
                    option_count = len(dynamic_field_list)
                    context = {
                    "errors": error_dict,
                    "chat_form": form,
                    "chat_active": "active",
                    "option_flag": "True",
                    "option_count": option_count,
                    "option_list": dynamic_field_list
                    }
                    return render(request, "chat_add.html", context)

            chat.save()
            option_id_list = []
            if dynamic_field_list:
                for j in dynamic_field_list:
                    option = RelatedOptionTable.objects.create(option_value=j["value"])
                    option_id_list.append(option.id)
            chat.options.set(option_id_list)
            chat.save()





            return redirect("chat-list")
        else:
            # print(f"❌ ERROR: Form is invalid. Error messages: {form.errors}")
            errors.append(form.errors)
            option_type = request.POST.get("option_type")
            error_dict = {}
            dynamic_field_list = []
            if option_type == 'Custom':
                for i in list(request.POST.keys()):
                    if i.startswith('dynamic_input'):
                        if request.POST.get(str(i)) == '':
                            error_dict[i] = "Field Required!"
                        dynamic_field_list.append({"name":i, "value":request.POST.get(str(i))})
            option_count = len(dynamic_field_list)

            context = {
                "errors": error_dict,
                "chat_form": form,
                "chat_active": "active",
                "option_flag": "True",
                "option_count":option_count,
                "option_list": dynamic_field_list
            }
            return render(request, "chat_add.html", context)
    else:
        form = ChatForm()
        # print(form)

    context = {
        "errors": errors,
        "chat_form": form,
        "chat_active": "active",
        "option_flag":"False"
    }
    return render(request, "chat_add.html", context)


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def load_column_list(request):
    table_id = request.GET.get("table_id")
    # print(f"📌 Received table_id: {table_id}")  # Debugging

    if not table_id:
        # print("❌ No table_id received!")
        return JsonResponse({"error": "Missing table_id", "columns": []}, safe=False)

    columns = ColumnList.objects.filter(table__id=table_id).values("id", "column_name")
    map_table = MapTables.objects.filter(table_name__id = table_id)
    redirect_flag = False
    if map_table:
        redirect_flag = True
    # print(f"✅ Found Columns: {list(columns)}")  # Debugging
    # print({"columns": list(columns), "redirect_flag": redirect_flag})
    return JsonResponse({"columns": list(columns), "redirect_flag": redirect_flag}, safe=False)


# @user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
# def related_chat_list(request):
#     try:
#         related_field_ids = Chat_Data.objects.values("related_chat")
#         fields_to_remove = []
#         for i in related_field_ids:
#             if i['related_chat']:
#                 fields_to_remove.append(i['related_chat'])
#
#         chat_list = Chat_Data.objects.order_by("-created_date").exclude(chat_id__in=fields_to_remove).exclude(
#             chat_type="End Message").values("chat_id", "chat_name")
#         if chat_list:
#             return JsonResponse({"chat_data": list(chat_list)},
#                                 safe=False)
#         else:
#             return JsonResponse({"chat_data": []}, safe=False)
#
#     except StopIteration:
#         return JsonResponse({"chat_data": []}, safe=False)



#need to edit this
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def related_option_hide(request):
    row_id = request.GET.get('row_id')
    option_id = request.GET.get('option_id', None)
    # print(f"option id : {option_id}")
    if not row_id:
        return JsonResponse({"status": "Success", "type": "None"})  # ✅ Change "Table" to "None"
    chat = Chat_Data.objects.filter(chat_id=row_id).first()

    if not chat:
        return JsonResponse({"status": "Error", "message": "Chat not found!"})

    # ✅ Check if option_table exists instead of option_type

    if chat.option_type == "Custom":
        related_option_ids = [(i.related_option_id.id, i.related_option_id.option_value) for i in
                              Chat_Data.objects.all() if i.related_option_id]

        # print(f"related_option_ids : {related_option_ids}")

        options_to_render = []
        for j in chat.options.all():
            # print(f"options ids in a chat  : {(j.id, j.option_value)}")
            if option_id:
                if j.id == uuid.UUID(option_id):
                    options_to_render.append(
                        {"option_name": j.id, "option_value": j.option_value})

            if (j.id, j.option_value) not in related_option_ids:
                options_to_render.append(
                    {"option_name": j.id, "option_value": j.option_value})



        return JsonResponse({"status": "Success", "type": 'Custom', "options": options_to_render}, safe=False)

    elif chat.option_type == "Table":  # ✅ Check if option_table is set
        return JsonResponse({"status": "Success", "type": 'Table'})
    else:
        return JsonResponse({"status": "Success", "type": str(chat.option_table)})


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def table_list(request):
    choice = request.GET.get('choice')
    chat_type = request.GET.get('chat_type')
    related_chat = request.GET.get('related_chat')

    if choice == 'Yes' and chat_type == 'Related':
        chat_data = Chat_Data.objects.filter(chat_id=related_chat).first()
        if chat_data.option_type == 'Table':
            table = chat_data.option_table
        else:
            table = "default"
            pass
        table_list = []
        try:
            for model in apps.get_models():
                for wy in model._meta.get_fields():
                    if wy.get_internal_type() == "ForeignKey":
                        if wy.related_model._meta.db_table.split("_")[1] == table:
                            table_list.append(model._meta.db_table.lower().split("_")[1])

            if table_list:
                return JsonResponse({"tables": list(table_list)},
                                    safe=False)
            else:
                return JsonResponse({"tables": []}, safe=False)

        except StopIteration:
            return JsonResponse({"tables": []}, safe=False)
    elif choice == 'No':
        try:
            app_models = apps.get_app_config('products').get_models()
            table_list_products = []
            count = 1
            for model in app_models:
                table_list_products.append(
                    str(model._meta.db_table).split("_")[1])
                count + 1
            if table_list_products:
                return JsonResponse({"tables": list(table_list_products)},
                                    safe=False)
            else:
                return JsonResponse({"tables": []}, safe=False)

        except StopIteration:
            return JsonResponse({"tables": []}, safe=False)


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_edit(request, chat_id):
    errors = []
    chat_data = get_object_or_404(Chat_Data, chat_id=chat_id)
    post_data = request.POST.copy()
    post_data["chat_type"] = chat_data.chat_type
    # request.POST["chat_type"] = chat_data.chat_type
    options = Options.objects.filter(table=chat_data.option_table, column=chat_data.option_column)
    existing_options = list(
        Options.objects.filter(table=chat_data.option_table, column=chat_data.option_column).values_list('option_value',
                                                                                                         flat=True))



    if request.method == "POST":
        # print(list(request.POST.keys()))
        # dynamic_field_list = []
        # for i in list(request.POST.keys()):
        #     if i.startswith('dynamic_input'):
        #         dynamic_field_list.append({str(i): request.POST.get(str(i))})
        # print(dynamic_field_list)
        form = ChatForm(post_data, instance=chat_data)
        # print(form)
        chat_type = request.POST.get("chat_type", None)
        option_table_id = request.POST.get("option_table", None)
        option_column_id = request.POST.get("option_column", None)
        related_chat_id = request.POST.get("related_chat", None)
        option_id = request.POST.get("related_option_id", None)
        redirect_data = request.POST.get('redirect', None)

        # print(f"🔍 DEBUG: Received chat_type: {chat_type}")
        # print(f"🔍 DEBUG: Received related_chat_id: {related_chat_id}")
        # print(f"🔍 DEBUG: Received option_table_id: {option_table_id}")
        # print(f"🔍 DEBUG: Received option_column_id: {option_column_id}")

        related_chat = Chat_Data.objects.filter(chat_id=related_chat_id).first() if related_chat_id else None
        option_table = TableList.objects.filter(id=option_table_id).first() if option_table_id else None
        option_column = ColumnList.objects.filter(id=option_column_id).first() if option_column_id else None


        if chat_type == "Welcome Message":
            option_table = None
            option_column = None
            related_chat = None

        if form.is_valid():
            chat = form.save(commit=False)
            chat.option_table = option_table
            chat.option_column = option_column
            chat.related_chat = related_chat
            chat.redirect = redirect_data


            option_type = request.POST.get("option_type")
            dynamic_field_list = []
            error_dict = {}
            existing_list_post = []
            if option_type == 'Custom':
                flag = 0
                for i in list(request.POST.keys()):
                    if i.startswith('dynamic_input'):
                        id = i.split('dynamic_input_')[1]
                        if len(id)>5:
                            existing_list_post.append(id)
                        if request.POST.get(str(i)) == '':
                            error_dict[i] = "Field Required!"
                            flag = 1
                        dynamic_field_list.append({"name":i, "value":request.POST.get(str(i))})
                if flag == 1:
                    option_count = len(dynamic_field_list)
                    context = {
                        "errors": error_dict,
                        "form": form,
                        "options": options,
                        "chat_active": "active",
                        "chat_data": chat_data,
                        "tables": TableList.objects.all(),
                        "option_table_id": chat_data.option_table.id if chat_data.option_table else "",
                        "related_chat_id": chat_data.related_chat.chat_id if chat_data.related_chat else "",
                        "option_column_id": chat_data.option_column.id if chat_data.option_column else "",
                        "option_column_list": ColumnList.objects.filter(
                            table=chat_data.option_table) if chat_data.option_table else [],
                        "option_type_value": chat_data.option_type if chat_data.option_type else "",
                        "existing_options": existing_options,
                        "option_flag": "True",
                        "option_count": option_count,
                        "option_list": dynamic_field_list,
                        "chat_id": chat_id
                    }
                    return render(request, "chat_edit.html", context)
                chat.save()

                option_id_list = []

                ## Get existing option list
                # find the difference
                #if already exist don't create a new option

                existing_option_list = set([ str(i.id) for i in chat.options.all()])

                dynamic_field_set = set(existing_list_post)

                fields_to_remove = list(existing_option_list - dynamic_field_set)


                #iterate and delete the removed options

                for i in fields_to_remove:
                    data = RelatedOptionTable.objects.filter(id=i)
                    chat.options.remove(data.first())
                    data.delete()



                if dynamic_field_list:
                    for j in dynamic_field_list:
                        id_ = j["name"].split('dynamic_input_')[1]
                        if len(id_)<5:
                            option = RelatedOptionTable.objects.create(option_value=j["value"])
                            option_id_list.append(option.id)
                            chat.options.add(option.id)
                        else:
                            related_data = RelatedOptionTable.objects.get(id = id_)
                            related_data.option_value = j["value"]
                            related_data.save()
            chat.save()

            return redirect("chat-list")
        else:
            option_type = request.POST.get("option_type")
            dynamic_field_list = []
            error_dict = {}
            if option_type == 'Custom':
                for i in list(request.POST.keys()):
                    if i.startswith('dynamic_input'):
                        if request.POST.get(str(i)) == '':
                            error_dict[i] = "Field Required!"
                        dynamic_field_list.append({"name":i, "value":request.POST.get(str(i))})
            option_count = len(dynamic_field_list)
            context = {
                "errors": error_dict,
                "form": form,
                "options": options,
                "chat_active": "active",
                "chat_data": chat_data,
                "tables": TableList.objects.all(),
                "option_table_id": chat_data.option_table.id if chat_data.option_table else "",
                "related_chat_id": chat_data.related_chat.chat_id if chat_data.related_chat else "",
                "option_column_id": chat_data.option_column.id if chat_data.option_column else "",
                "option_column_list": ColumnList.objects.filter(
                table=chat_data.option_table) if chat_data.option_table else [],
                "option_type_value": chat_data.option_type if chat_data.option_type else "",
                "existing_options": existing_options,
                "option_flag": "True",
                "option_count": option_count,
                "option_list": dynamic_field_list,
                "chat_id": chat_id
            }
            pass

    else:
        form = ChatForm(instance=chat_data)
        option_type = chat_data.option_type
        error_dict = {}
        dynamic_field_list = []
        if option_type == 'Custom':
            for i in list(chat_data.options.all()):
                dynamic_field_list.append({"name": f'dynamic_input_{i.id}', "value": i.option_value})
        option_count = len(dynamic_field_list)

        context = {
            "errors": error_dict,
            "form": form,
            "options": options,
            "chat_active": "active",
            "chat_data": chat_data,
            "tables": TableList.objects.all(),
            "option_table_id": chat_data.option_table.id if chat_data.option_table else "",
            "related_chat_id": chat_data.related_chat.chat_id if chat_data.related_chat else "",
            "option_column_id": chat_data.option_column.id if chat_data.option_column else "",
            "option_column_list": ColumnList.objects.filter(table=chat_data.option_table) if chat_data.option_table else [],
            "option_type_value": chat_data.option_type if chat_data.option_type else "",
            "existing_options": existing_options,
            "option_flag": "True",
            "option_count": option_count,
            "option_list": dynamic_field_list,
            "chat_id": chat_id
        }

    return render(request, "chat_edit.html", context)


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def load_column_list(request):
    """ Load columns dynamically based on selected table. """
    table_id = request.GET.get("table_id")
    # print(f"📌 Received table_id: {table_id}")  # Debugging

    if not table_id:
        # print("❌ No table_id received!")
        return JsonResponse({"error": "Missing table_id", "columns": []}, safe=False)

    columns = ColumnList.objects.filter(table__id=table_id).values("id", "column_name")
    map_table = MapTables.objects.filter(table_name__id=table_id)
    redirect_flag = False
    if map_table:
        redirect_flag = True
    # print(f"✅ Found Columns: {list(columns)}")  # Debugging
    return JsonResponse({"columns": list(columns),"redirect_flag": redirect_flag}, safe=False)


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def related_chat_list(request, chat_id = None):
    """ Fetch Related Chat List """

    #fetch the chat ids
    #exclude custom to handle separately
    #check the type of related chat

    chat =  Chat_Data.objects.filter(chat_id = chat_id).first()
    related_chat = None
    if chat:
        related_chat = chat.related_chat
    # print(f"related chat : {related_chat}")
    chat_id_add = None
    if related_chat:
        chat_id_add = related_chat.chat_id

    # print(f"related chat option type : {remove_table_option_type}")
    # print(f"related chat id : {chat_id}")



    remove_chat_id = None
    if chat:
        remove_chat_id = chat.chat_id

    # getting the ids for remove lately
    # print(f"remove_chat_id: {remove_chat_id}")
    # print(f"remove_option_type: {remove_option_type}")



    related_options_without_custom = Chat_Data.objects.all()


    # getting all selected option ids
    related_option_ids = [(i.related_option_id.id, i.related_option_id.option_value) for i in Chat_Data.objects.all() if i.related_option_id]


    related_field_ids = []
    field_ids = []
    custom_field_ids = []

    # finding the whole chat ids except custom but including welcome and end
    # find all the ids listed in the related chat field
    # field_ids : related chat field value
    # related_field_ids : whole chat ids except custom

    for ids in related_options_without_custom:
        if ids.option_type == "Table":
            related_field_ids.append(ids.chat_id)
        if ids.option_type == "Custom":
            custom_field_ids.append(ids.chat_id)

        if ids.chat_type == "Welcome Message":
            related_field_ids.append(ids.chat_id)

        if ids.related_chat:
            if ids.related_chat.option_type == "Table":
                field_ids.append(ids.related_chat.chat_id)
            elif ids.related_chat.chat_type == "Welcome Message":
                field_ids.append(ids.related_chat.chat_id)



    # print(f"field_ids : {field_ids}")
    # print(f"related_field_ids: {related_field_ids}")

    table_field_ids = list(set(related_field_ids) - set(field_ids))
    # print(f"related_field_set: {set(related_field_ids)}")
    # print(f"field_id_set: {set(field_ids)}")

    # handled custom self

    fields_to_remove_custom = []

    chat_list = Chat_Data.objects.filter(option_type="Custom")
    for i in chat_list:
        flag = True
        for j in i.options.all():
            if (j.id, j.option_value) not in related_option_ids:
                flag = False
        if flag:
            fields_to_remove_custom.append(i.chat_id)

    custom_fields = list(set(custom_field_ids) - set(fields_to_remove_custom))

    fields = custom_fields + table_field_ids

    fields.append(chat_id_add)

    remove = []
    if chat_id:
        remove = [uuid.UUID(chat_id), ]

    field_list = list(set(fields) - set(remove))





    chat_list_result = list(Chat_Data.objects.filter( chat_id__in= field_list).values("chat_id", "chat_name"))


    return JsonResponse({"chat_data": list(chat_list_result)}, safe=False)


# @user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
@api_view(["POST"])
def chatbot_data_api(request):
    """ Fetch Chatbot API Data """
    if request.user.is_authenticated:
        user_location = UserLocation.objects.filter(user=request.user).first()

    else:
        anonymous_id = request.data.get("anonymous_id")
        user_location = UserLocation.objects.filter(
            anonymous_id=anonymous_id
        ).first()
    order_type = "Long Distance"
    if user_location and user_location.shop:
        # Shop found; use shop logic
        shop_id = user_location.shop
        order_type = "Shop"

    # else:
    #     return JsonResponse({"status": False, "message": "No Shop Found"})

    data_type = request.data.get("type", None)
    related_chat_id = request.data.get("related_chat_id", None)
    # category_id = request.data.get("category_id", None)  # ✅ Fix: Get category ID from request
    filter_option_value = request.data.get("option_value", None)  # ✅ Fix: Get option value
    # subcategory_id = request.data.get("subcategory_id", None)  # ✅ New: Get subcategory ID for product names
    option_type = request.data.get("option_type", None)

    paginator = PageNumberPagination()
    paginator.page_size = request.data.get("page_size", 4)

    # ✅ Fetch Welcome Message
    if data_type == "welcome":
        welcome_message = Chat_Data.objects.filter(chat_type="Welcome Message").first()
        if welcome_message:
            return Response(
                {
                    "status": True,
                    "chat_id": welcome_message.chat_id,
                    "chat_name": welcome_message.chat_name,
                    "message": welcome_message.message,
                }
            )
        return Response(
            {"status": False,"error": "No Welcome Message found"}, status=status.HTTP_404_NOT_FOUND
        )

    # ✅ Validate "related_chat_id"
    if not related_chat_id:
        return Response(
            {"status": False,"error": "Missing 'related_chat_id' in request body"},
            status=status.HTTP_400_BAD_REQUEST,
        )

    # ✅ Fetch Related Chat Data
    queryset = Chat_Data.objects.filter(related_chat=related_chat_id)
    current_chat = Chat_Data.objects.filter(chat_id = related_chat_id).first()
    if not current_chat:
        return JsonResponse({"status": False, "error" : "Chat not found! "})
    if option_type == "Custom":
        queryset = queryset.filter(related_option_id = filter_option_value)

    queryset_data = queryset.first()
    if queryset_data:
        option_type = queryset_data.option_type
    else:
        return JsonResponse({"status": False, "error": "Invalid related chat id!"})
    # result_page = paginator.paginate_queryset(queryset, request)
    serialized_data = []

    for chat in queryset:

        if chat.chat_type == "End Message":
            return Response(
                {
                    "status": True,
                    "chat_id": chat.chat_id,
                    "chat_type": chat.chat_type,
                    "chat_name": chat.chat_name,
                    "message": chat.message,
                }
            )


        if option_type == "Table":
            table_uuid = chat.option_table_id if chat.option_table else None
            column_uuid = chat.option_column_id if chat.option_column else None

            # check  redirect true or false if true find the redirect name

            # initialize redirect name
            redirect_name = ""
            if chat.redirect == "Yes":
                redirect_name = MapTables.objects.filter(table_name__id = table_uuid).first().map_name

            prev_table_uuid = None
            prev_column_uuid = None


            if current_chat.option_type == "Table":
                prev_table_uuid = current_chat.option_table_id if current_chat.option_table else None
            options_data = []
            failure_flag = False
            failure_reason = None
            try:
                # ✅ Debug: Print category UUID before filtering
                # print(f"🔍 Filtering subcategories for category ID: {category_id}")

                # ✅ Fetch table object from TableList

                table_obj = TableList.objects.filter(id=table_uuid).first()
                prev_table_obj = TableList.objects.filter(id = prev_table_uuid).first()
                if not table_obj:
                    raise Exception(f"Table with UUID {table_uuid} not found")

                # ✅ Get the correct Django model name from table name
                table_name = table_obj.table_name
                prev_table_name = None
                if prev_table_obj:
                    prev_table_name = prev_table_obj.table_name

                # print(f"✅ Previous Table Name: {prev_table_name}")
                model_class_name = "".join(word.capitalize() for word in table_name.split("_"))

                prev_model_class_name = None
                if prev_table_name:
                    prev_model_class_name  = "".join(word.capitalize() for word in prev_table_name.split("-") )

                # ✅ Fetch column name from ColumnList
                column_obj = ColumnList.objects.filter(id=column_uuid).first()
                if not column_obj:
                    raise Exception(f"Column with UUID {column_uuid} not found")

                column_name = column_obj.column_name  # ✅ Get column name
                column_id = column_obj.column_id
                # print(f"✅ Column Name Fetched: {column_name}")

                # ✅ Fetch model dynamically
                table_model = apps.get_model("products", model_class_name)

                if not table_model:
                    raise Exception(f"Model '{model_class_name}' not found in 'products' app.")


                # ✅ Debug available fields in the model
                model_fields = [field.name for field in table_model._meta.fields]
                # print(f"✅ Available Fields in {model_class_name}: {model_fields}")
                # print(column_name)
                # print(column_id)
                from django.db.models import ManyToManyField
                m2m_fields = [
                    field.name
                    for field in table_model._meta.get_fields()
                    if isinstance(field, ManyToManyField) and not field.auto_created
                ]


                # ✅ Ensure column exists before querying

                if column_name not in model_fields or column_id not in model_fields:
                    raise Exception(f"Column '{column_name}' or '{column_id}' does not exist in model '{model_class_name}'")



                # find foriegn key

                foreign_column = ""


                #find previous chat with the id and get the table name...............
                if prev_model_class_name:
                    for wy in table_model._meta.get_fields():
                        if wy.get_internal_type() == "ForeignKey":
                            if wy.related_model._meta.db_table.split("_")[
                                1] == prev_table_name.lower():  # check foreign key related to previous chat table
                                # previous chat table
                                foreign_column = wy.name
                                break

                    # Filter using dynamic column name
                    try:
                        if order_type == "Shop":

                            if 'sales_unit' in m2m_fields:
                                field_filter = table_model.objects.filter(**{foreign_column: filter_option_value})
                                # sales unit filter
                                field_filter = field_filter.filter(sales_unit__in = [shop_id])
                                options_data = list(field_filter.values(column_id, column_name)) # Dynamic column filtering, #current column
                                options_data = paginator.paginate_queryset(options_data, request)
                            else:
                                options_data = list(table_model.objects.filter(**{foreign_column: filter_option_value}).values(column_id, column_name)) # Dynamic column filtering, #current column
                                options_data = paginator.paginate_queryset(options_data, request)
                        else:

                            if 'long_distance_availability' in model_fields:
                                field_filter = table_model.objects.filter(**{foreign_column: filter_option_value})
                                field_filter = field_filter.filter(long_distance_availability=True)
                                options_data = list(field_filter.values(column_id, column_name)) # Dynamic column filtering, #current column
                                options_data = paginator.paginate_queryset(options_data, request)
                            else:
                                options_data = list(table_model.objects.filter(**{foreign_column: filter_option_value}).values(column_id, column_name)) # Dynamic column filtering, #current column
                                options_data = paginator.paginate_queryset(options_data, request)

                    except:
                        # options_data = list(table_model.objects.values(column_id, column_name))
                        options_data = []
                else:
                    if order_type == "Shop":
                        if 'sales_unit' in m2m_fields:
                            field_filter= table_model.objects.filter(sales_unit__in = [shop_id])
                            options_data = list(field_filter.values(column_id, column_name))
                            options_data = paginator.paginate_queryset(options_data, request)


                        else:
                            options_data = list(table_model.objects.values(column_id, column_name))
                            options_data = paginator.paginate_queryset(options_data, request)
                    else:
                        if 'long_distance_availability' in model_fields:
                            field_filter = table_model.objects.filter(long_distance_availability=True)
                            options_data = list(field_filter.values(column_id,
                                                                    column_name))  # Dynamic column filtering, #current column
                            options_data = paginator.paginate_queryset(options_data, request)
                        else:
                            options_data = list(
                                table_model.objects.values(column_id,column_name))  # Dynamic column filtering, #current column
                            options_data = paginator.paginate_queryset(options_data, request)




                # ✅ Fetch ID and Value (Filtered by Category ID)
                # print("now....")
                # if category_id:
                #     options_data = list(
                #         table_model.objects.filter(category_id=category_id).values(column_id, column_name)
                #     )
                #     # print(f"✅ Filtered Subcategories Data: {options_data}")
                # else:
                #     options_data = list(table_model.objects.values(column_id,column_name))
                #     # print(options_data)

                # ✅ Apply Filtering by Option Value
                # if filter_option_value:
                #     options_data = [
                #         item for item in options_data if filter_option_value.lower() in item[column_name].lower()
                #     ]
                    # print(f"✅ Filtered by Option Value: {options_data}")
                # ✅ Fetch Product Names when subcategory_id is provided
                # product_data=[]
                # if subcategory_id:
                #     options_data = list(
                #         Products.objects.filter(item_sub_category_id=subcategory_id).values("id", "item_name")
                #     )

            except Exception as e:
                failure_flag = True
                failure_reason = str(e)
                # options_data = [{"id": None, "value": f"Error: {str(e)}"}]
            if failure_flag:
                data_to_append = {
                    "status": False,
                    "error": failure_reason,
                    "chat_id": chat.chat_id,
                    "chat_name": chat.chat_name,
                    "chat_type": chat.chat_type,
                    "message": chat.message,
                    "option_type": chat.option_type,
                    "related_chat": chat.related_chat.chat_id if chat.related_chat else None,
                    "options": [{"id": item.get(column_id), "value": item.get(column_name, "Field Not Found")} for item in
                                options_data],
                    "redirect": True if chat.redirect == "Yes" else False,
                    "redirect_name" : redirect_name if chat.redirect == "Yes" else None
                    # "products": [{"id": prod.get("id"), "name": prod.get("item_name")} for prod in options_data],
                    # ✅ New: Products data
                }
            else:
                data_to_append = {
                    "status": True,
                    "chat_id": chat.chat_id,
                    "chat_name": chat.chat_name,
                    "chat_type": chat.chat_type,
                    "message": chat.message,
                    "option_type": chat.option_type,
                    "related_chat": chat.related_chat.chat_id if chat.related_chat else None,
                    "options": [{"id": item.get(column_id), "value": item.get(column_name, "Field Not Found")} for item in
                                options_data],
                    "redirect": True if chat.redirect == "Yes" else False,
                    "redirect_name": redirect_name if chat.redirect else None
                    # "products": [{"id": prod.get("id"), "name": prod.get("item_name")} for prod in options_data],
                    # ✅ New: Products data
                }
                # if model_class_name == "Products":
                #     data_to_append["redirect"] = True
            serialized_data.append(data_to_append )
            try:
                return paginator.get_paginated_response(serialized_data)
            except Exception as e:

                return JsonResponse( {
                        "status": False,
                        "error": str(e),
                        "chat_id": chat.chat_id,
                        "chat_name": chat.chat_name,
                        "chat_type": chat.chat_type,
                        "option_type": chat.option_type,
                        "message": chat.message,
                        "related_chat": chat.related_chat.chat_id if chat.related_chat else None,
                        # ✅ New: Products data
                    })


        elif option_type == "Custom":

            try:

                options  = list(chat.options.all())
                option_list = [ {"id": i.id , "value": i.option_value }for i in options]
                option_list = paginator.paginate_queryset(option_list, request)
                serialized_data.append(
                    {
                        "status": True,
                        "chat_id": chat.chat_id,
                        "chat_name": chat.chat_name,
                        "chat_type": chat.chat_type,
                        "option_type": chat.option_type,
                        "message": chat.message,
                        "related_chat": chat.related_chat.chat_id if chat.related_chat else None,
                        "options": option_list,
                        # ✅ New: Products data
                    }
                )
            except Exception as e:
                return JsonResponse( {
                        "status": False,
                        "error": str(e),
                        "chat_id": chat.chat_id,
                        "chat_name": chat.chat_name,
                        "chat_type": chat.chat_type,
                        "option_type": chat.option_type,
                        "message": chat.message,
                        "related_chat": chat.related_chat.chat_id if chat.related_chat else None,
                        # ✅ New: Products data
                    })





    try:
        return paginator.get_paginated_response(serialized_data)
    except:
        return JsonResponse({"status": False, "error": "page not found"})

# @api_view(["GET"])
# def product_name(request):
#     subcategory_id = "5a683284-e105-4cf5-9248-967025fcdbad"  # Replace with dynamic input if needed

#     # ✅ Ensure filtering works with UUID
#     products = Products.objects.filter(item_sub_category_id=subcategory_id).values("id", "item_name")

#     # ✅ Print Debug Output
#     print(f"🔍 DEBUG: Products found: {list(products)}")

#     # ✅ Return JSON Response
#     return Response({"products": list(products)})


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def related_option_list(request, chat_id):
    """ Fetch Related Chat List """
    chat_data = Chat_Data.objects.filter(chat_id=chat_id)

    related_option_ids = [(i.related_option_id.id, i.related_option_id.option_value) for i in Chat_Data.objects.all() if i.related_option_id]

    options = chat_data.options
    options_to_render = []
    for i in options.all():
        if(i.related_option_id.id, i.related_option_id.option_value) not in related_option_ids:
            options_to_render.append({"option_name":i.related_option_id.id, "option_value":i.related_option_id.option_value})

    return JsonResponse({"options": options_to_render}, safe=False)


def check_related(request):
    option_id = request.GET.get("uuid")
    # queryset = RelatedOptionTable.objects.filter(id=option_id).first()
    queryset = Chat_Data.objects.filter(related_option_id__id = option_id ).first()
    if queryset:
        return JsonResponse({"status": "related"})
    else:
        return JsonResponse({"status": "not related"})


@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_tables(request):
    tables = ColumnList.objects.order_by("-created_date")

    paginator = Paginator(tables, 10)
    page = request.GET.get("page")
    try:
        tables = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        tables = paginator.get_page(1)
    except EmptyPage:
        tables = paginator.get_page(paginator.num_pages)

    context = {"tables": tables, "chat_active": "active"}
    return render(request, "chat_table_list.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_tables_edit(request, table_id):
    errors = []
    table = get_object_or_404(TableList, pk=table_id)
    column = get_object_or_404(ColumnList, table = table_id)
    if request.method == "POST":
        table_form = TableListForm(request.POST, instance=table)
        column_form = ColumnListForm(request.POST, instance = column)
        if table_form.is_valid() and column_form.is_valid():
            table_data = table_form.save()
            column_data = column_form.save(commit = False)
            column_data.table =table_data
            column_data.save()
            return redirect("chat_table_list")

        else:
            errors.append(table_form.errors)
            errors.append(column_form.errors)
    else:
        table_form = TableListForm(instance=table)
        column_form = ColumnListForm(instance= column)
    context = {"errors": errors, "table_form": table_form, "column_form": column_form, "chat_active": "active"}
    return render(request, "chat_table_edit.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def chat_tables_add(request):
    errors = []
    if request.method == "POST":
        table_form = TableListForm(request.POST)
        column_form = ColumnListForm(request.POST)
        if table_form.is_valid() and column_form.is_valid():
            table_data = table_form.save()
            column_data = column_form.save(commit = False)
            column_data.table =table_data
            column_data.save()
            return redirect("chat_table_list")
        else:
            errors.append(table_form.errors)
            errors.append(column_form.errors)
    else:
        table_form = TableListForm()
        column_form = ColumnListForm()

        errors = []

    context = {
        "errors": errors,
        "table_form": table_form,
        "column_form": column_form,
        "chat_active": "active"

    }
    return render(request, "chat_table_add.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def table_chat_delete(request, table_id):
    table = TableList.objects.filter(pk=table_id)
    column = ColumnList.objects.filter(table = table_id)

    if table and column:
        table.delete()
        column.delete()
    return redirect("chat_table_list")


@api_view(["POST"])
def send_user_query(request):
    if request.method == "POST":
        try:
            msg = request.data.get('msg', "")
            admin_user_mail_id = "akhilraj3200@gmail.com"
            if request.user.is_authenticated:

                subject = f"User Query ({request.user.email}-{request.user.phone_number})"
                if request.user.first_name:
                    user_name = request.user.first_name
                else:
                    user_name = "user"
                message  = f"User enquiry recieved from {user_name} please check: \n\n" + f"'{msg}'"
                send_mail(
                    subject, message, EMAIL_HOST_USER, [admin_user_mail_id], fail_silently=False
            )
                return JsonResponse({"status": True, "message": "Email send successfully!"})
            else:
                return JsonResponse({"status": False, "message": "user not authenticated"})
        except Exception as e:
            return JsonResponse({"status": False, "message": "message send failed!", "error": str(e)})
    else:
        return JsonResponse({"status": False, "message": "Post method required!"})




@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def map_tables(request):
    tables = MapTables.objects.order_by("-created_date")

    paginator = Paginator(tables, 10)
    page = request.GET.get("page")
    try:
        tables = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        tables = paginator.get_page(1)
    except EmptyPage:
        tables = paginator.get_page(paginator.num_pages)

    context = {"tables": tables, "chat_active": "active"}
    return render(request, "map_table_list.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def map_table_edit(request, table_id):
    errors = []
    map_table = get_object_or_404(MapTables, pk=table_id)
    if request.method == "POST":
        map_table_form = MapForm(request.POST, instance=map_table)
        if map_table_form.is_valid() :
            map_table_data = map_table_form.save()
            return redirect("chat_table_map_list")
        else:
            errors.append(map_table_form.errors)
    else:
        map_table_form = MapForm(instance=map_table)

    context = {"errors": errors, "map_table_form": map_table_form, "chat_active": "active"}
    return render(request, "map_table_edit.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def map_table_add(request):
    errors = []
    if request.method == "POST":
        map_table_form = MapForm(request.POST)
        if map_table_form.is_valid():
            table_data = map_table_form.save()
            return redirect("chat_table_map_list")
        else:
            errors.append(map_table_form.errors)
    else:
        map_table_form = MapForm()

        errors = []

    context = {
        "errors": errors,
        "map_table_form": map_table_form,
        "chat_active": "active"

    }
    return render(request, "map_table_add.html", context)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def map_table_delete(request, table_id):
    map_table = MapTables.objects.filter(id=table_id)

    if map_table:
        map_table.delete()
    return redirect("chat_table_map_list")
