from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login as auth_login, logout
from django.contrib.auth.decorators import user_passes_test, login_required
from rest_framework.decorators import api_view
from django.views.decorators.http import require_POST
from django.forms.models import inlineformset_factory
from django.db.models import Sum, Avg,  DateTimeField
from django.core.exceptions import ValidationError
from django.db.models import F
import razorpay
import hmac
import hashlib
import json
import twilio
from django.views.decorators.csrf import csrf_exempt
from datetime import datetime, date, timezone
import requests, random


from django.shortcuts import get_object_or_404
from django.conf import settings
from django.http import JsonResponse, HttpResponse
from django.contrib import messages
from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.apps import apps

from cms.models import FAQ, AboutUs, AppUrl, ContactUs, PrivacyPolicy, TermsAndConditions
from .forms import AboutUsForm, AppUrlForm, ContactUsForm, FAQForm, PrivacyPolicyForm, ShopForm, StoreUserForm, TermsAndConditionsForm, UserEditForm, UserForm, UserModalForm, BankDetailsForm, CategoryForm, ProductSubCategoryForm, ProductForm, TagForm, DynamicFilterForm, SpecialListForm, DeliveryBoyForm, SKUForm, CourierDetailsForm, CouponForm, DeliverySlotForm, DiscountForm, AdForm, CustomProductForm, ProductionUnitForm, CustomOrderForm, MessageForm
from shops.models import Shop, BankDetails, ProductionUnit
from products.models import ProductCategory, ProductSubCategory, Products, SalesUnitProductSelection, ProductImage, ProductVideo, Tags, DynamicFiltering, SpecialList, SKU, CustomProduct, CustomProductImage, CustomProductVideo
from accounts.models import *
from orders.models import DeliveryBoys, Orders, OrderDelivery, Coupons, DeliverySlot, Discount, Ads, Payment, Communication, Message
from django.core.mail import send_mail
from NavyaBackers.settings import EMAIL_HOST_USER
import string, secrets
from datetime import timedelta
from accounts.views import send_notification, initialize_fcm_app

from datetime import datetime
from django.urls import reverse
from django.contrib.auth.models import Group
from django.db.models import Count,Q, F
from django.template.loader import render_to_string
from dal import autocomplete
import requests


from rest_framework.permissions import IsAuthenticated
import jwt
from django.conf import settings
from django.core.mail import send_mail
from django.urls import reverse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from django.core.mail import EmailMessage
import os
from accounts.models import LoggingOperation


def generate_random_password(length=8):
    characters = string.ascii_letters + string.digits
    return ''.join(secrets.choice(characters) for _ in range(length))


def login(request):
    error = {}
    if request.method == "POST":
        email = request.POST.get("username", "")
        password = request.POST.get("password", "")
        user = authenticate(request, username=email, password=password)
        if user is not None:
            auth_login(request, user)
            return redirect("homepage")
        else:
            error = {"message": "invalid username or password"}
    return render(request, "login.html", error)


def check_user_role(allowed_roles):
    def inner_function(user):
        return user.user_type in allowed_roles

    return inner_function


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin", "Shop Admin", "PU Admin"]))
def home_page(request):
    context = {}
    today = timezone.now().date()
    shop_id_verify = None
    if(request.user.user_type == "Shop Admin"):
        shop_id_verify = Shop.objects.prefetch_related('unit_admin_user').filter(
        unit_admin_user__uuid=request.user.uuid)
        if shop_id_verify:

            shop_id = shop_id_verify[0]
            request.session['product_view'] = 'Yes'
            orders_today = Orders.objects.exclude(order_status__in=["Failed", "New Order"]).filter(
                created_date__date=today, store_uuid=shop_id.uuid).count()
            new_order_today = Orders.objects.filter(created_date__date=today, order_status='Confirmed',
                                                    store_uuid=shop_id.uuid).count()
            failed_order_today = Orders.objects.filter(created_date__date = today, order_status= "Failed",store_uuid=shop_id.uuid ).count()
            if orders_today:
                avg_failed_orders = round((failed_order_today / orders_today) * 100, 2)
            else:
                avg_failed_orders = 0
            fulfiled_order = Orders.objects.filter(created_date__date=today, order_status='Delivered',
                                                   store_uuid=shop_id.uuid).count()
            currently_unassigned_order = Orders.objects.filter(created_date__date=today,
                                                               order_status__in=["Confirmed","Viewed", "Order Packed"],
                                                               store_uuid=shop_id.uuid).count()
            total_orders = Orders.objects.filter(store_uuid=shop_id.uuid).exclude(order_status__in=["New Order"]).count()
            today_revenue = Orders.objects.filter(created_date__date=today, store_uuid=shop_id.uuid).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
                today_revenue=Sum('grand_total'))
            today_revenue_data = 0
            if today_revenue['today_revenue']:
                today_revenue_data = round(today_revenue['today_revenue'] if today_revenue['today_revenue'] else 0 , 2)
            last_week_start = today - timedelta(days=7)
            week_before_last_week = last_week_start - timedelta(days=7)
            week_revenue = Orders.objects.filter(created_date__date__gte=last_week_start,
                                                 created_date__date__lte=today, store_uuid=shop_id.uuid).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
                week_revenue=Sum('grand_total'))

            week_before_last_week_revenue = Orders.objects.filter(created_date__date__gte=week_before_last_week,
                                                                  created_date__date__lte=last_week_start,
                                                                  store_uuid=shop_id.uuid).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
                last_week_revenue=Sum('grand_total'))
            revenue_difference_output = {}
            if week_revenue['week_revenue'] and week_before_last_week_revenue['last_week_revenue']:
                week_revenue_percent_with_week = round(
                    (week_revenue['week_revenue'] / week_before_last_week_revenue['last_week_revenue']) * 100, 2)
                if week_revenue_percent_with_week > 100:
                    week_revenue_percent_with_week = week_revenue_percent_with_week - 100
                    revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                    revenue_difference_output['flag'] = 'increase'
                else:
                    week_revenue_percent_with_week = 100 - week_revenue_percent_with_week
                    revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week, 2)
                    revenue_difference_output['flag'] = 'decrease'

            else:
                if week_revenue['week_revenue'] and not week_before_last_week_revenue['last_week_revenue']:
                    week_revenue_percent_with_week = 100
                    revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week, 2)
                    revenue_difference_output['flag'] = 'increase'
                else:
                    week_revenue_percent_with_week = 0
                    revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                    revenue_difference_output['flag'] = 'increase'

            last_week_revenue_avg = Orders.objects.filter(store_uuid=shop_id.uuid,
                                                          created_date__date__gte=last_week_start,
                                                          created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(last_week_avg_revenue=Avg('grand_total'))
            revenue_percent_data = {}
            if today_revenue['today_revenue'] and last_week_revenue_avg['last_week_avg_revenue']:
                today_revenue_percent_with_week = round((today_revenue['today_revenue'] / last_week_revenue_avg[
                    'last_week_avg_revenue']) * 100, 2)
                if today_revenue_percent_with_week > 100:
                    today_revenue_percent_with_week = today_revenue_percent_with_week - 100
                    revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week, 2)
                    revenue_percent_data['flag'] = 'increase'
                else:
                    today_revenue_percent_with_week = 100 - today_revenue_percent_with_week
                    revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                    revenue_percent_data['flag'] = 'decrease'

            else:
                if today_revenue['today_revenue'] and not last_week_revenue_avg['last_week_avg_revenue']:
                    today_revenue_percent_with_week = 100
                    revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week, 2)
                    revenue_percent_data['flag'] = 'increase'
                else:
                    today_revenue_percent_with_week = 0
                    revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week, 2)
                    revenue_percent_data['flag'] = 'increase'

            last_week_revenue_count = Orders.objects.filter(store_uuid=shop_id.uuid,
                                                            created_date__date__gte=last_week_start,
                                                            created_date__date__lte =today).exclude(order_status__in = ["New Order", "Failed"]).count()
            revenue_count_data = {}
            if orders_today and last_week_revenue_count:
                today_count_percent_with_week = round((orders_today / last_week_revenue_count), 2) * 100
                if today_count_percent_with_week > 100:
                    today_count_percent_with_week = today_count_percent_with_week - 100
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'increase'
                else:
                    today_count_percent_with_week = 100 - today_count_percent_with_week
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'decrease'
            else:
                if orders_today and not last_week_revenue_count:
                    today_count_percent_with_week = 100
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week, 2)
                    revenue_count_data['flag'] = 'increase'
                else:
                    today_count_percent_with_week = 0
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week, 2)
                    revenue_count_data['flag'] = 'increase'

            month_revenue = Orders.objects.filter(created_date__year=today.year,
                                                  created_date__month=today.month, store_uuid=shop_id.uuid).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
                month_revenue=Sum('grand_total'))
            month_revenue['month_revenue'] = round(month_revenue['month_revenue'] if month_revenue['month_revenue'] else 0 , 2)
            delivery_success_percentage = 0
            if fulfiled_order and orders_today:
                delivery_success_percentage = round((fulfiled_order / orders_today) * 100, 2)
            avg_today_revenue = Orders.objects.filter(store_uuid=shop_id.uuid, created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
                today_revenue=Avg('grand_total'))
            avg_today_revenue_data = 0
            if avg_today_revenue['today_revenue']:
                avg_today_revenue_data = round(avg_today_revenue['today_revenue'], 2)
            results = Orders.objects.filter(store_uuid=shop_id.uuid,created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).values('store_uuid__unit_name').annotate(
                total_amount=Sum('grand_total')).order_by(
                '-total_amount')[:5]


            for i in results:
                if i['total_amount']:
                    i['total_amount'] = round(i['total_amount'], 2)
            context = {"orders_today": orders_today, 'new_order_today': new_order_today,
                       "fulfiled_order": fulfiled_order,
                       'currently_unassigned_order': currently_unassigned_order,
                       "failed_order": failed_order_today,
                       "avg_failed_order": avg_failed_orders,
                       'total_orders': total_orders, 'today_revenue': today_revenue_data,
                       'month_revenue': month_revenue, "grand_total_by_store": results,
                       'today_count_percent_with_week': revenue_count_data,
                       'today_revenue_percent_with_week': revenue_percent_data,
                       'delivery_success_percentage': delivery_success_percentage,
                       'avg_today_revenue': avg_today_revenue_data,
                       'revenue_difference_output': revenue_difference_output, 'home_active': "active"}


    elif request.user.user_type == "NBC Admin" or request.user.user_type == "Super Admin":
        request.session["product_view"] = 'No'
        orders_today = Orders.objects.exclude(order_status__in=["Failed", "New Order"]).filter(
            created_date__date=today ).count()
        new_order_today = Orders.objects.filter(created_date__date=today, order_status='Confirmed').count()
        failed_order_today = Orders.objects.filter(created_date__date=today, order_status="Failed").count()
        if orders_today:
            avg_failed_orders = round((failed_order_today / orders_today) * 100, 2)
        else:
            avg_failed_orders = 0
        fulfiled_order = Orders.objects.filter(created_date__date=today, order_status='Delivered').count()
        currently_unassigned_order = Orders.objects.filter(order_status__in=["Confirmed","Viewed", "Order Packed"], created_date__date=today).count()
        last_week_start = today - timedelta(days=7)

        week_before_last_week = last_week_start - timedelta(days=7)
        week_revenue = Orders.objects.filter(created_date__date__gte=last_week_start,
                                             created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            week_revenue=Sum('grand_total'))
        week_before_last_week_revenue = Orders.objects.filter(created_date__date__gte=week_before_last_week,
                                                              created_date__date__lte=last_week_start).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            last_week_revenue=Sum('grand_total'))
        revenue_difference_output = {}


        if week_revenue['week_revenue'] and week_before_last_week_revenue['last_week_revenue']:
            week_revenue_percent_with_week = round((week_revenue['week_revenue'] / week_before_last_week_revenue['last_week_revenue'])  * 100, 2)
            if week_revenue_percent_with_week > 100:
                week_revenue_percent_with_week = week_revenue_percent_with_week - 100
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'
            else:
                week_revenue_percent_with_week = 100 - week_revenue_percent_with_week
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'decrease'

        else:
            if  week_revenue['week_revenue'] and not week_before_last_week_revenue['last_week_revenue']:
                week_revenue_percent_with_week = 100
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'
            else:
                week_revenue_percent_with_week = 0
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'


        last_week_revenue_avg =  Orders.objects.filter(created_date__date__gte=last_week_start,
    created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            last_week_avg_revenue=Avg('grand_total'))
        today_revenue = Orders.objects.filter(created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(today_revenue=Sum('grand_total'))
        today_revenue_data = 0
        if today_revenue['today_revenue']:
            today_revenue_data = round(today_revenue['today_revenue'], 2)
        revenue_percent_data = {}
        if today_revenue['today_revenue'] and last_week_revenue_avg['last_week_avg_revenue']:
            today_revenue_percent_with_week = round((today_revenue['today_revenue'] / last_week_revenue_avg['last_week_avg_revenue'])  * 100, 2)
            if today_revenue_percent_with_week > 100:
                today_revenue_percent_with_week = today_revenue_percent_with_week - 100
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
            else:
                today_revenue_percent_with_week = 100 - today_revenue_percent_with_week
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'decrease'

        else:
            if today_revenue['today_revenue'] and not last_week_revenue_avg['last_week_avg_revenue']:
                today_revenue_percent_with_week = 100
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
            else:
                today_revenue_percent_with_week = 0
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
        last_week_revenue_count = Orders.objects.filter(created_date__date__gte=last_week_start,
                                                      created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).count()
        revenue_count_data = {}
        if orders_today and last_week_revenue_count:
            today_count_percent_with_week = round((orders_today/last_week_revenue_count)*100, 2)
            if today_count_percent_with_week > 100:
                today_count_percent_with_week = today_count_percent_with_week - 100
                revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                revenue_count_data['flag'] = 'increase'
            else:
                today_count_percent_with_week = 100 - today_count_percent_with_week
                revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                revenue_count_data['flag'] = 'decrease'
        else:
                if orders_today and not last_week_revenue_count:
                    today_count_percent_with_week = 100
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'increase'
                else:
                    today_count_percent_with_week = 0
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'increase'

        delivery_success_percentage = 0

        if fulfiled_order and orders_today:
            delivery_success_percentage = round((fulfiled_order/orders_today)*100, 2)
        avg_today_revenue = Orders.objects.filter(created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(today_revenue=Avg('grand_total'))

        avg_today_revenue_data = 0
        if avg_today_revenue['today_revenue']:
            avg_today_revenue_data = round(avg_today_revenue['today_revenue'], 2)


        total_orders = Orders.objects.exclude(order_status__in=["New Order"]).count()

        month_revenue = Orders.objects.filter(created_date__year=today.year,
                                              created_date__month=today.month, order_status = "Delivered").aggregate(
            month_revenue=Sum('grand_total'))
        month_revenue['month_revenue'] = round(month_revenue['month_revenue'] if month_revenue['month_revenue'] else 0, 2)
        results = Orders.objects.filter(created_date__date=today, order_type ="Local Orders").exclude(order_status__in = ["New Order", "Failed"]).values('store_uuid__unit_name').annotate(total_amount=Sum('grand_total')).order_by(
            '-total_amount')[:5]
        for i in results:
            if i['total_amount']:
                i['total_amount'] = round(i['total_amount'], 2)
        context = {"orders_today": orders_today, 'new_order_today': new_order_today, "fulfiled_order": fulfiled_order,
                   'currently_unassigned_order': currently_unassigned_order,
                   # 'orders_over_5_hours': orders_over_5_hours,
                   "failed_order": failed_order_today,
                   "avg_failed_orders": avg_failed_orders,
                   'total_orders': total_orders, 'today_revenue': today_revenue_data,
                   'month_revenue': month_revenue, "grand_total_by_store": results, 'today_count_percent_with_week':revenue_count_data,'today_revenue_percent_with_week': revenue_percent_data,'delivery_success_percentage':delivery_success_percentage,
                   'avg_today_revenue':avg_today_revenue_data,'revenue_difference_output': revenue_difference_output,'home_active': "active"}




    elif request.user.user_type == "PU Admin":
        request.session["product_view"] = 'No'
        orders_today = Orders.objects.exclude(order_status__in=["Failed", "New Order"]).filter(
            order_type="Long Distance Orders",
            created_date__date=today ).count()
        new_order_today = Orders.objects.filter(created_date__date=today, order_status='Confirmed', order_type = "Long Distance Orders").count()
        fulfiled_order = Orders.objects.filter(created_date__date=today, order_status='Delivered', order_type = "Long Distance Orders").count()
        failed_order_today = Orders.objects.filter(created_date__date=today, order_status="Failed",order_type = "Long Distance Orders").count()
        if orders_today:
            avg_failed_orders = round((failed_order_today / orders_today) * 100, 2)
        else:
            avg_failed_orders = 0
        currently_unassigned_order = Orders.objects.filter(order_status__in=["Confirmed","Viewed", "Order Packed"], created_date__date=today, order_type = "Long Distance Orders").count()
        last_week_start = today - timedelta(days=7)

        week_before_last_week = last_week_start - timedelta(days=7)
        week_revenue = Orders.objects.filter(order_type = "Long Distance Orders",created_date__date__gte=last_week_start,
                                             created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            week_revenue=Sum('grand_total'))
        week_before_last_week_revenue = Orders.objects.filter(order_type = "Long Distance Orders",created_date__date__gte=week_before_last_week,
                                                              created_date__date__lte=last_week_start).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            last_week_revenue=Sum('grand_total'))
        revenue_difference_output = {}
        if week_revenue['week_revenue'] and week_before_last_week_revenue['last_week_revenue']:
            week_revenue_percent_with_week = round(
                (week_revenue['week_revenue'] / week_before_last_week_revenue['last_week_revenue']) * 100, 2)
            if week_revenue_percent_with_week > 100:
                week_revenue_percent_with_week = week_revenue_percent_with_week - 100
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'
            else:
                week_revenue_percent_with_week = 100 - week_revenue_percent_with_week
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'decrease'

        else:
            if week_revenue['week_revenue'] and not week_before_last_week_revenue['last_week_revenue']:
                week_revenue_percent_with_week = 100
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'
            else:
                week_revenue_percent_with_week = 0
                revenue_difference_output['revenue_difference'] = round(week_revenue_percent_with_week,2)
                revenue_difference_output['flag'] = 'increase'

        last_week_revenue_avg =  Orders.objects.filter(order_type = "Long Distance Orders",created_date__date__gte=last_week_start,
    created_date__date__lte=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            last_week_avg_revenue=Avg('grand_total'))
        today_revenue = Orders.objects.filter(order_type = "Long Distance Orders",created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(today_revenue=Sum('grand_total'))
        today_revenue_data = 0
        if today_revenue['today_revenue']:
            today_revenue_data = round(today_revenue['today_revenue'], 2)
        revenue_percent_data = {}
        if today_revenue['today_revenue'] and last_week_revenue_avg['last_week_avg_revenue']:
            today_revenue_percent_with_week = round((today_revenue['today_revenue'] / last_week_revenue_avg[
                'last_week_avg_revenue']) * 100, 2)
            if today_revenue_percent_with_week > 100:
                today_revenue_percent_with_week = today_revenue_percent_with_week % 100
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
            else:
                today_revenue_percent_with_week = 100 % today_revenue_percent_with_week
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'decrease'

        else:
            if today_revenue['today_revenue'] and not last_week_revenue_avg['last_week_avg_revenue']:
                today_revenue_percent_with_week = 100
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
            else:
                today_revenue_percent_with_week = 0
                revenue_percent_data['today_revenue_percent_with_week'] = round(today_revenue_percent_with_week,2)
                revenue_percent_data['flag'] = 'increase'
        last_week_revenue_count = Orders.objects.filter(order_type = "Long Distance Orders",created_date__date__gte=last_week_start,
                                                      created_date__date__lte=today, order_status = "Delivered").count()
        revenue_count_data = {}
        if orders_today and last_week_revenue_count:
            today_count_percent_with_week = round((orders_today/last_week_revenue_count)*100,2)
            if today_count_percent_with_week > 100:
                today_count_percent_with_week = today_count_percent_with_week - 100
                revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                revenue_count_data['flag'] = 'increase'
            else:
                today_count_percent_with_week = 100 - today_count_percent_with_week
                revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                revenue_count_data['flag'] = 'decrease'
        else:
                if orders_today and not last_week_revenue_count:
                    today_count_percent_with_week = 100
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'increase'
                else:
                    today_count_percent_with_week = 0
                    revenue_count_data['today_count_percent_with_week'] = round(today_count_percent_with_week,2)
                    revenue_count_data['flag'] = 'increase'

        delivery_success_percentage = 0

        if fulfiled_order and orders_today:
            delivery_success_percentage = round((fulfiled_order/orders_today)*100, 2)
        avg_today_revenue = Orders.objects.filter(order_type = "Long Distance Orders",created_date__date=today).exclude(order_status__in = ["New Order", "Failed"]).aggregate(today_revenue=Avg('grand_total'))
        avg_today_revenue_data = 0
        if avg_today_revenue['today_revenue']:
            avg_today_revenue_data = round(avg_today_revenue['today_revenue'], 2)


        total_orders = Orders.objects.filter(order_type = "Long Distance Orders").exclude(order_status__in=["New Order"]).count()

        month_revenue = Orders.objects.filter(order_type = "Long Distance Orders",created_date__year=today.year,
                                              created_date__month=today.month).exclude(order_status__in = ["New Order", "Failed"]).aggregate(
            month_revenue=Sum('grand_total'))
        month_revenue['month_revenue'] = round(month_revenue['month_revenue'] if month_revenue['month_revenue'] else 0, 2)
        results = Orders.objects.filter(created_date__date=today,order_type = "Long Distance Orders").exclude(order_status__in = ["New Order", "Failed"]).values('pu_uuid__pu_name').annotate(total_amount=Sum('grand_total')).order_by(
            '-total_amount')[:5]
        for i in results:
            if i['total_amount']:
                i['total_amount'] = round(i['total_amount'], 2)
        context = {"orders_today": orders_today, 'new_order_today': new_order_today, "fulfiled_order": fulfiled_order,
                   'currently_unassigned_order': currently_unassigned_order,
                   "failed_order": failed_order_today,
                   "avg_failed_orders": avg_failed_orders,
                   'total_orders': total_orders, 'today_revenue': today_revenue_data,
                   'month_revenue': month_revenue, "grand_total_by_pu": results, 'today_count_percent_with_week':revenue_count_data,'today_revenue_percent_with_week': revenue_percent_data,'delivery_success_percentage':delivery_success_percentage,
                   'avg_today_revenue':avg_today_revenue_data,'revenue_difference_output': revenue_difference_output,'home_active': "active"}

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
















@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def shop_list(request):
    shops = Shop.objects.order_by("-created_at")
    paginator = Paginator(shops, 10)
    page = request.GET.get("page")
    try:
        shops = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        shops = paginator.get_page(1)
    except EmptyPage:
        shops = paginator.get_page(paginator.num_pages)
    context = {"shop_data": shops, "sales_unit_active": "active"}
    return render(request, "shop_list.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def shop_add(request):
    errors = []
    user_modal_form = UserModalForm()
    if request.method == "POST":
        shop_form = ShopForm(request.POST)
        bank_form = BankDetailsForm(request.POST)
        if shop_form.is_valid() and bank_form.is_valid():
            shop = shop_form.save()
            bank_details = bank_form.save(commit=False)
            bank_details.shop = shop
            bank_details.save()
            product_enter_list = []
            # for i in Products.objects.filter(product_type = "Master Product"):
            #     product_enter_list.append(SalesUnitProductSelection(sales_unit = shop,  product = i,  status="Visible"))
            # SalesUnitProductSelection.objects.bulk_create(product_enter_list)
            subject = "Shop created"
            message = "New shop assigned you as the unit admin user"
            for user in shop.unit_admin_user.all():
                send_mail(
                    subject, message, EMAIL_HOST_USER, [user.email], fail_silently=True
                )
            try:
                log_user = request.user
                log_type = "shop"
                message = "Shop Created"
                description = f"Shop {shop.unit_name} created with code {shop.unit_code}"
                LoggingOperation.objects.create(user=log_user,log_type=log_type,message=message, description=description)
            except:
                pass

            return redirect("shop_list")
        else:
            errors.append(shop_form.errors)
            shop_error_columns = list(shop_form.errors.keys())
            bank_error_columns = list(bank_form.errors.keys())
            error_list = shop_error_columns + bank_error_columns
            step1_columns = ["unit_name","unit_code","unit_location","email","contact_no","status","unit_admin_user","delivery_mode","delivery_radius"]
            step2_colums = ["latitude","longitude","street","city","state_or_province","district","pin_code"]
            step3_columns = ["account_name","bank_name","branch_name","ifsc_code","account_number", "gst"]
            step1 = set(error_list) & set(step1_columns)
            step2 = set(error_list) & set(step2_colums)
            step3 = set(error_list) & set(step3_columns)
            page = 0
            if step1 :
                page = 0
            elif step2:
                page = 1
            elif step3:
                page = 2
            context = {
                "errors": errors,
                "shop_form": shop_form,
                "bank_form": bank_form,
                "user_modal_form": user_modal_form,
                "show_modal": "modal_hide",
                "sales_unit_active": "active",
                "page" : page
            }
            return render(request, "shop_add.html", context)
    else:
        shop_form = ShopForm()
        bank_form = BankDetailsForm()
        errors = []
    context = {
        "errors": errors,
        "shop_form": shop_form,
        "bank_form": bank_form,
        "user_modal_form": user_modal_form,
        "show_modal": "modal_hide",
        "sales_unit_active": "active",
        "page": 0,
    }
    return render(request, "shop_add.html", context)


@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def shop_delete(request, shop_id):
    shop = Shop.objects.filter(pk=shop_id)
    if shop:
        SalesUnitProductSelection.objects.filter(sales_unit=shop_id).delete()
        shop_data = shop.first()
        shop.delete()
        try:
            log_user = request.user
            log_type = "shop"
            message = "Shop Deleted"
            description = f"Shop {shop_data.unit_name}  with code {shop_data.unit_code} deleted"
            LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
        except Exception as e:
            print(e)
            pass
    return redirect("shop_list")

def category_delete(request, category_id):
    category = get_object_or_404(ProductCategory, uuid=category_id)
    sub_category = ProductSubCategory.objects.filter(category = category)

    if sub_category:
        messages.warning(request,"Couldn't delete subcategories exists")

    elif category:
        category.delete()
        try:
            log_user = request.user
            log_type = "product"
            message = "Category Deleted"
            description = f"Cagegory {category.category_name}  with code {category.category_code} deleted"
            LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
        except:
            pass
        messages.success(request, "Category deleted successfully")
    else:
        messages.warning(request, "Something went wrong")
    return redirect("list_category")


def sub_category_delete(request, sub_category_id):

    sub_category = ProductSubCategory.objects.get(uuid = sub_category_id)
    category_id = sub_category.category.uuid
    if sub_category:
        sub_category.delete()

        try:
            log_user = request.user
            log_type = "product"
            message = "Sub category deleted"
            description = f"Sub category {sub_category.sub_category_name}  with code {sub_category.sub_category_code} deleted for category {sub_category.category.category_name} with code {sub_category.category.category_code}"
            LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
        except:
            pass


    return redirect(f"/adminportal/add-sub-category/{str(category_id)}/")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def shop_edit(request, shop_id=None):
    shop = get_object_or_404(Shop, pk=shop_id)
    existing_shop_status = shop.status
    bank_details = BankDetails.objects.filter(shop=shop).first()
    errors = []
    if request.method == "POST":
        shop_form = ShopForm(request.POST, instance=shop)
        bank_form = BankDetailsForm(request.POST, instance=bank_details)
        if shop_form.is_valid() and bank_form.is_valid():
            shop = shop_form.save()
            bank_details = bank_form.save(commit=False)
            bank_details.shop = shop
            bank_details.save()
            if existing_shop_status != shop.status:
                for user in shop.unit_admin_user.all():
                    subject = "Shop status updated"
                    message = f"Your shop {shop.unit_name} changed their status to {shop.status}"
                    send_mail(
                        subject, message, EMAIL_HOST_USER, [user.email], fail_silently=True
                    )
            try:
                log_user = request.user
                log_type = "shop"
                message = "Shop Updated"
                f"Shop {shop.unit_name}  with code {shop.unit_code} deleted"
                description =  f"Shop {shop.unit_name}  with code {shop.unit_code} updated"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except Exception as e:
                print(e)

                pass
            return redirect("shop_list")
        else:
            errors.append(shop_form.errors)
            errors.append(bank_form.errors)

            shop_error_columns = list(shop_form.errors.keys())
            bank_error_columns = list(bank_form.errors.keys())
            error_list = shop_error_columns + bank_error_columns
            step1_columns = ["unit_name","unit_code","unit_location","email","contact_no","status","unit_admin_user","delivery_mode","delivery_radius"]
            step2_colums = ["latitude","longitude","street","city","state_or_province","district","pin_code"]
            step3_columns = ["account_name","bank_name","branch_name","ifsc_code","account_number", "gst"]
            step1 = set(error_list) & set(step1_columns)
            step2 = set(error_list) & set(step2_colums)
            step3 = set(error_list) & set(step3_columns)
            page = 0
            if step1 :
                page = 0
            elif step2:
                page = 1
            elif step3:
                page = 2


            context = {"shop_form": shop_form, "bank_form": bank_form, "sales_unit_active": "active", "page": page}
            return render(request, "shop_edit.html", context)
    else:
        shop_form = ShopForm(instance=shop)
        bank_form = BankDetailsForm(instance=bank_details)
    context = {"shop_form": shop_form, "bank_form": bank_form, "sales_unit_active": "active", "page": 0}
    return render(request, "shop_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def users(request):
    users = Users.objects.exclude(user_type__exact='Customer').order_by("-created_date")
    paginator = Paginator(users, 10)
    page = request.GET.get("page")
    try:
        users = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        users = paginator.get_page(1)
    except EmptyPage:
        users = paginator.get_page(paginator.num_pages)

    context = {"users": users, "users_active": "active"}
    return render(request, "users.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def user_edit(request, user_id):
    errors = []
    user = get_object_or_404(Users, pk=user_id)
    if request.method == "POST":
        form = UserEditForm(request.POST, instance=user)
        if form.is_valid():
            form.save()
            return redirect("users")

        else:
            errors.append(form.errors)
    else:
        form = UserEditForm(instance=user)
    context = {"errors": errors, "form": form, "public_users_active": "active", "user_id": user_id}
    return render(request, "edit_users.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def user_add(request):
    errors = []
    if request.method == "POST":
        user_form = UserForm(request.POST)
        if user_form.is_valid():
            first_name = user_form.cleaned_data["first_name"]
            last_name = user_form.cleaned_data["last_name"]
            email = user_form.cleaned_data["email"]
            user_type = user_form.cleaned_data["user_type"]
            phone_number = user_form.cleaned_data["phone_number"]
            status = user_form.cleaned_data["status"]
            user_obj = Users(
                first_name=first_name,
                last_name=last_name,
                email=email,
                user_type=user_type,
                phone_number=phone_number,
                status=status
            )
            my_password = generate_random_password()
            user_obj.set_password(my_password)
            subject = "Orderpicky Registration Successful "
            message = f"Congratulations, your account has been successfully created. Your password is {my_password}"
            recepient = str(user_obj.email)
            try:
                send_mail(
                    subject, message, EMAIL_HOST_USER, [recepient], fail_silently=False
                )
                user_obj.save()
                return redirect("users")
            except:

                errors = [{'email': ['Please enter valid email']}]

                context = {
                    "errors": errors,
                    "user_form": user_form,
                }
                return render(request, "add_user.html", context)

        else:
            errors.append(user_form.errors)
    else:
        user_form = UserForm()

        errors = []

    context = {
        "errors": errors,
        "user_form": user_form,
    }
    return render(request, "add_user.html", context)


@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def user_delete(request, user_id):
    user = Users.objects.filter(pk=user_id)
    if user:
        user.delete()
    return redirect("users")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def user_add_modal(request):
    errors = []
    shop_form = ShopForm()
    if request.method == "POST":

        user_modal_form = UserModalForm(request.POST)
        if user_modal_form.is_valid():
            user_obj = user_modal_form.save()
            my_password = generate_random_password()
            user_obj.password = my_password
            subject = "Orderpicky Registration Successful "
            message = f"Congratulations, your account has been successfully created. Your password is {my_password}"
            recepient = str(user_obj.email)
            send_mail(
                subject, message, EMAIL_HOST_USER, [recepient], fail_silently=True
            )
            user_modal_form = UserModalForm()
            context = {
                "show_modal": "modal_hide",
                "shop_form": shop_form,
                "user_modal_form": user_modal_form,
            }
            return render(request, "shop_add.html", context)
        else:
            errors.append(user_modal_form.errors)
    else:
        user_modal_form = UserModalForm()
        errors = []

    context = {
        "shop_form": shop_form,
        "user_modal_form": user_modal_form,
        "errors": errors,
        "show_modal": "modal_show",
    }
    return render(request, "shop_add.html", context)


def admin_logout(request):
    logout(request)
    return redirect('/adminportal/login/')


def reset_password(request, user_id):
    errors = []
    user = get_object_or_404(Users, pk=user_id)
    my_password = generate_random_password()
    user.set_password(my_password)
    user.save()
    subject = "Navya Bakers Registration Successful "
    message = f"Congratulations, your account has been successfully created. Your password is {my_password}"
    recipient = str(user.email)
    send_mail(subject, message, EMAIL_HOST_USER, [recipient], fail_silently=False)
    messages.add_message(request, messages.SUCCESS,
                         'Password Reset Successfully. You will receive a mail with the password.')
    form = UserEditForm(instance=user)
    context = {"errors": errors, "form": form, "public_users_active": "active", "user_id": user_id}
    return render(request, "edit_users.html", context)

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def category_list(request):
    category_data = ProductCategory.objects.order_by("category_name")
    paginator = Paginator(category_data, 10)
    page = request.GET.get("page")
    try:
        category = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        category = paginator.get_page(1)
    except EmptyPage:
        category = paginator.get_page(paginator.num_pages)
    context = {"category_list": category, "category_active": "active"}
    return render(request, "category_list.html", context)






@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def category_edit(request, category_id):
    errors = []
    category = get_object_or_404(ProductCategory, pk=category_id)
    sub_category_list = ProductSubCategory.objects.filter(category=category)

    sub_category_form = ProductSubCategoryForm()
    if request.method == "POST":
        form = CategoryForm(request.POST, request.FILES, instance=category)
        if form.is_valid():
            if request.POST.get('image1', ''):
                form.instance.icon = None
            if request.POST.get('image2', ''):
                form.instance.standard_image = None
            if request.POST.get('image3', ''):
                form.instance.banner_image = None
            category = form.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "Category updated"
                description = f"Category {category.category_name}  with code {category.category_code} updated"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            return redirect("list_category")

        else:
            errors.append(form.errors)
            context = {"category_form": form, "subcategory_status": True, "category_id" : category.uuid, "sub_category_form": sub_category_form,"subcategory_add": True,"sub_category": list(sub_category_list)}
            return render(request, "category_add.html", context)
    else:
        form = CategoryForm(instance=category)
    context = {"category_form": form, "subcategory_status": True, "category_id" : category.uuid, "sub_category_form": sub_category_form}
    return render(request,"category_add.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def add_category(request, category_id=None):
    errors = []
    if request.method == "POST":
        category_form = CategoryForm(request.POST, request.FILES)
        sub_category_form = ProductSubCategoryForm()
        if category_form.is_valid():
            category = category_form.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "Category created"
                description = f"Category {category.category_name}  with code {category.category_code} created"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, descrition=description)
            except:
                pass
            category_instance = get_object_or_404(ProductCategory, pk=category.uuid)
            category_form = CategoryForm(instance=category_instance)
            # category_form.fields['category_name'].widget.attrs.update({
            #     'readonly': True
            # })
            # category_form.fields['category_code'].widget.attrs.update({
            #     'readonly': True
            # })

            context = {"category_form": category_form, "subcategory_status": True, "category_id" : category.uuid, "sub_category_form": sub_category_form}
            return render(request,"category_add.html", context)
        else:
            errors.append(category_form.errors)
            context = {
                "errors": errors,
                "category_form": category_form,
                "category_id": ""

            }
            return render(request, "category_add.html", context)
    else:
        category_form = CategoryForm()
        errors = []
    context = {
        "errors": errors,
        "category_form": category_form,
        "subcategory_status": False,
        "category_id" : ""
    }
    return render(request, "category_add.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def add_sub_category(request, category_id):
    errors = []
    category = get_object_or_404(ProductCategory, uuid=category_id)
    if request.method == "POST":
        sub_category_form = ProductSubCategoryForm(request.POST)

        sub_category_list = ProductSubCategory.objects.filter(category= category)
        category_form = CategoryForm(instance=category)
        if sub_category_form.is_valid():
            sub_category = sub_category_form.save(commit=False)
            sub_category.category = category
            sub_category.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "Sub category created"
                description = f"Sub category {sub_category.sub_category_name}  with code {sub_category.sub_category_code} created for category {sub_category.category.category_name} with code {sub_category.category.category_code}"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            sub_category_form = ProductSubCategoryForm()

            context = {"sub_category_form": sub_category_form, "subcategory_status": True, "category_form": category_form, "category_id": category_id, "subcategory_add": True, "sub_category": list(sub_category_list)}
            return render(request,"category_add.html", context)
        else:
            errors.append(sub_category_form.errors)
            if sub_category_list:
                context = {
                    "errors": errors,
                    "sub_category_form": sub_category_form,
                    "subcategory_status": True, "category_form": category_form, "category_id": category_id,"subcategory_add": True, "sub_category": list(sub_category_list)

            }
            else:
                context = {
                    "errors": errors,
                    "sub_category_form": sub_category_form,
                    "subcategory_status": True, "category_form": category_form, "category_id": category_id

                }

            return render(request, "category_add.html", context)
    else:
        category_form = CategoryForm(instance = category)
        sub_category_form = ProductSubCategoryForm()
        sub_category_list = ProductSubCategory.objects.filter(category=category)
        errors = []
        context = {"sub_category_form": sub_category_form, "subcategory_status": True, "category_form": category_form,
                   "category_id": category_id, "subcategory_add": True, "sub_category": list(sub_category_list)}

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



@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def edit_sub_category_row(request, sub_category_id):
    sub_category = get_object_or_404(ProductSubCategory, uuid=sub_category_id)
    category_id = sub_category.category.uuid
    errors =[]
    if request.method == "POST":
        form = ProductSubCategoryForm(request.POST, request.FILES, instance=sub_category)
        if form.is_valid():
            form.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "Sub category updated"
                description = f"Sub category {sub_category.sub_category_name}  with code {sub_category.sub_category_code} updated for category {sub_category.category.category_name} with code {sub_category.category.category_code}"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            return redirect(f"/adminportal/add-sub-category/{str(category_id)}/")

        else:
            errors.append(form.errors)
    else:
        form = ProductSubCategoryForm(instance=sub_category)
    context = {"errors": errors, "sub_category_form": form, "public_users_active": "active", "sub_category_id": sub_category_id, "category_id": category_id}
    return render(request, "edit_sub_category.html", context)




@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def master_product_add(request):
    errors = []
    sku_active = False
    details_active = True
    product = None
    
    if request.method == "POST":
        product_id = request.POST.get('product_id') # get product id
        # if product id exists update the product.
        if product_id:
            # Update existing product
            product = get_object_or_404(Products, pk=product_id)
            product_form = ProductForm(request.POST, request.FILES, instance=product)
        else:
            # Create new product
            product_form = ProductForm(request.POST, request.FILES)
        if product_form.is_valid():
            product = product_form.save()

            # Handle image uploads
            images = request.FILES.getlist('images')
            for image in images:
                ProductImage.objects.create(product=product, image=image)

            # Handle video uploads
            videos = request.FILES.getlist('videos')
            for video in videos:
                ProductVideo.objects.create(product=product, video=video)

            # Change active tabs
            sku_active = True
            details_active = False
            try:
                log_user = request.user
                log_type = "product"
                message = "Master Product Added"
                description = f"Product {product.item_name}  with code {product.item_code} added for category {product.item_category.category_name} ({product.item_category.category_code}) and sub category {product.item_sub_category.sub_category_name} ({product.item_sub_category.sub_category_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            
            return JsonResponse({
                'success': True,
                'sku_active': sku_active,
                'details_active': details_active,
                'product': {
                    'id': product.id
                }
            })
        else:
            errors.append(product_form.errors)
            return JsonResponse({'success': False, 'errors': product_form.errors})
    else:
        product_form = ProductForm()

    context = {
        "errors": errors,
        "product_form": product_form,
        "category_active": "active",  
        "sku_active": sku_active, 
        "details_active": details_active,
        "product": product 
    }

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



#adding the sku
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def add_sku(request, product_id):

    # we will add a sku to a particular product

    # fetch product details
    product = get_object_or_404(Products, pk=product_id)

    if request.method == "POST":

        # add the sku

        # create the sku with
        #             "sku_name",
        #             "sku_code",
        #             "sku_quantity",
        #             "sku_unit",
        #             "sku_mrp",
        #             "sku_expiry_duration",
        #             "sku_bulk_qty_limit",
        #             "sku_status"
        form = SKUForm(request.POST)
        if form.is_valid():
            sku = form.save(commit=False)
            # check expiry date if > 30 check availability
            if sku.sku_expiry_duration > 30 and sku.sku_status == "Visible":
                sku.long_distance_availability = True

            sku.product = product
            sku_data = sku.save()

            # if a sku is created we should assign it to every shop initially
            # for each shop there is a shop admin status
            # 3 status visible, disabled, out of stock
            # for default we mark it as visible
            # a sku status is also there

            for i in Shop.objects.all():
                sales_product, _ = SalesUnitProductSelection.objects.get_or_create(
                    sales_unit=i, sku=sku,
                    defaults={'shop_admin_status': sku.sku_status, 'status': sku.sku_status}
            )

                # from the iteration we will get the shop id
                # since visible we assign the shop id to the category, sub category, sku, product
                # fetch the product sku and category and sub category instance from sku assign the shop
                # print(f"SKU: {sku_data}")
                # print(f"SKU Product: {sku.product}")
                if sku.sku_status == "Visible":
                    sku.product.sales_unit.add(i) # adding shop to product
                    sku.sales_unit.add(i) # adding shop to sku
                    sku.product.item_category.sales_unit.add(i) # adding shop to item_category
                    sku.product.item_sub_category.sales_unit.add(i) # adding shop to sub category

                if sku.long_distance_availability:
                    Products.objects.filter(id=sku.product.id).update(long_distance_availability=True)
                    ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(long_distance_availability=True)
                    ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(
                        long_distance_availability=True)
                # check if already also
                # not needed duplicate skipped
                sku.save()

            # log the operation for future needs
            try:
                log_user = request.user
                log_type = "product"
                message = "SKU Added"
                description = f"SKU {sku.sku_name}  with code {sku.sku_code} added for product {sku.product.item_name}({sku.product.item_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            return JsonResponse({
                'status': 'success',
                'sku_name': sku.sku_name,  # Assuming your model has these fields
                'sku_code': sku.sku_code,
                'sku_quantity': sku.sku_quantity,
                'sku_unit': sku.sku_unit,
                'sku_mrp': sku.sku_mrp,
                'sku_id': sku.id
            })
        else:
            return JsonResponse({'status': 'error', 'errors': form.errors})
    return JsonResponse({'status': 'error', 'message': 'Invalid request method'})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def get_skus(request, product_id):
    skus = SKU.objects.filter(product_id=product_id).order_by('created_at')  # Adjust according to your SKU model
    sku_list = [{
        'sku_id': sku.id, # type: ignore
        'sku_name': sku.sku_name,
        'sku_code': sku.sku_code,
        'sku_quantity': sku.sku_quantity,  # Adjust according to your model
        'sku_unit': sku.sku_unit,  # Adjust according to your model
        'sku_mrp': sku.sku_mrp  # Adjust according to your model
    } for sku in skus]
    
    return JsonResponse({'status': 'success', 'skus': sku_list})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delete_sku(request):
    if request.method == "POST":
        # get sku id
        sku_id = request.POST.get('sku_id')
        sku = get_object_or_404(SKU, id=sku_id)  # Adjust according to your SKU model

        # print(f"SKU_TO_DELETE: {sku}")


        sku_product = sku.product  # getting product from sku
        # print(f"SKU PRODUCT: {sku.product}")
        sku_category = sku.product.item_category  # getting category from sku
        # print(f"SKU CATEGORY : {sku_category}")
        sku_sub_category = sku.product.item_sub_category # getting sub category from sku
        # print(f"SKU SUB CATEGORY: {sku_sub_category}")

        sku.delete()

        # product exists looking for availablility
        long_dist_sku_product = SKU.objects.filter(product=sku.product, sku_status="Visible",
                                                   sku_expiry_duration__gt=30)
        if not long_dist_sku_product:
            Products.objects.filter(id=sku.product.id).update(long_distance_availability=False)
        else:
            long_dist_product_flag = False
            for i in long_dist_sku_product:
                long_dist_sales_check = SalesUnitProductSelection.objects.filter(sku=i).first()
                if long_dist_sales_check:
                    if long_dist_sales_check.status == "Visible":
                        Products.objects.filter(id=sku.product.id).update(long_distance_availability=True)
                        long_dist_product_flag = True
                        break
            if not long_dist_product_flag:
                Products.objects.filter(id=sku.product.id).update(long_distance_availability=False)

        # sub category exists looking for availablility
        long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category=sku.product.item_sub_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
        if not long_dist_sku_sub_category:
            ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(
                long_distance_availability=False)
        else:

            long_dist_sub_category_flag = False
            for i in long_dist_sku_sub_category:
                long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                if long_dist_sales_check_sub:
                    if long_dist_sales_check_sub.status == "Visible":
                        ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(
                            long_distance_availability=True)
                        long_dist_sub_category_flag = True
                        break
            if not long_dist_sub_category_flag:
                ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(
                    long_distance_availability=False)

        # category exists looking for availablility
        long_dist_sku_category = SKU.objects.filter(product__item_category=sku.product.item_category,
                                                    sku_status="Visible", sku_expiry_duration__gt=30)
        if not long_dist_sku_category:
            ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                long_distance_availability=False)
        else:
            long_dist_sku_category_flag = False
            for i in long_dist_sku_category:
                long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=i).first()
                if long_dist_sales_check_cat:
                    if long_dist_sales_check_cat.status == "Visible":
                        ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                            long_distance_availability=True)
                        long_dist_sku_category_flag = True
                        break
            if not long_dist_sku_category_flag:
                ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                    long_distance_availability=False)

        # check sku exists for the product if any don't remove the shop from product
        sku_data = SKU.objects.filter(product = sku_product, sku_status="Visible")

        # print(f"SKU EXIST FOR PRODUCT AFTER DELETION: {sku_data}")

        # check sku exists for the sub category if any don't remove the shop from sub category

        sku_sub_category_data = SKU.objects.filter(product__item_sub_category = sku_sub_category, sku_status = "Visible")

        # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")


        # check sku exists for the category if any don't remove the shop from sub category

        sku_category_data = SKU.objects.filter(product__item_category = sku_category, sku_status = "Visible")

        # print(f"SKU EXIST FOR CATEGORY AFTER DELETION: {sku_category_data}")




        # # remove the shop status data from  SalesUnitProductSelection table
        # sales_products= SalesUnitProductSelection.objects.filter(
        #     sku=sku
        # )
        # print(f"Sales Products: {sales_products}")

        # remove shop from the product list

        # select shop list
        shops = Shop.objects.order_by('-created_at')

        for shop in shops:
            if not sku_data:
                sku_product.sales_unit.remove(shop)  # removing product from sku
            else:
                product_remove_flag = True
                # print(f"Iterating on Product skus : {sku_data}")
                for j in sku_data:
                    sku_sales = SalesUnitProductSelection.objects.filter(sku=j, sales_unit=shop).first()
                    # print(f"product skus Shop Status for {sku_sales}")
                    if sku_sales:
                        # print("product skus Shop status exists")

                        if sku_sales.shop_admin_status == "Visible":
                            # print(f"{sku_sales}: Visible")
                            product_remove_flag = False
                            break
                if product_remove_flag:
                    # print("No visible status available removed")
                    sku_product.sales_unit.remove(shop)

            # remove shop from the sub category list
            if not sku_sub_category_data:
                sku_sub_category.sales_unit.remove(shop)
            else:
                sub_category_remove_flag = True
                # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                for k in sku_sub_category_data:
                    sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                      sales_unit=shop).first()
                    # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                    if sku_sub_category_sales:
                        # print("sub category skus Shop status exists")
                        if sku_sub_category_sales.shop_admin_status == "Visible":
                            # print(f"{sku_sub_category_sales}: Visible")
                            sub_category_remove_flag = False
                            break
                if sub_category_remove_flag:
                    # print("No visible status available removed")
                    sku_sub_category.sales_unit.remove(shop)

            # remove shop from the category list
            if not sku_category_data:
                sku_category.sales_unit.remove(shop)
            else:
                category_remove_flag = True
                # print(f"Iterating category skus : {sku_category_data}")
                for l in sku_category_data:
                    sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                    # print(f"category  skus Shop Status for {sku_category_sales}")
                    if sku_category_sales:
                        # print("category skus Shop status exists")
                        if sku_category_sales.shop_admin_status == "Visible":
                            # print(f"{sku_category_sales}: Visible")
                            category_remove_flag = False
                            break
                if category_remove_flag:
                    # print("No visible status available removed")
                    sku_category.sales_unit.remove(shop)
        # for i in sales_products:
        #     i.delete()






        # log information
        try:
            log_user = request.user
            log_type = "product"
            message = "SKU Deleted"
            description = f"SKU {sku.sku_name}  with code {sku.sku_code} deleted for product {sku.product.item_name}({sku.product.item_code}) "
            LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
        except:
            pass
        return JsonResponse({'status': 'success'})
    return JsonResponse({'status': 'error', 'message': 'Invalid request'})


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def get_sku(request, sku_id):
    try:
        sku = SKU.objects.get(id=sku_id)
        data = {
            'status': 'success',
            'sku': {
                'sku_name': sku.sku_name,
                'sku_code': sku.sku_code,
                'sku_quantity': sku.sku_quantity,
                'sku_unit': sku.sku_unit,
                'sku_mrp': sku.sku_mrp,
                'sku_expiry_duration': sku.sku_expiry_duration,
                'sku_bulk_qty_limit': sku.sku_bulk_qty_limit,
                'sku_status': sku.sku_status,
            }
        }
        return JsonResponse(data)
    except SKU.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'SKU not found.'})

#update sku
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def update_sku(request, sku_id):
    sku = get_object_or_404(SKU, id=sku_id) # get sku instance

    # check the current sku status

    # if sku status not visible

    if request.method == 'POST':
        form = SKUForm(request.POST, instance=sku)  # Bind the form to the SKU instance
        if form.is_valid():
            sku_data = form.save()  # Save the updated SKU

            for i in Shop.objects.all():
                sales_product, _ = SalesUnitProductSelection.objects.get_or_create(
                    sales_unit=i, sku=sku_data,
                    defaults={'shop_admin_status': sku_data.sku_status, 'status': sku_data.sku_status}
            )
                sales_product.shop_admin_status = sku_data.sku_status
                sales_product.status = sku_data.sku_status
                sales_product.save()
            if sku_data.sku_expiry_duration > 30 and sku_data.sku_status == "Visible":

                sales_unit_data = SalesUnitProductSelection.objects.filter(sku= sku_data).first()

                if sales_unit_data:

                    if sales_unit_data.status == "Visible":
                        sku_data.long_distance_availability = True

                    else:
                        sku_data.long_distance_availability = False

                else:
                    sku_data.long_distance_availability = True
                sku_data.save()
            else:
                sku_data.long_distance_availability = False
                sku_data.save()

            if sku_data.long_distance_availability:
                Products.objects.filter(id=sku.product.id).update(long_distance_availability=True)
                ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                    long_distance_availability=True)
                ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(
                    long_distance_availability=True)
            else:
                # product exists looking for availablility
                long_dist_sku_product = SKU.objects.filter(product=sku.product, sku_status="Visible",sku_expiry_duration__gt =30)
                if not long_dist_sku_product:
                    Products.objects.filter(id=sku.product.id).update(long_distance_availability=False)
                else:
                    long_dist_product_flag = False
                    for z in long_dist_sku_product:
                        long_dist_sales_check =SalesUnitProductSelection.objects.filter(sku= z).first()
                        if long_dist_sales_check:
                            if long_dist_sales_check.status == "Visible":
                                Products.objects.filter(id=sku.product.id).update(long_distance_availability=True)
                                long_dist_product_flag = True
                                break
                    if not long_dist_product_flag:
                        Products.objects.filter(id=sku.product.id).update(long_distance_availability=False)

                # sub category exists looking for availablility
                long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category=sku.product.item_sub_category, sku_status="Visible",sku_expiry_duration__gt =30)
                if not long_dist_sku_sub_category:
                    ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(long_distance_availability=False)
                else:

                    long_dist_sub_category_flag = False
                    for y in long_dist_sku_sub_category:
                        long_dist_sales_check_sub =SalesUnitProductSelection.objects.filter(sku= y).first()
                        if long_dist_sales_check_sub:
                            if long_dist_sales_check_sub.status == "Visible":
                                ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(long_distance_availability=True)
                                long_dist_sub_category_flag = True
                                break
                    if not long_dist_sub_category_flag:
                        ProductSubCategory.objects.filter(uuid=sku.product.item_sub_category.uuid).update(long_distance_availability=False)



                # category exists looking for availablility
                long_dist_sku_category = SKU.objects.filter(product__item_category=sku.product.item_category, sku_status="Visible",sku_expiry_duration__gt =30)
                if not long_dist_sku_category:
                    ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(long_distance_availability=False)
                else:
                    long_dist_sku_category_flag = False
                    for x in long_dist_sku_category:
                        long_dist_sales_check_cat =SalesUnitProductSelection.objects.filter(sku= x).first()
                        if long_dist_sales_check_cat:
                            if long_dist_sales_check_cat.status == "Visible":
                                ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                                    long_distance_availability=True)
                                long_dist_sku_category_flag = True
                                break
                    if not long_dist_sku_category_flag:
                        ProductCategory.objects.filter(uuid=sku.product.item_category.uuid).update(
                            long_distance_availability=False)






                if sku_data.sku_status == "Visible":
                    for shop_data in Shop.objects.all():
                        sku.product.sales_unit.add(shop_data) # adding shop to product
                        sku.sales_unit.add(shop_data) # adding shop to sku
                        sku.product.item_category.sales_unit.add(shop_data) # adding shop to item_category
                        sku.product.item_sub_category.sales_unit.add(shop_data) # adding shop to sub category
                else:

                    # check sku exists for the product if any don't remove the shop from product
                    sku_data = SKU.objects.filter(product=sku.product, sku_status="Visible")

                    # print(f"SKU EXIST FOR PRODUCT AFTER DELETION: {sku_data}")

                    # check sku exists for the sub category if any don't remove the shop from sub category

                    sku_sub_category_data = SKU.objects.filter(product__item_sub_category=sku.product.item_sub_category,
                                                               sku_status="Visible")

                    # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

                    # check sku exists for the category if any don't remove the shop from sub category

                    sku_category_data = SKU.objects.filter(product__item_category=sku.product.item_category, sku_status="Visible")

                    # print(f"SKU EXIST FOR CATEGORY AFTER DELETION: {sku_category_data}")

                    # # remove the shop status data from  SalesUnitProductSelection table
                    # sales_products= SalesUnitProductSelection.objects.filter(
                    #     sku=sku
                    # )
                    # print(f"Sales Products: {sales_products}")

                    # remove shop from the product list

                    # select shop list
                    shops = Shop.objects.order_by('-created_at')

                    for shop in shops:
                        if not sku_data:
                            sku.product.sales_unit.remove(shop)  # removing product from sku
                        else:
                            product_remove_flag = True
                            # print(f"Iterating on Product skus : {sku_data}")
                            for j in sku_data:
                                sku_sales = SalesUnitProductSelection.objects.filter(sku=j, sales_unit=shop).first()
                                # print(f"product skus Shop Status for {sku_sales}")
                                if sku_sales:
                                    # print("product skus Shop status exists")

                                    if sku_sales.shop_admin_status == "Visible":
                                        # print(f"{sku_sales}: Visible")
                                        product_remove_flag = False
                                        break
                            if product_remove_flag:
                                # print("No visible status available removed")
                                sku.product.sales_unit.remove(shop)

                        # remove shop from the sub category list
                        if not sku_sub_category_data:
                            sku.product.item_sub_category.sales_unit.remove(shop)
                        else:
                            sub_category_remove_flag = True
                            # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                            for k in sku_sub_category_data:
                                sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                                  sales_unit=shop).first()
                                # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                                if sku_sub_category_sales:
                                    # print("sub category skus Shop status exists")
                                    if sku_sub_category_sales.shop_admin_status == "Visible":
                                        # print(f"{sku_sub_category_sales}: Visible")
                                        sub_category_remove_flag = False
                                        break
                            if sub_category_remove_flag:
                                # print("No visible status available removed")
                                sku.product.item_sub_category.sales_unit.remove(shop)

                        # remove shop from the category list
                        if not sku_category_data:
                            sku.product.item_category.sales_unit.remove(shop)
                        else:
                            category_remove_flag = True
                            # print(f"Iterating category skus : {sku_category_data}")
                            for l in sku_category_data:
                                sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l,
                                                                                              sales_unit=shop).first()
                                # print(f"category  skus Shop Status for {sku_category_sales}")
                                if sku_category_sales:
                                    # print("category skus Shop status exists")
                                    if sku_category_sales.shop_admin_status == "Visible":
                                        # print(f"{sku_category_sales}: Visible")
                                        category_remove_flag = False
                                        break
                            if category_remove_flag:
                                # print("No visible status available removed")
                                sku.product.item_category.sales_unit.remove(shop)

            try:
                log_user = request.user
                log_type = "product"
                message = "SKU Updated"
                description = f"SKU {sku_data.sku_name}  with code {sku_data.sku_code} updated for product {sku_data.product.item_name}({sku_data.product.item_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except Exception as e:
                print(e)

                pass

            return JsonResponse({'status': 'success', 'message': 'SKU updated successfully.'})
        else:
            return JsonResponse({'status': 'error', 'errors': form.errors})

    return JsonResponse({'status': 'error', 'message': 'Invalid request method'})


def update_sku_from_product_list(request, sku_id):
    sku = get_object_or_404(SKU, id=sku_id)

    if request.method == 'POST':
        status = request.POST.get('sku_status')

        if status is not None:
            sku.sku_status = status
            sku.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "SKU Status Updated"
                description = f"SKU {sku.sku_name}  with code {sku.sku_code} updated status to {status} for product {sku.product.item_name}({sku.product.item_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except:
                pass
            if status != "Visible":
                sales_unit_entries = SalesUnitProductSelection.objects.filter(sku=sku)
                sales_unit_entries.update(status=status)
                sales_unit_entries.update(shop_admin_status=status)

            return JsonResponse({'status': 'success', 'message': 'SKU status updated successfully.'})
        else:
            return JsonResponse({'status': 'error', 'message': 'No status provided in the request.'})

    return JsonResponse({'status': 'error', 'message': 'Invalid request method. Only POST is allowed.'})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def master_product_edit(request, product_id):
    product = get_object_or_404(Products, pk=product_id) # get product using product id
    errors = []
    sku_active = False
    details_active = True

    # for removing the shop list if we change the category and sub category during editing
    existing_category = product.item_category
    existing_sub_category = product.item_sub_category
    to_category = request.POST.get("item_category")
    to_sub_category = request.POST.get("item_sub_category")
    # print(existing_category)
    # print(existing_sub_category)
    # print(to_category)
    # print(to_sub_category)



    if request.method == "POST":
        product_form = ProductForm(request.POST, request.FILES, instance=product)
        if product_form.is_valid():
            product = product_form.save()

            # Handle image uploads
            images = request.FILES.getlist('images')
            for image in images:
                ProductImage.objects.create(product=product, image=image)

            # Handle video uploads
            videos = request.FILES.getlist('videos')
            for video in videos:
                ProductVideo.objects.create(product=product, video=video)

            # Change active tabs
            sku_active = True
            details_active = False

            # before updated

            # after updated



            # sub category exists looking for availablility
            long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category=existing_sub_category,
                                                            sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_sub_category:
                ProductSubCategory.objects.filter(uuid=existing_sub_category.uuid).update(
                    long_distance_availability=False)
            else:

                long_dist_sub_category_flag = False
                for i in long_dist_sku_sub_category:
                    long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_sub:
                        if long_dist_sales_check_sub.status == "Visible":
                            ProductSubCategory.objects.filter(uuid=existing_sub_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sub_category_flag = True
                            break
                if not long_dist_sub_category_flag:
                    ProductSubCategory.objects.filter(uuid=existing_sub_category.uuid).update(
                        long_distance_availability=False)

            # category exists looking for availablility
            long_dist_sku_category = SKU.objects.filter(product__item_category=existing_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_category:
                ProductCategory.objects.filter(uuid=existing_category.uuid).update(
                    long_distance_availability=False)
            else:
                long_dist_sku_category_flag = False
                for i in long_dist_sku_category:
                    long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_cat:
                        if long_dist_sales_check_cat.status == "Visible":
                            ProductCategory.objects.filter(uuid=existing_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sku_category_flag = True
                            break
                if not long_dist_sku_category_flag:
                    ProductCategory.objects.filter(uuid=existing_category.uuid).update(
                        long_distance_availability=False)









            # product exists looking for availablility
            long_dist_sku_product = SKU.objects.filter(product=product, sku_status="Visible",
                                                       sku_expiry_duration__gt=30)
            if not long_dist_sku_product:
                Products.objects.filter(id=product.id).update(long_distance_availability=False)
            else:
                long_dist_product_flag = False
                for i in long_dist_sku_product:
                    long_dist_sales_check = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check:
                        if long_dist_sales_check.status == "Visible":
                            Products.objects.filter(id=product.id).update(long_distance_availability=True)
                            long_dist_product_flag = True
                            break
                if not long_dist_product_flag:
                    Products.objects.filter(id=product.id).update(long_distance_availability=False)

            # sub category exists looking for availablility
            long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category=product.item_sub_category,
                                                            sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_sub_category:
                ProductSubCategory.objects.filter(uuid=product.item_sub_category.uuid).update(
                    long_distance_availability=False)
            else:

                long_dist_sub_category_flag = False
                for i in long_dist_sku_sub_category:
                    long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_sub:
                        if long_dist_sales_check_sub.status == "Visible":
                            ProductSubCategory.objects.filter(uuid=product.item_sub_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sub_category_flag = True
                            break
                if not long_dist_sub_category_flag:
                    ProductSubCategory.objects.filter(uuid=product.item_sub_category.uuid).update(
                        long_distance_availability=False)

            # category exists looking for availablility
            long_dist_sku_category = SKU.objects.filter(product__item_category=product.item_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_category:
                ProductCategory.objects.filter(uuid=product.item_category.uuid).update(
                    long_distance_availability=False)
            else:
                long_dist_sku_category_flag = False
                for i in long_dist_sku_category:
                    long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_cat:
                        if long_dist_sales_check_cat.status == "Visible":
                            ProductCategory.objects.filter(uuid=product.item_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sku_category_flag = True
                            break
                if not long_dist_sku_category_flag:
                    ProductCategory.objects.filter(uuid=product.item_category.uuid).update(
                        long_distance_availability=False)

            sku_sub_category_data = SKU.objects.filter(product__item_sub_category=existing_sub_category,
                                                       sku_status="Visible")

            # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

            # check sku exists for the category if any don't remove the shop from sub category

            sku_category_data = SKU.objects.filter(product__item_category=existing_category, sku_status="Visible")

            # print(f"SKU EXIST FOR CATEGORY AFTER DELETION: {sku_category_data}")

            to_sku_sub_category_data = SKU.objects.filter(product__item_sub_category__uuid=to_sub_category,
                                                       sku_status="Visible")

            # print(f"SKU Exist if we change sub category {to_sku_sub_category_data}")


            to_sku_category_data = SKU.objects.filter(product__item_category__uuid=to_category, sku_status="Visible")

            # print(f"SKU Exist if we change category {to_sku_category_data}")



            # select shop list
            shops = Shop.objects.order_by('-created_at')



            # only remove the current shop
            for shop in shops:



                # add the shop if any sku is in visible state
                if to_sku_category_data:
                    for to_sku_category_ in to_sku_category_data:
                        to_sku_category_sales = SalesUnitProductSelection.objects.filter(sku=to_sku_category_, sales_unit=shop).first()  # fetch current shop
                        if to_sku_category_sales:
                            if to_sku_category_sales.shop_admin_status == "Visible":
                                to_sku_category_sales.sku.product.item_sub_category.sales_unit.add(shop)
                                # print(f"{sku_sub_category_sales}: Visible")
                                break


                if to_sku_sub_category_data:
                    for to_sku_sub_category_ in to_sku_sub_category_data:
                        to_sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=to_sku_sub_category_, sales_unit=shop).first()  # fetch current shop
                        if to_sku_sub_category_sales:
                            if to_sku_sub_category_sales.shop_admin_status == "Visible":
                                to_sku_sub_category_sales.sku.product.item_sub_category.sales_unit.add(shop)
                                # print(f"{sku_sub_category_sales}: Visible")
                                break
                    # to_sku_sub_category_data.product.item_category.sales_unit.add(shop)

                # remove shop from the sub category list
                if not sku_sub_category_data:
                    existing_sub_category.sales_unit.remove(shop)
                else:
                    sub_category_remove_flag = True
                    # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                    for k in sku_sub_category_data:
                        sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                          sales_unit=shop).first()
                        # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                        if sku_sub_category_sales:
                            # print("sub category skus Shop status exists")
                            if sku_sub_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sub_category_sales}: Visible")
                                sub_category_remove_flag = False
                                break
                    if sub_category_remove_flag:
                        # print("No visible status available removed")
                        existing_sub_category.sales_unit.remove(shop)

                # remove shop from the category list
                if not sku_category_data:
                    existing_category.sales_unit.remove(shop)
                else:
                    category_remove_flag = True
                    # print(f"Iterating category skus : {sku_category_data}")
                    for l in sku_category_data:
                        sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                        # print(f"category  skus Shop Status for {sku_category_sales}")
                        if sku_category_sales:
                            # print("category skus Shop status exists")
                            if sku_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_category_sales}: Visible")
                                category_remove_flag = False
                                break
                    if category_remove_flag:
                        # print("No visible status available removed")
                        existing_category.sales_unit.remove(shop)

            try:
                log_user = request.user
                log_type = "product"
                message = "Master Product Updated"
                description = f"Product {product.item_name}  with code {product.item_code} updated for category {product.item_category.category_name} ({product.item_category.category_code}) and sub category {product.item_sub_category.sub_category_name} ({product.item_sub_category.sub_category_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            
            return JsonResponse({
                'success': True,
                'sku_active': sku_active,
                'details_active': details_active,
                'product': {
                    'id': product.id
                }
            })
        else:
            errors.append(product_form.errors)
            return JsonResponse({'success': False, 'errors': product_form.errors})
    
    product_form = ProductForm(instance=product)

    context = {
        "errors": errors,
        "product_form": product_form,
        "category_active": "active",  
        "sku_active": sku_active, 
        "details_active": details_active,
        "product": product,
        "product_id": product_id
    }

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


@login_required
def delete_image(request, image_id):
    image = get_object_or_404(ProductImage, id=image_id)
    product_id = image.product.id   # type: ignore
    image.delete()
    try:
        log_user = request.user
        log_type = "product"
        message = "Master Product Image deleted"
        description = f"Product {image.product.item_name}  with code {image.product.item_code} deleted its image for category {image.product.item_category.category_name} ({image.product.item_category.category_code}) and sub category {image.product.item_sub_category.sub_category_name} ({image.product.item_sub_category.sub_category_code}) "
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
    except:
        pass
    return redirect('edit_master_product', product_id=product_id) 

@login_required
def delete_video(request, video_id):
    video = get_object_or_404(ProductVideo, id=video_id)
    product_id = video.product.id   # type: ignore
    video.delete()
    try:
        log_user = request.user
        log_type = "product"
        message = "Master Product Video deleted"
        description = f"Product {video.product.item_name}  with code {video.product.item_code} deleted its video for category {video.product.item_category.category_name} ({video.product.item_category.category_code}) and sub category {video.product.item_sub_category.sub_category_name} ({video.product.item_sub_category.sub_category_code}) "
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
    except:
        pass
    return redirect('edit_master_product', product_id=product_id) 

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def master_product_delete(request, product_id):
    product = Products.objects.filter(pk=product_id) # fetch product by id
    product_data = product.first()
    product_category = product_data.item_category
    product_sub_category = product_data.item_sub_category
    if product:
        # if ads found for product don't delete the product
        ads = Ads.objects.filter(Product=product_id)
        if ads:
            messages.add_message(request, messages.WARNING,
                                 "Your Product used in ads! couldn't delete product")
                # messages.error(request, "Your coupon used in ads! couldn't delete coupon")
        else:
            product.delete()



            # sub category exists looking for availablility
            long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category=product_sub_category,
                                                            sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_sub_category:
                ProductSubCategory.objects.filter(uuid=product_sub_category.uuid).update(
                    long_distance_availability=False)
            else:

                long_dist_sub_category_flag = False
                for i in long_dist_sku_sub_category:
                    long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_sub:
                        if long_dist_sales_check_sub.status == "Visible":
                            ProductSubCategory.objects.filter(uuid=product_sub_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sub_category_flag = True
                            break
                if not long_dist_sub_category_flag:
                    ProductSubCategory.objects.filter(uuid=product_sub_category.uuid).update(
                        long_distance_availability=False)

            # category exists looking for availablility
            long_dist_sku_category = SKU.objects.filter(product__item_category=product_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_category:
                ProductCategory.objects.filter(uuid=product_category.uuid).update(
                    long_distance_availability=False)
            else:
                long_dist_sku_category_flag = False
                for i in long_dist_sku_category:
                    long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=i).first()
                    if long_dist_sales_check_cat:
                        if long_dist_sales_check_cat.status == "Visible":
                            ProductCategory.objects.filter(uuid=product_category.uuid).update(
                                long_distance_availability=True)
                            long_dist_sku_category_flag = True
                            break
                if not long_dist_sku_category_flag:
                    ProductCategory.objects.filter(uuid=product_category.uuid).update(
                        long_distance_availability=False)



            sku_sub_category_data = SKU.objects.filter(product__item_sub_category=product_sub_category,
                                                       sku_status="Visible")

            # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

            # check sku exists for the category if any don't remove the shop from sub category

            sku_category_data = SKU.objects.filter(product__item_category=product_category, sku_status="Visible")

            # print(f"SKU EXIST FOR CATEGORY AFTER DELETION: {sku_category_data}")

            shops = Shop.objects.order_by('-created_at')

            for shop in shops:
                if not sku_category_data:
                    product_category.sales_unit.remove(shop)  # removing product from sku
                else:
                    product_remove_flag = True
                    # print(f"Iterating on Product skus : {sku_data}")
                    for j in sku_category_data:
                        sku_sales = SalesUnitProductSelection.objects.filter(sku=j, sales_unit=shop).first()
                        # print(f"product skus Shop Status for {sku_sales}")
                        if sku_sales:
                            # print("product skus Shop status exists")

                            if sku_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sales}: Visible")
                                product_remove_flag = False
                                break
                    if product_remove_flag:
                        # print("No visible status available removed")
                        product_category.sales_unit.remove(shop)

                if not sku_sub_category_data:
                    product_sub_category.sales_unit.remove(shop)  # removing product from sku
                else:
                    product_remove_flag = True
                    # print(f"Iterating on Product skus : {sku_data}")
                    for j in sku_sub_category_data:
                        sku_sales = SalesUnitProductSelection.objects.filter(sku=j, sales_unit=shop).first()
                        # print(f"product skus Shop Status for {sku_sales}")
                        if sku_sales:
                            # print("product skus Shop status exists")

                            if sku_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sales}: Visible")
                                product_remove_flag = False
                                break
                    if product_remove_flag:
                        # print("No visible status available removed")
                        product_sub_category.sales_unit.remove(shop)

            # if we delete the product skus will delete
            # if not skus we check for category and sub category
            # if skus exist for category and subcategory shop will not remove
            # other wise remove shop


            try:
                log_user = request.user
                log_type = "product"
                message = "Master Product deleted"
                description = f"Product {product_data.item_name}  with code {product_data.item_code} deleted for category {product_data.item_category.category_name} ({product_data.item_category.category_code}) and sub category {product_data.item_sub_category.sub_category_name} ({product_data.item_sub_category.sub_category_code}) "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except Exception as e:
                print(e)
                pass

    return redirect("list_master_product")

from django.http import JsonResponse

# this is a function to filter and list the products based on sub category
# we have this drop down menu having the list of sub categories
# if we select one sub category based on that sub category product will list on the below table.

def subcategory_product_list(request):
    category_id = request.GET.get('category_id')
    subcategory_id = request.GET.get('subcategory_id')
    shop_id = request.GET.get('shop_id')
    product_type = request.GET.get('product_type')
    # filter the products
    product_list = Products.objects.filter(product_type=product_type).order_by('-created_date')
    if subcategory_id:
        product_list = product_list.filter(item_category=category_id, item_sub_category= subcategory_id)
    else:
        product_list = product_list.filter(item_category = category_id)
    list_data = []
    for i in product_list.filter():
        sku_list = []
        for j in i.skus.all():
            try:
                # check whether shop status created if not create one with default status
                sales_product, _ = SalesUnitProductSelection.objects.get_or_create(
                    sales_unit=shop_id, sku=j,
                    defaults={'shop_admin_status': 'Visible', 'status': 'Visible'}
                )
                # add the shop status for easy reference
                if sales_product.shop_admin_status == "Visible": # remove not included not needed in listing
                    j.sales_unit.add(shop_id)
                    j.product.sales_unit.add(shop_id)
                    j.product.item_category.sales_unit.add(shop_id)
                    j.product.item_sub_category.sales_unit.add(shop_id)

                if sales_product.status == "Visible":
                    j.long_distance_availability = True
                    j.save()
                    Products.objects.filter(id=j.product.id).update(long_distance_availability=True)
                    ProductCategory.objects.filter(uuid=j.product.item_category.uuid).update(
                        long_distance_availability=True)
                    ProductSubCategory.objects.filter(uuid=j.product.item_sub_category.uuid).update(
                        long_distance_availability=True)
                # assign the status information since it is not available on sku table
                # we list the shop status information on product list page
                # we can change the status also
                j.status = sales_product.status
                j.shop_admin_status = sales_product.shop_admin_status
                sku_list.append(j)
            except:
                j.status = "Disabled"
                sku_list.append(j)
        i.sku = sku_list
        list_data.append(i)
    paginator = Paginator(list_data, 10)
    products = paginator.get_page(1) # try doing the above statuses after pagination ............
    pagination = render_to_string('pagination.html', {'product_data': products})
    if request.user.user_type == 'Shop Admin':
        tbody = render_to_string('product_list_page.html', {"product_data":products})
    else:
        tbody = render_to_string('product_page.html', {"product_data": products})


    return JsonResponse({"tbody": tbody, "pagination": pagination}, safe=False)




# get the list of subcategories from a category
# on selecting the category from drop down a list of sub category loaded on drop down subcategory
# could be more efficient with processing limit to the page

# change that...........................................................
def load_subcategories(request):
    category_id = request.GET.get('category_id')
    shop_id = request.GET.get('shop_id')
    product_type = request.GET.get('product_type')
    product_list = Products.objects.filter(product_type=product_type).order_by('-created_date')
    subcategories =[]
    if category_id:
        product_list = product_list.filter(item_category=category_id)
        subcategories = ProductSubCategory.objects.filter(category_id=category_id).values('uuid', 'sub_category_name')

    list_data = []
    for i in product_list.filter():
        sku_list = []
        for j in i.skus.all():
            try:
                sales_product, _ = SalesUnitProductSelection.objects.get_or_create(
                    sales_unit=shop_id, sku=j,
                    defaults={'shop_admin_status': 'Visible', 'status': 'Visible'}
                )

                if sales_product.shop_admin_status == "Visible": # remove not included not needed in listing
                    j.sales_unit.add(shop_id)
                    j.product.sales_unit.add(shop_id)
                    j.product.item_category.sales_unit.add(shop_id)
                    j.product.item_sub_category.sales_unit.add(shop_id)

                if sales_product.status == "Visible":
                    j.long_distance_availability = True
                    j.save()
                    Products.objects.filter(id=j.product.id).update(long_distance_availability=True)
                    ProductCategory.objects.filter(uuid=j.product.item_category.uuid).update(
                        long_distance_availability=True)
                    ProductSubCategory.objects.filter(uuid=j.product.item_sub_category.uuid).update(
                        long_distance_availability=True)


                j.status = sales_product.status
                j.shop_admin_status = sales_product.shop_admin_status
                sku_list.append(j)
            except:
                j.status = "Disabled"
                sku_list.append(j)
        i.sku = sku_list
        list_data.append(i)
    paginator = Paginator(list_data, 10)
    products = paginator.get_page(1)
    pagination = render_to_string('pagination.html', {'product_data': products})
    if request.user.user_type == 'Shop Admin':
        tbody = render_to_string('product_list_page.html', {"product_data": products})
    else:
        tbody = render_to_string('product_page.html', {"product_data": products})


    if subcategories:
        return JsonResponse({"subcategories":list(subcategories), "tbody": tbody, "pagination": pagination}, safe=False)
    else:
        return JsonResponse({"subcategories":[], "tbody": tbody, "pagination": pagination}, safe=False)




    list_data = []
    # for i in list(subcategories):
    #     data = {}
    #     data["id"] = i.uuid
    #     data["name"] = i.sub_category_name
    #     list_data.append(data)

def load_subcategories_product(request):
    category_id = request.GET.get('category_id')
    if category_id:
        subcategories = ProductSubCategory.objects.filter(category_id=category_id).values('uuid', 'sub_category_name')
        return JsonResponse(list(subcategories), safe=False)
    else:
        return JsonResponse([], safe = False)







@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def master_product_list(request):
    products = Products.objects.order_by("-created_at")
    paginator = Paginator(products, 10)
    page = request.GET.get("page")
    try:
        products = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        products = paginator.get_page(1)
    except EmptyPage:
        products = paginator.get_page(paginator.num_pages)
    context = {"product_data": products, "category_active": "active"}
    return render(request, "product_list.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def master_product_list(request, product_split = False):
    search_query = request.GET.get('search', "")
    product_date = request.GET.get('product_date', "")
    product_status = request.GET.get('product_status', "")
    product_list = Products.objects.filter(product_type = "Master Product").order_by('-created_date')

    if search_query:
        product_list = Products.objects.filter(
            Q(item_name__icontains=search_query) |
            Q(item_code__icontains=search_query) |
            Q(item_category__category_name__icontains=search_query)|
            Q(item_sub_category__sub_category_name__icontains = search_query)
        ).order_by('-created_date')
    if product_date:
        formatted_date = datetime.strptime(product_date, "%Y-%m-%d")
        product_list = product_list.filter(created_date__date=formatted_date)
    if product_status:
        product_list = product_list.filter(product_status=product_status)

    paginator = Paginator(product_list, 10)
    page = request.GET.get('page')

    try:
        products = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        products = paginator.get_page(1)
    except EmptyPage:
        products = paginator.get_page(paginator.num_pages)

    base_url = reverse('list_master_product')
    query_params = request.GET.copy()
    if 'page' in query_params:
        del query_params['page']
    pagination_links = [
        {
            'page_number': page_number,
            'url': f"{base_url}?{query_params.urlencode(safe='/')}&page={page_number}",
        }
        for page_number in products.paginator.page_range
    ]
    context = {
        "product_data": products,
        'search_query': search_query,
        'date': product_date,
        'product_status': product_status,
        'pagination_links': pagination_links,
        "category_active": "active"

    }

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






# get product list
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin", "Shop Admin"]))
def product_list(request, shop_id = None,product_type = "Master Product"):
    search_query = request.GET.get('search', "")

    # fetch products from the table
    product_list = Products.objects.filter(product_type=product_type).order_by('-created_date')

    # if shop admin we only need the products assigned to the shop
    # get shop id
    if request.user.user_type == 'Shop Admin':
        shop_id = Shop.objects.prefetch_related('unit_admin_user').filter(unit_admin_user__uuid = request.user.uuid).first().uuid




    category_list = ProductCategory.objects.all().order_by("-created_at")

    # fetch the shop details

    shop_details = get_object_or_404(Shop,uuid = shop_id)
    shop_name = shop_details.unit_name
    shop_location = shop_details.unit_location

    # filter using search query
    if search_query:
        product_list = Products.objects.filter(product_type =product_type).filter(
            Q(item_name__icontains=search_query) |
            Q(item_code__icontains=search_query) |
            Q(item_category__category_name__icontains=search_query)|
            Q(item_sub_category__sub_category_name__icontains = search_query)
        ).order_by('-created_date')

    category_page = request.GET.get('category_page')

    # filter the products based on category
    if category_page:
        product_list = product_list.filter(item_category=category_page)

    # filter the products using sub category
    sub_category_page = request.GET.get('subcategory_page')
    if sub_category_page:
        product_list = product_list.filter(item_sub_category=sub_category_page)

    # shop admin status is not in product table we need to fetch from Sales unit product selection table
    # in the product listing page we have a provision to change the shop admin status for shop admin user
    list_data = []
    for i in product_list:
        sku_list = []
        for j in i.skus.all():
            try:
                # sales_product = SalesUnitProductSelection.objects.get(sales_unit=shop_details.uuid, sku=j.id)
                sales_product, _ =SalesUnitProductSelection.objects.get_or_create(
                    sales_unit=shop_details, sku=j,
                    defaults={'shop_admin_status': 'Visible', 'status': 'Visible'}
                )

                if sales_product.shop_admin_status == "Visible": # remove not included not needed in listing
                    j.sales_unit.add(shop_id)
                    j.product.sales_unit.add(shop_id)
                    j.product.item_category.sales_unit.add(shop_id)
                    j.product.item_sub_category.sales_unit.add(shop_id)

                if sales_product.status == "Visible":
                    j.long_distance_availability = True
                    j.save()
                    Products.objects.filter(id=j.product.id).update(long_distance_availability=True)
                    ProductCategory.objects.filter(uuid=j.product.item_category.uuid).update(
                        long_distance_availability=True)
                    ProductSubCategory.objects.filter(uuid=j.product.item_sub_category.uuid).update(
                        long_distance_availability=True)

                j.status = sales_product.status
                j.shop_admin_status = sales_product.shop_admin_status
                sku_list.append(j)

                # list_data.append(i)
            except Exception as e:
                j.status = "Disabled"
                sku_list.append(j)
        i.sku = sku_list
        list_data.append(i)


    paginator = Paginator(list_data, 10)
    page = request.GET.get('page')



    try:
        products = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        products = paginator.get_page(1)
    except EmptyPage:
        products = paginator.get_page(paginator.num_pages)

    base_url = reverse('list_shop_product',kwargs={'shop_id':shop_id, 'product_type':'Master Product'})
    query_params = request.GET.copy()
    if 'page' in query_params:
        del query_params['page']
    pagination_links = [
        {
            'page_number': page_number,
            'url': f"{base_url}?{query_params.urlencode(safe='/')}&page={page_number}",
        }
        for page_number in products.paginator.page_range
    ]
    context = {
        "product_data": products,
        'search_query': search_query,
        'pagination_links': pagination_links,
        'product_type' : product_type,
        "sales_unit_active": "active",
        "shop_id": shop_id,
        "shop_name": shop_name,
        "shop_location":shop_location,
        "category_list": category_list

    }
    if request.user.user_type == 'Shop Admin':
        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            tbody = render_to_string('product_list_page.html',
                                     {"product_data": products, 'pagination_links': pagination_links})
            pagination = render_to_string('pagination.html', {'product_data': products})
            return JsonResponse({'tbody': tbody, "pagination": pagination})
        return render(request, "product_list_shop_admin.html", context)
    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        tbody = render_to_string('product_page.html', {"product_data": products, 'pagination_links': pagination_links})
        pagination = render_to_string('pagination.html', {'product_data':products})
        return JsonResponse({'tbody': tbody, "pagination":pagination })


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


# it is the status which can be changed with the admin dashboard not shop admin
# we have the status details in the salesproductselectiontable
# in that table we have a field status
# with this view we can change that status
# with this change of status shop admin status also change to the new status.

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin", "Shop Admin"]))
def update_product_sales_status(request):
    # print("Logging : Updating Product status on Admin")
    if request.method == 'POST':
        sku_id = request.POST.get('sku_id')
        shop_id = request.POST.get('shop_id')
        new_status = request.POST.get('status')
        # we have the id details to fetch the product status
        #fetching product status
        try:
            sales_unit_product = SalesUnitProductSelection.objects.get(sales_unit=shop_id, sku=sku_id)
        except SalesUnitProductSelection.DoesNotExist:
            # if not found record
            return JsonResponse({'success': False, 'error': 'Operation not allowed.'})
        try:
            # assigning the new status
            sales_unit_product.status = new_status
            sales_unit_product.shop_admin_status =new_status
            sales_unit_product.save()

            # if visible add the shop availablility
            if new_status == "Visible":
                SKU.objects.filter(id = sku_id).update(long_distance_availability=True)
                Products.objects.filter(id=sales_unit_product.sku.product.id).update(long_distance_availability=True)
                ProductCategory.objects.filter(uuid=sales_unit_product.sku.product.item_category.uuid).update(
                    long_distance_availability=True)
                ProductSubCategory.objects.filter(uuid=sales_unit_product.sku.product.item_sub_category.uuid).update(
                    long_distance_availability=True)
            else:
                # print("Logging: Status updating to not visible statuses")
                SKU.objects.filter(id = sku_id).update(long_distance_availability=False)
                # product exists looking for availablility
                long_dist_sku_product = SKU.objects.filter(product=sales_unit_product.sku.product, sku_status="Visible",
                                                           sku_expiry_duration__gt=30)
                if not long_dist_sku_product:
                    Products.objects.filter(id=sales_unit_product.sku.product.id).update(long_distance_availability=False)
                else:
                    long_dist_product_flag = False
                    for i in long_dist_sku_product:
                        long_dist_sales_check = SalesUnitProductSelection.objects.filter(sku=i).first()
                        if long_dist_sales_check:
                            if long_dist_sales_check.status == "Visible":
                                Products.objects.filter(id=sales_unit_product.sku.product.id).update(long_distance_availability=True)
                                long_dist_product_flag = True
                                break
                    if not long_dist_product_flag:
                        Products.objects.filter(id=sales_unit_product.sku.product.id).update(long_distance_availability=False)

                # sub category exists looking for availablility
                long_dist_sku_sub_category = SKU.objects.filter(
                    product__item_sub_category=sales_unit_product.sku.product.item_sub_category,
                    sku_status="Visible", sku_expiry_duration__gt=30)
                if not long_dist_sku_sub_category:
                    ProductSubCategory.objects.filter(uuid=sales_unit_product.sku.product.item_sub_category.uuid).update(
                        long_distance_availability=False)
                else:

                    long_dist_sub_category_flag = False
                    for i in long_dist_sku_sub_category:
                        long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                        if long_dist_sales_check_sub:
                            if long_dist_sales_check_sub.status == "Visible":
                                ProductSubCategory.objects.filter(uuid=sales_unit_product.sku.product.item_sub_category.uuid).update(
                                    long_distance_availability=True)
                                long_dist_sub_category_flag = True
                                break
                    if not long_dist_sub_category_flag:
                        ProductSubCategory.objects.filter(uuid=sales_unit_product.sku.product.item_sub_category.uuid).update(
                            long_distance_availability=False)

                # category exists looking for availablility
                long_dist_sku_category = SKU.objects.filter(product__item_category=sales_unit_product.sku.product.item_category,
                                                            sku_status="Visible", sku_expiry_duration__gt=30)
                if not long_dist_sku_category:
                    ProductCategory.objects.filter(uuid=sales_unit_product.sku.product.item_category.uuid).update(
                        long_distance_availability=False)
                else:
                    long_dist_sku_category_flag = False
                    for i in long_dist_sku_category:
                        long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=i).first()
                        if long_dist_sales_check_cat:
                            if long_dist_sales_check_cat.status == "Visible":
                                ProductCategory.objects.filter(uuid=sales_unit_product.sku.product.item_category.uuid).update(
                                    long_distance_availability=True)
                                long_dist_sku_category_flag = True
                                break
                    if not long_dist_sku_category_flag:
                        ProductCategory.objects.filter(uuid=sales_unit_product.sku.product.item_category.uuid).update(
                            long_distance_availability=False)



            if new_status == "Visible":
                sales_unit_product.sku.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.item_category.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.item_sub_category.sales_unit.add(sales_unit_product.sales_unit)

                # else remove shop availablility
            else:
                sales_unit_product.sku.sales_unit.remove(sales_unit_product.sales_unit)

                # check sku exists for the product if any don't remove the shop from product
                sku_data = SKU.objects.filter(product=sales_unit_product.sku.product, sku_status="Visible")

                # print(f"SKU EXIST FOR PRODUCT AFTER DELETION: {sku_data}")

                # check sku exists for the sub category if any don't remove the shop from sub category

                sku_sub_category_data = SKU.objects.filter(product__item_sub_category= sales_unit_product.sku.product.item_sub_category,
                                                           sku_status="Visible")

                # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

                # check sku exists for the category if any don't remove the shop from sub category

                sku_category_data = SKU.objects.filter(product__item_category=sales_unit_product.sku.product.item_category, sku_status="Visible")

                if not sku_data:
                    sales_unit_product.sku.product.sales_unit.remove(shop_id)
                else:
                    product_remove_flag = True
                    # print(f"Iterating on Product skus : {sku_data}")
                    for j in sku_data:
                        sku_sales = SalesUnitProductSelection.objects.filter(sku=j, sales_unit=sales_unit_product.sales_unit).first()
                        # print(f"product skus Shop Status for {sku_sales}")
                        if sku_sales:
                            # print("product skus Shop status exists")

                            if sku_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sales}: Visible")
                                product_remove_flag = False
                                break
                    if product_remove_flag:
                        # print("No visible status available removed")
                        sales_unit_product.sku.product.sales_unit.remove(sales_unit_product.sales_unit)

                    # remove shop from the sub category list
                    if not sku_sub_category_data:
                        sales_unit_product.sku.product.item_sub_category.sales_unit.remove(sales_unit_product.sales_unit)
                    else:
                        sub_category_remove_flag = True
                        # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                        for k in sku_sub_category_data:
                            sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                              sales_unit=sales_unit_product.sales_unit).first()
                            # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                            if sku_sub_category_sales:
                                # print("sub category skus Shop status exists")
                                if sku_sub_category_sales.shop_admin_status == "Visible":
                                    # print(f"{sku_sub_category_sales}: Visible")
                                    sub_category_remove_flag = False
                                    break
                        if sub_category_remove_flag:
                            # print("No visible status available removed")
                            sales_unit_product.sku.product.item_sub_category.sales_unit.remove(sales_unit_product.sales_unit)

                    # remove shop from the category list
                    if not sku_category_data:
                        sales_unit_product.sku.product.item_category.sales_unit.remove(sales_unit_product.sales_unit)
                    else:
                        category_remove_flag = True
                        # print(f"Iterating category skus : {sku_category_data}")
                        for l in sku_category_data:
                            sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l,
                                                                                          sales_unit=sales_unit_product.sales_unit).first()
                            # print(f"category  skus Shop Status for {sku_category_sales}")
                            if sku_category_sales:
                                # print("category skus Shop status exists")
                                if sku_category_sales.shop_admin_status == "Visible":
                                    # print(f"{sku_category_sales}: Visible")
                                    category_remove_flag = False
                                    break
                        if category_remove_flag:
                            # print("No visible status available removed")
                            sales_unit_product.sku.product.item_category.sales_unit.remove(sales_unit_product.sales_unit)

            try:
                log_user = request.user
                log_type = "product"
                message = f"Product Status Updated for Shop {sales_unit_product.sales_unit.unit_name}({sales_unit_product.sales_unit.unit_code})"
                description = f"SKU {sales_unit_product.sku.sku_name}  with code {sales_unit_product.sku.sku_code} updated its status to {new_status} for product {sales_unit_product.sku.product.item_name} ({sales_unit_product.sku.product.item_code} "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except:
                pass
            return JsonResponse({'status': 'success'})
        except:
            return JsonResponse({'error': 'Invalid request.'})


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def category_based_update_status(request, shop_id):
    category_id = request.POST.get('category')
    sub_category_id = request.POST.get('subcategory')
    new_status = request.POST.get('status_category_select')
    shop = Shop.objects.filter(uuid = shop_id).first()
    product_list = Products.objects.order_by('-created_date')
    if category_id:
        product_list = product_list.filter(item_category__uuid=category_id)
    if sub_category_id:
        product_list = product_list.filter(item_sub_category__uuid=sub_category_id)
    product_selection = SalesUnitProductSelection.objects.filter(sales_unit__uuid = shop_id)
    update_list = []
    show_list = []
    for i in product_list:
        sku_list = []
        for j in i.skus.all():
            if j.sku_status == "Visible":
                check = product_selection.filter(sku = j).first()
                check.status=new_status
                check.shop_admin_status = new_status
                j.status = new_status
                j.shop_admin_status = new_status
                update_list.append(check)
                sku_list.append(j)
                if new_status == "Visible":
                    j.sales_unit.add(shop)
                    j.long_distance_availability=True
                else:
                    j.sales_unit.remove(shop)
                    j.long_distance_availability=False

            else:
                check = product_selection.filter(sku=j).first()
                j.status = check.status
                if j.status == "Visible":
                    j.long_distance_availability = True
                j.shop_admin_status = check.shop_admin_status
                update_list.append(check)
                sku_list.append(j)
            j.save()
        i.sku = sku_list
        show_list.append(i)




    SalesUnitProductSelection.objects.bulk_update(update_list, ['status', 'shop_admin_status'])


    # check sku exists for the product if any don't remove the shop from product

    # print(f"SKU EXIST FOR PRODUCT AFTER DELETION: {sku_data}")

    # check sku exists for the sub category if any don't remove the shop from sub category



    # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

    # check sku exists for the category if any don't remove the shop from sub category



    if category_id:

        sku_category_data = SKU.objects.filter(product__item_category__uuid=category_id,
                                               sku_status="Visible")


        long_dist_sku_category = sku_category_data.filter(sku_expiry_duration__gt=30)
        if not long_dist_sku_category:
            ProductCategory.objects.filter(uuid=category_id).update(
                long_distance_availability=False)
        else:
            long_dist_sku_category_flag = False
            for z in long_dist_sku_category:
                long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=z).first()
                if long_dist_sales_check_cat:
                    if long_dist_sales_check_cat.status == "Visible":
                        ProductCategory.objects.filter(uuid=category_id).update(
                            long_distance_availability=True)
                        long_dist_sku_category_flag = True
                        break
            if not long_dist_sku_category_flag:
                ProductCategory.objects.filter(uuid=category_id).update(
                    long_distance_availability=False)




        if not sku_category_data:
            update_status = ProductCategory.objects.filter(uuid=category_id).first()
            if update_status:
                update_status.sales_unit.remove(shop)
        else:
            category_remove_flag = True
            # print(f"Iterating category skus : {sku_category_data}")
            for l in sku_category_data:
                sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                # print(f"category  skus Shop Status for {sku_category_sales}")
                if sku_category_sales:
                    # print("category skus Shop status exists")
                    if sku_category_sales.shop_admin_status == "Visible":
                        # print(f"{sku_category_sales}: Visible")
                        category_remove_flag = False
                        break
            if category_remove_flag:
                # print("No visible status available removed")
                update_status = ProductCategory.objects.filter(uuid=category_id).first()
                if update_status:
                    update_status.sales_unit.remove(shop)
            else:
                update_status = ProductCategory.objects.filter(uuid=category_id).first()
                if update_status:
                    update_status.sales_unit.add(shop)
    else:

        for cat in ProductCategory.objects.all():
            sku_category_data = SKU.objects.filter(product__item_category=cat,
                                                   sku_status="Visible")

            long_dist_sku_category = sku_category_data.filter(sku_expiry_duration__gt=30)
            if not long_dist_sku_category:
                cat.long_distance_availability=False
                cat.save()
            else:
                long_dist_sku_category_flag = False
                for y in long_dist_sku_category:
                    long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=y).first()
                    if long_dist_sales_check_cat:
                        if long_dist_sales_check_cat.status == "Visible":
                            cat.long_distance_availability=True
                            cat.save()
                            long_dist_sku_category_flag = True
                            break
                if not long_dist_sku_category_flag:
                    cat.long_distance_availability=False
                    cat.save()



            if not sku_category_data:
                cat.sales_unit.remove(shop)
            else:
                category_remove_flag = True
                # print(f"Iterating category skus : {sku_category_data}")
                for l in sku_category_data:
                    sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                    # print(f"category  skus Shop Status for {sku_category_sales}")
                    if sku_category_sales:
                        # print("category skus Shop status exists")
                        if sku_category_sales.shop_admin_status == "Visible":
                            # print(f"{sku_category_sales}: Visible")
                            category_remove_flag = False
                            break
                if category_remove_flag:
                    # print("No visible status available removed")
                    cat.sales_unit.remove(shop)
                else:
                    cat.sales_unit.add(shop)

    if sub_category_id:
        sku_sub_category_data = SKU.objects.filter(
            product__item_sub_category__uuid=sub_category_id,
            sku_status="Visible")

        long_dist_sku_sub_category = sku_sub_category_data.filter( sku_expiry_duration__gt=30)
        if not long_dist_sku_sub_category:
            ProductSubCategory.objects.filter(uuid=sub_category_id).update(
                long_distance_availability=False)
        else:

            long_dist_sub_category_flag = False
            for x in long_dist_sku_sub_category:
                long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=x).first()
                if long_dist_sales_check_sub:
                    if long_dist_sales_check_sub.status == "Visible":
                        ProductSubCategory.objects.filter(
                            uuid=sub_category_id).update(
                            long_distance_availability=True)
                        long_dist_sub_category_flag = True
                        break
            if not long_dist_sub_category_flag:
                ProductSubCategory.objects.filter(uuid=sub_category_id).update(
                    long_distance_availability=False)







        # remove shop from the sub category list
        if not sku_sub_category_data:
            update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
            if update_status:
                update_status.sales_unit.remove(shop)
        else:
            sub_category_remove_flag = True
            # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
            for k in sku_sub_category_data:
                sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                  sales_unit=shop).first()
                # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                if sku_sub_category_sales:
                    # print("sub category skus Shop status exists")
                    if sku_sub_category_sales.shop_admin_status == "Visible":
                        # print(f"{sku_sub_category_sales}: Visible")
                        sub_category_remove_flag = False
                        break
            if sub_category_remove_flag:
                # print("No visible status available removed")
                update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
                if update_status:
                    update_status.sales_unit.remove(shop)
            else:
                update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
                if update_status:
                    update_status.sales_unit.add(shop)

    else:
        if category_id:
            for sub_cat in ProductSubCategory.objects.filter(category__uuid = category_id):

                sku_sub_category_data = SKU.objects.filter(product__item_sub_category=sub_cat,
                                                   sku_status="Visible")


                long_dist_sku_sub_category = sku_sub_category_data.filter(sku_expiry_duration__gt=30)
                if not long_dist_sku_sub_category:
                    sub_cat.long_distance_availability=False
                    sub_cat.save()
                else:

                    long_dist_sub_category_flag = False
                    for i in long_dist_sku_sub_category:
                        long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                        if long_dist_sales_check_sub:
                            if long_dist_sales_check_sub.status == "Visible":
                                sub_cat.long_distance_availability=True
                                sub_cat.save()
                                long_dist_sub_category_flag = True
                                break
                    if not long_dist_sub_category_flag:
                        sub_cat.long_distance_availability=False
                        sub_cat.save()

                # remove shop from the sub category list
                if not sku_sub_category_data:
                    sub_cat.sales_unit.remove(shop)
                else:
                    sub_category_remove_flag = True
                    # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                    for k in sku_sub_category_data:
                        sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                          sales_unit=shop).first()
                        # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                        if sku_sub_category_sales:
                            # print("sub category skus Shop status exists")
                            if sku_sub_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sub_category_sales}: Visible")
                                sub_category_remove_flag = False
                                break
                    if sub_category_remove_flag:
                        sub_cat.sales_unit.remove(shop)
                    else:
                        sub_cat.sales_unit.add(shop)
        else:
            for sub_cat in ProductSubCategory.objects.all():
                sku_sub_category_data = SKU.objects.filter(product__item_sub_category=sub_cat,
                                                   sku_status="Visible")
                long_dist_sku_sub_category = sku_sub_category_data.filter(sku_expiry_duration__gt=30)


                if not long_dist_sku_sub_category:
                    sub_cat.long_distance_availability=False
                    sub_cat.save()
                else:

                    long_dist_sub_category_flag = False
                    for i in long_dist_sku_sub_category:
                        long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                        if long_dist_sales_check_sub:
                            if long_dist_sales_check_sub.status == "Visible":
                                sub_cat.long_distance_availability=True
                                sub_cat.save()
                                long_dist_sub_category_flag = True
                                break
                    if not long_dist_sub_category_flag:
                        sub_cat.long_distance_availability=False
                        sub_cat.save()




                # remove shop from the sub category list
                if not sku_sub_category_data:
                    sub_cat.sales_unit.remove(shop)
                else:
                    sub_category_remove_flag = True
                    # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                    for k in sku_sub_category_data:
                        sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                          sales_unit=shop).first()
                        # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                        if sku_sub_category_sales:
                            # print("sub category skus Shop status exists")
                            if sku_sub_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sub_category_sales}: Visible")
                                sub_category_remove_flag = False
                                break
                    if sub_category_remove_flag:
                        # print("No visible status available removed")

                        sub_cat.sales_unit.remove(shop)
                    else:
                        sub_cat.sales_unit.add(shop)

    # product status checking
    # unique category and sub_category update the availability with the same flow
    sku_category_list = []
    sku_sub_category_list = []
    for product in product_list:

        sku_products = SKU.objects.filter(product = product, sku_status =  "Visible")
        long_dist_sku_product = sku_products.filter(sku_expiry_duration__gt=30)

        if not long_dist_sku_product:
            product.long_distance_availability=False
            product.save()
        else:

            long_dist_product_flag = False
            for i in long_dist_sku_product:
                long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=i).first()
                if long_dist_sales_check_sub:
                    if long_dist_sales_check_sub.status == "Visible":
                        product.long_distance_availability=True
                        product.save()
                        long_dist_product_flag = True
                        break
            if not long_dist_product_flag:
                product.long_distance_availability=False
                product.save()





        if not sku_products:
            product.sales_unit.remove(shop)
        else:
            product_remove_flag = True
            for sku_product in sku_products:
                sku_product_sales = SalesUnitProductSelection.objects.filter(sku=sku_product, sales_unit=shop).first()
                # print(f"category  skus Shop Status for {sku_category_sales}")
                if sku_product_sales:
                    # print("category skus Shop status exists")
                    if sku_product_sales.shop_admin_status == "Visible":
                        # print(f"{sku_category_sales}: Visible")
                        product_remove_flag = False
                        break
            if product_remove_flag:
                product.sales_unit.remove(shop)
            else:
                product.sales_unit.add(shop)

        # remove shop from the category list




    try:
        log_user = request.user
        log_type = "product"
        message = f"Product Status Updated for Category or Sub Category"
        description = f"Bulk Category update"
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                        description=description)
    except:
        pass


    paginator = Paginator(show_list , 10)

    products = paginator.get_page(1)


    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        tbody = render_to_string('product_page.html', {"product_data": products})
        pagination = render_to_string('pagination.html', {'product_data':products})
        return JsonResponse({'tbody': tbody, "pagination":pagination })
    base_url = reverse('list_shop_product', kwargs={'shop_id': shop_id, 'product_type': 'Master Product', "sales_unit_active": "active"})
    return redirect(base_url)


def update_product_product_admin_status(request):
    if request.method == 'POST':
        sku_id = request.POST.get('sku_id')
        shop_id = request.POST.get('shop_id')
        new_status = request.POST.get('status')
        try:
            sales_unit_product = SalesUnitProductSelection.objects.get(sales_unit=shop_id, sku=sku_id)
        except SalesUnitProductSelection.DoesNotExist:
            return JsonResponse({'success': False, 'error': 'Operation not allowed.'})
        try:
            sales_unit_product.shop_admin_status = new_status
            sales_unit_product.save()
            # if visible add the shop availablility

            if new_status == "Visible":
                sales_unit_product.sku.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.item_category.sales_unit.add(sales_unit_product.sales_unit)
                sales_unit_product.sku.product.item_sub_category.sales_unit.add(sales_unit_product.sales_unit)

                # else remove shop availablility
            else:
                sales_unit_product.sku.sales_unit.remove(sales_unit_product.sales_unit)

                # check sku exists for the product if any don't remove the shop from product
                sku_data = SKU.objects.filter(product=sales_unit_product.sku.product, sku_status="Visible")

                # print(f"SKU EXIST FOR PRODUCT AFTER DELETION: {sku_data}")

                # check sku exists for the sub category if any don't remove the shop from sub category

                sku_sub_category_data = SKU.objects.filter(
                    product__item_sub_category=sales_unit_product.sku.product.item_sub_category,
                    sku_status="Visible")

                # print(f"SKU EXIST FOR SUB CATEGORY AFTER DELETION: {sku_sub_category_data}")

                # check sku exists for the category if any don't remove the shop from sub category

                sku_category_data = SKU.objects.filter(
                    product__item_category=sales_unit_product.sku.product.item_category, sku_status="Visible")

                if not sku_data:
                    sales_unit_product.sku.product.sales_unit.remove(sales_unit_product.sales_unit)
                else:
                    product_remove_flag = True
                    # print(f"Iterating on Product skus : {sku_data}")
                    for j in sku_data:
                        sku_sales = SalesUnitProductSelection.objects.filter(sku=j,
                                                                             sales_unit=sales_unit_product.sales_unit).first()
                        # print(f"product skus Shop Status for {sku_sales}")
                        if sku_sales:
                            # print("product skus Shop status exists")

                            if sku_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sales}: Visible")
                                product_remove_flag = False
                                break
                    if product_remove_flag:
                        # print("No visible status available removed")
                        sales_unit_product.sku.product.sales_unit.remove(sales_unit_product.sales_unit)

                    # remove shop from the sub category list
                    if not sku_sub_category_data:
                        sales_unit_product.sku.product.item_sub_category.sales_unit.remove(
                            sales_unit_product.sales_unit)
                    else:
                        sub_category_remove_flag = True
                        # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                        for k in sku_sub_category_data:
                            sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                              sales_unit=sales_unit_product.sales_unit).first()
                            # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                            if sku_sub_category_sales:
                                # print("sub category skus Shop status exists")
                                if sku_sub_category_sales.shop_admin_status == "Visible":
                                    # print(f"{sku_sub_category_sales}: Visible")
                                    sub_category_remove_flag = False
                                    break
                        if sub_category_remove_flag:
                            # print("No visible status available removed")
                            sales_unit_product.sku.product.item_sub_category.sales_unit.remove(
                                sales_unit_product.sales_unit)

                    # remove shop from the category list
                    if not sku_category_data:
                        sales_unit_product.sku.product.item_category.sales_unit.remove(sales_unit_product.sales_unit)
                    else:
                        category_remove_flag = True
                        # print(f"Iterating category skus : {sku_category_data}")
                        for l in sku_category_data:
                            sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l,
                                                                                          sales_unit=sales_unit_product.sales_unit).first()
                            # print(f"category  skus Shop Status for {sku_category_sales}")
                            if sku_category_sales:
                                # print("category skus Shop status exists")
                                if sku_category_sales.shop_admin_status == "Visible":
                                    # print(f"{sku_category_sales}: Visible")
                                    category_remove_flag = False
                                    break
                        if category_remove_flag:
                            # print("No visible status available removed")
                            sales_unit_product.sku.product.item_category.sales_unit.remove(
                                sales_unit_product.sales_unit)

            try:
                log_user = request.user
                log_type = "product"
                message = f"Product Shop Admin Status Updated for Shop {sales_unit_product.sales_unit.unit_name}({sales_unit_product.sales_unit.unit_code})"
                description = f"SKU {sales_unit_product.sku.sku_name}  with code {sales_unit_product.sku.sku_code} updated its status to {new_status} for product {sales_unit_product.sku.product.item_name} ({sales_unit_product.sku.product.item_code} "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                                description=description)
            except:
                pass
            return JsonResponse({'status': 'success'})
        except:
            return JsonResponse({'error': 'Invalid request.'})

@login_required
@user_passes_test(check_user_role(["Shop Admin"]))
def category_based_shop_admin_update_status(request, shop_id):
    category_id = request.POST.get('category')
    sub_category_id = request.POST.get('subcategory')
    new_status = request.POST.get('status_category_select')
    shop = Shop.objects.filter(uuid = shop_id).first()
    product_list = Products.objects.order_by('-created_date')
    if category_id:
        product_list = product_list.filter(item_category__uuid=category_id)
    if sub_category_id:
        product_list = product_list.filter(item_sub_category=sub_category_id)
    update_list = []
    product_selection = SalesUnitProductSelection.objects.filter(sales_unit__uuid=shop_id)
    update_list = []
    show_list = []
    for i in product_list:
        sku_list = []
        for j in i.skus.all():
            if j.sku_status == "Visible":
                check = product_selection.filter(sku=j).first()
                if check.status == "Visible":
                    check.shop_admin_status = new_status
                    j.status = check.status
                    j.shop_admin_status = new_status
                else:
                    j.status = check.status
                    j.shop_admin_status = check.shop_admin_status
                update_list.append(check)
                sku_list.append(j)

            else:
                check = product_selection.filter(sku=j).first()
                j.status = check.status
                j.shop_admin_status = check.shop_admin_status
                update_list.append(check)
                sku_list.append(j)
        i.sku = sku_list
        show_list.append(i)


    SalesUnitProductSelection.objects.bulk_update(update_list, ['shop_admin_status'])




    if category_id:

        sku_category_data = SKU.objects.filter(product__item_category=category_id,
                                               sku_status="Visible")
        if not sku_category_data:
            update_status = ProductCategory.objects.filter(uuid=category_id).first()
            if update_status:
                update_status.sales_unit.remove(shop)
        else:
            category_remove_flag = True
            # print(f"Iterating category skus : {sku_category_data}")
            for l in sku_category_data:
                sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                # print(f"category  skus Shop Status for {sku_category_sales}")
                if sku_category_sales:
                    # print("category skus Shop status exists")
                    if sku_category_sales.shop_admin_status == "Visible":
                        # print(f"{sku_category_sales}: Visible")
                        category_remove_flag = False
                        break
            if category_remove_flag:
                # print("No visible status available removed")
                update_status = ProductCategory.objects.filter(uuid=category_id).first()
                if update_status:
                    update_status.sales_unit.remove(shop)
            else:
                update_status = ProductCategory.objects.filter(uuid=category_id).first()
                if update_status:
                    update_status.sales_unit.add(shop)
    else:

        for cat in ProductCategory.objects.all():
            sku_category_data = SKU.objects.filter(product__item_category=cat,
                                                   sku_status="Visible")
            if not sku_category_data:
                cat.sales_unit.remove(shop)
            else:
                category_remove_flag = True
                # print(f"Iterating category skus : {sku_category_data}")
                for l in sku_category_data:
                    sku_category_sales = SalesUnitProductSelection.objects.filter(sku=l, sales_unit=shop).first()
                    # print(f"category  skus Shop Status for {sku_category_sales}")
                    if sku_category_sales:
                        # print("category skus Shop status exists")
                        if sku_category_sales.shop_admin_status == "Visible":
                            # print(f"{sku_category_sales}: Visible")
                            category_remove_flag = False
                            break
                if category_remove_flag:
                    # print("No visible status available removed")
                    cat.sales_unit.remove(shop)
                else:
                    cat.sales_unit.add(shop)

    if sub_category_id:
        sku_sub_category_data = SKU.objects.filter(
            product__item_sub_category__uuid=sub_category_id,
            sku_status="Visible")

        # remove shop from the sub category list
        if not sku_sub_category_data:
            update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
            if update_status:
                update_status.sales_unit.remove(shop)
        else:
            sub_category_remove_flag = True
            # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
            for k in sku_sub_category_data:
                sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                  sales_unit=shop).first()
                # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                if sku_sub_category_sales:
                    # print("sub category skus Shop status exists")
                    if sku_sub_category_sales.shop_admin_status == "Visible":
                        # print(f"{sku_sub_category_sales}: Visible")
                        sub_category_remove_flag = False
                        break
            if sub_category_remove_flag:
                # print("No visible status available removed")
                update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
                if update_status:
                    update_status.sales_unit.remove(shop)
            else:
                update_status = ProductSubCategory.objects.filter(uuid=sub_category_id).first()
                if update_status:
                    update_status.sales_unit.add(shop)

    else:
        if category_id:
            for sub_cat in ProductSubCategory.objects.filter(category__uuid = category_id):

                sku_sub_category_data = SKU.objects.filter(product__item_sub_category=sub_cat,
                                                   sku_status="Visible")
                # remove shop from the sub category list
                if not sku_sub_category_data:
                    sub_cat.sales_unit.remove(shop)
                else:
                    sub_category_remove_flag = True
                    # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                    for k in sku_sub_category_data:
                        sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                          sales_unit=shop).first()
                        # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                        if sku_sub_category_sales:
                            # print("sub category skus Shop status exists")
                            if sku_sub_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sub_category_sales}: Visible")
                                sub_category_remove_flag = False
                                break
                    if sub_category_remove_flag:
                        sub_cat.sales_unit.remove(shop)
                    else:
                        sub_cat.sales_unit.add(shop)
        else:
            for sub_cat in ProductSubCategory.objects.all():
                sku_sub_category_data = SKU.objects.filter(product__item_sub_category=sub_cat,
                                                   sku_status="Visible")
                # remove shop from the sub category list
                if not sku_sub_category_data:
                    sub_cat.sales_unit.remove(shop)
                else:
                    sub_category_remove_flag = True
                    # print(f"Iterating on Sub category skus : {sku_sub_category_data}")
                    for k in sku_sub_category_data:
                        sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=k,
                                                                                          sales_unit=shop).first()
                        # print(f"sub category  skus Shop Status for {sku_sub_category_sales}")
                        if sku_sub_category_sales:
                            # print("sub category skus Shop status exists")
                            if sku_sub_category_sales.shop_admin_status == "Visible":
                                # print(f"{sku_sub_category_sales}: Visible")
                                sub_category_remove_flag = False
                                break
                    if sub_category_remove_flag:
                        # print("No visible status available removed")

                        sub_cat.sales_unit.remove(shop)
                    else:
                        sub_cat.sales_unit.add(shop)

    # product status checking
    # unique category and sub_category update the availability with the same flow
    sku_category_list = []
    sku_sub_category_list = []
    for product in product_list:

        sku_products = SKU.objects.filter(product = product, sku_status =  "Visible")
        if not sku_products:
            product.sales_unit.remove(shop)
        else:
            product_remove_flag = True
            for sku_product in sku_products:
                sku_product_sales = SalesUnitProductSelection.objects.filter(sku=sku_product, sales_unit=shop).first()
                # print(f"category  skus Shop Status for {sku_category_sales}")
                if sku_product_sales:
                    # print("category skus Shop status exists")
                    if sku_product_sales.shop_admin_status == "Visible":
                        # print(f"{sku_category_sales}: Visible")
                        category_remove_flag = False
                        break
            if product_remove_flag:
                product.sales_unit.remove(shop)
            else:
                product.sales_unit.add(shop)








    paginator = Paginator(show_list, 10)

    products = paginator.get_page(1)

    try:
        log_user = request.user
        log_type = "product"
        message = f"Product Status Updated for Category or Sub Category For Shop"
        description = f"Bulk Category update for Shop"
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                        description=description)
    except:
        pass

    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        tbody = render_to_string('product_list_page.html', {"product_data": products})

        pagination = render_to_string('pagination.html', {'product_data': products})
        return JsonResponse({'tbody': tbody, "pagination": pagination})


    base_url = reverse('list_product_shop_admin')
    return redirect(base_url)



@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def sub_category_creation(request, category_id):
    link_1 = request.POST.get('image_link_1', '/media/icons/icon.jpg')
    link_2 = request.POST.get('image_link_2', '/media/standard_images/standard_image.jpg')
    link_3 = request.POST.get('image_link_3', '/media/banners/banner.jpg')

    image_field1 = render_to_string('image_field.html', {'class_name': 'upload', 'image_reset_button': 'image_reset_button1', 'field_name' : 'icon'})
    image_field2 = render_to_string('image_field.html', {'class_name': 'upload2', 'image_reset_button': 'image_reset_button2', 'field_name' : 'standard_image'})
    image_field3 = render_to_string('image_field.html', {'class_name': 'upload3', 'image_reset_button': 'image_reset_button3', 'field_name' : 'banner_image'})

    errors = []
    if request.headers.get('x-requested-with') == 'XMLHttpRequest':
        category = get_object_or_404(ProductCategory, uuid=category_id)
        sub_category_form = ProductSubCategoryForm(request.POST)

        sub_category_list = ProductSubCategory.objects.filter(category=category)
        if sub_category_form.is_valid():
            sub_category = sub_category_form.save(commit=False)
            sub_category.category = category
            sub_category.save()
            try:
                log_user = request.user
                log_type = "product"
                message = "Sub category created"
                description = f"Sub category {sub_category.sub_category_name}  with code {sub_category.sub_category_code} created for category {sub_category.category.category_name} with code {sub_category.category.category_code}"
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass
            sub_categories = render_to_string('sub_category_delete_list.html', {'sub_category': sub_category_list})
            return JsonResponse({"data": sub_categories, "errors": [], "success": True,'image_field1': image_field1, 'image_field2': image_field2, 'image_field3': image_field3,
                 "link_1": link_1, "link_2": link_2, "link_3": link_3} )
        else:
            error = {}
            for i, data in sub_category_form.errors.items():
                error[i] = data[0]

            errors.append(sub_category_form.errors)

            if sub_category_list:
                sub_categories = render_to_string('sub_category_delete_list.html', {'sub_category': sub_category_list})
                return JsonResponse(
                {
                    "data": sub_categories,
                    "errors": error,
                    "success": False,
                    'image_field1': image_field1, 'image_field2': image_field2, 'image_field3': image_field3,
                    "link_1": link_1, "link_2": link_2, "link_3": link_3

                })
            else:
                return JsonResponse({
                    "data": [],
                    "errors": error,
                    "success": False,
                    'image_field1': image_field1, 'image_field2': image_field2, 'image_field3': image_field3,
                    "link_1": link_1, "link_2": link_2, "link_3": link_3


                })
    else:
        return JsonResponse({
            "data":[],
            "errors": {"sub_category_code":"Something went wrong try again"},
            "success" : False,
            'image_field1': image_field1, 'image_field2': image_field2, 'image_field3': image_field3,
                    "link_1": link_1, "link_2": link_2, "link_3": link_3
        })





def filter_products(request):
    category_id = request.GET.get('category_id', None)

    # Filter products based on the category selected
    if category_id:
        products = Products.objects.filter(item_category__uuid=category_id)
    else:
        products = Products.objects.all()  # Default all products

    # Prepare the data for JSON response
    product_list = []
    for product in products:
        product_list.append({
            'id': product.id,
            'name': product.name,
            'price': product.price,
            'category': product.category.name
        })

    return JsonResponse({'products': product_list})



# @login_required
# @user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
# def product_list_shop_admin(request, product_type = "Master Product"):
#     search_query = request.GET.get('search', "")
#
#     product_list = Products.objects.filter(product_type =product_type).order_by('-created_date')
#     category_list = ProductCategory.objects.all().order_by("-created_at")
#     shop_details = get_object_or_404(Shop,uuid = shop_id)
#     shop_name = shop_details.unit_name
#     shop_location = shop_details.unit_location
#
#     if search_query:
#         product_list = Products.objects.filter(product_type =product_type).filter(
#             Q(item_name__icontains=search_query) |
#             Q(item_code__icontains=search_query) |
#             Q(item_category__category_name__icontains=search_query)|
#             Q(item_sub_category__sub_category_name__icontains = search_query)
#         ).order_by('-created_date')
#
#     for i in product_list:
#         try:
#             sales_product = SalesUnitProductSelection.objects.get(sales_unit = shop_details.uuid, product= i.id)
#             i.status = sales_product.status
#         except:
#             i.status = "disable"
#     paginator = Paginator(product_list, 10)
#     page = request.GET.get('page')
#
#     try:
#         products = paginator.get_page(page)
#     except (PageNotAnInteger, TypeError):
#         products = paginator.get_page(1)
#     except EmptyPage:
#         products = paginator.get_page(paginator.num_pages)
#
#     base_url = reverse('list_shop_product',kwargs={'shop_id':shop_id, 'product_type':'Master Product'})
#     query_params = request.GET.copy()
#     if 'page' in query_params:
#         del query_params['page']
#     pagination_links = [
#         {
#             'page_number': page_number,
#             'url': f"{base_url}?{query_params.urlencode(safe='/')}&page={page_number}",
#         }
#         for page_number in products.paginator.page_range
#     ]
#     context = {
#         "product_data": products,
#         'search_query': search_query,
#         'pagination_links': pagination_links,
#         'product_type' : product_type,
#         "product_active": "active",
#         "shop_id": shop_id,
#         "shop_name": shop_name,
#         "shop_location":shop_location,
#         "category_list": category_list
#
#     }
#
#     return render(request, "product_list_shop.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def image_field_rendering(request):
    link_1 = request.GET.get('image_link_1', '/media/icons/icon.jpg')
    link_2 = request.GET.get('image_link_2', '/media/standard_images/standard_image.jpg')
    link_3 = request.GET.get('image_link_3', '/media/banners/banner.jpg')

    image_field1 = render_to_string('image_field.html', {'class_name': 'upload', 'image_reset_button': 'image_reset_button1', 'field_name' : 'icon'})
    image_field2 = render_to_string('image_field.html', {'class_name': 'upload2', 'image_reset_button': 'image_reset_button2', 'field_name' : 'standard_image',"link":  link_2})
    image_field3 = render_to_string('image_field.html', {'class_name': 'upload3', 'image_reset_button': 'image_reset_button3', 'field_name' : 'banner_image',"link":  link_3})
    return JsonResponse({'image_field1':image_field1, 'image_field2': image_field2, 'image_field3': image_field3, "link_1":  link_1, "link_2":  link_2,"link_3":  link_3 })

@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def tag_list(request):
    tags = Tags.objects.order_by("-created_at")
    paginator = Paginator(tags, 6)
    page = request.GET.get("page")
    try:
        tags = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        tags = paginator.get_page(1)
    except EmptyPage:
        tags = paginator.get_page(paginator.num_pages)
    context = {"tag_data": tags, "category_active": "active"}
    return render(request, "tag_list.html", context)



@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def tag_delete(request, tag_id):

    tags = Tags.objects.filter(pk=tag_id)
    if tags:
        tags.delete()
    return redirect("tag_list")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def tag_edit(request, tag_id):
    errors = []
    tags = get_object_or_404(Tags, pk=tag_id)
    if request.method == "POST":
        form = TagForm(request.POST, request.FILES, instance=tags)
        if form.is_valid():
            if request.POST.get('image1', ''):
                form.instance.icon = None
            form.save()
            return redirect("tag_list")

        else:
            errors.append(form.errors)
    else:
        form = TagForm(instance=tags)
    context = {"tag_form": form, "category_active": "active"}
    return render(request,"tag_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def tag_add(request):
    errors = []
    if request.method == "POST":
        tag_form = TagForm(request.POST, request.FILES)
        if tag_form.is_valid():
            tags = tag_form.save()
            return redirect("tag_list")
        else:
            errors.append(tag_form.errors)
            context = {
                "errors": errors,
                "tag_form": tag_form,
                "category_active": "active"
            }
            return render(request, "tag_add.html", context)
    else:
        tag_form = TagForm()

    context = {
        "errors": errors,
        "tag_form": tag_form,
        "category_active": "active"

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








@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def dynamic_filter_list(request):
    filter_list = DynamicFiltering.objects.order_by("-created_at")
    paginator = Paginator(filter_list, 6)
    page = request.GET.get("page")
    try:
        filter_list = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        filter_list = paginator.get_page(1)
    except EmptyPage:
        filter_list = paginator.get_page(paginator.num_pages)
    context = {"filter_data": filter_list, "category_active": "active"}
    return render(request, "dynamic_filter_list.html", context)



@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def dynamic_filter_delete(request, filter_id):

    filter_list = DynamicFiltering.objects.filter(pk=filter_id)
    if filter_list:
        filter_list.delete()
    return redirect("filter_list")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def dynamic_filter_edit(request, filter_id):
    errors = []
    filter_list = get_object_or_404(DynamicFiltering, pk=filter_id)
    if request.method == "POST":
        form = DynamicFilterForm(request.POST, instance=filter_list)
        if form.is_valid():
            form.save()
            return redirect("filter_list")

        else:
            errors.append(form.errors)
    else:
        form = DynamicFilterForm(instance=filter_list)
    context = {"filter_form": form, "category_active": "active"}
    return render(request,"dynamic_filter_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def dynamic_filter_add(request):
    errors = []
    if request.method == "POST":
        filter_form = DynamicFilterForm(request.POST)
        if filter_form.is_valid():
            filter = filter_form.save()
            return redirect("filter_list")
        else:
            errors.append(filter_form.errors)
            context = {
                "errors": errors,
                "filter_form": filter_form,
                "category_active": "active"
            }
            return render(request, "dynamic_filter_add.html", context)
    else:
        filter_form = DynamicFilterForm()

    context = {
        "errors": errors,
        "filter_form": filter_form,
        "category_active": "active"

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




@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def special_list(request):
    special_product_list = SpecialList.objects.order_by("-created_at")
    paginator = Paginator(special_product_list, 6)
    page = request.GET.get("page")
    try:
        special_product_list = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        special_product_list = paginator.get_page(1)
    except EmptyPage:
        special_product_list = paginator.get_page(paginator.num_pages)
    context = {"special_data": special_product_list, "category_active": "active"}
    return render(request, "special_list.html", context)



@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def special_list_delete(request, special_list_id):

    special_product_list = SpecialList.objects.filter(pk=special_list_id)
    if special_product_list:
        special_product_list.delete()
    return redirect("special_list")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def special_list_edit(request, special_list_id):
    errors = []
    special_product_list = get_object_or_404(SpecialList, pk=special_list_id)
    if request.method == "POST":
        form = SpecialListForm(request.POST, request.FILES, instance=special_product_list)
        if form.is_valid():
            if request.POST.get('image1', ''):
                form.instance.icon = None
            if request.POST.get('image2', ''):
                form.instance.standard_image = None
            if request.POST.get('image3', ''):
                form.instance.banner_image = None
            form.save()
            return redirect("special_list")

        else:
            errors.append(form.errors)
    else:
        form = SpecialListForm(instance=special_product_list)
    context = {"special_form": form, "category_active": "active"}
    return render(request,"special_list_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def special_list_add(request):
    errors = []
    if request.method == "POST":
        form = SpecialListForm(request.POST, request.FILES)
        if form.is_valid():
            special = form.save()
            return redirect("special_list")
        else:
            errors.append(form.errors)
            context = {
                "errors": errors,
                "special_form": form,
                "category_active": "active"
            }
            return render(request, "special_list_add.html", context)
    else:
        form = SpecialListForm()

    context = {
        "errors": errors,
        "special_form": form,
        "category_active": "active"

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





class SendVerificationEmailView(APIView):
    """
    View to send verification email.
    """
    # permission_classes = [IsAuthenticated]

    def post(self, request, delivery_boy):
        user = request.user
        delivery_boys = get_object_or_404(DeliveryBoys, pk=delivery_boy)
        if delivery_boys.status == 'verified':
            context = {"message": "Phone  alreay verified .", 'status': 0}
            return render(request, "phone_verification.html", context)


        # Create a token
        token = jwt.encode({'delivery_boy': str(delivery_boys.pk), 'exp': timezone.now() + timedelta(hours=24)},
                           settings.SECRET_KEY, algorithm='HS256')

        # Create verification link
        verification_link = request.build_absolute_uri(
            reverse('verify-phone', args=[token])
        )
        try:
            sms(f"click here to verify: {verification_link}", delivery_boys.phone_number)
            context = {"message": "Verification link sent to your phone number.", 'status': 1, "send" : 1}
        except Exception as e:
            context = {"message": str(e), 'status': 0, "send": 1}

        # Send the email
        # send_mail(
        #     'Verify your email',
        #     f'Click the link to verify your email: {verification_link}',
        #     settings.DEFAULT_FROM_EMAIL,
        #     [user.email],
        #     fail_silently=False,
        # )


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

        # return Response(
        #     {"status": 1, "message": "Verification email sent."},
        #     status=status.HTTP_200_OK
        # )


class VerifyEmailView(APIView):
    def get(self, request, token):
        try:
            payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
            delivery_boys = get_object_or_404(DeliveryBoys, pk=payload['delivery_boy'])

            # Update email verification status
            delivery_boys.status  = "verified"
            delivery_boys.save()

            return render(request, 'phone_verification.html', {
                'status': 1,
                'message': "Phone number verified successfully.",
                "send": 0
            })
        except jwt.ExpiredSignatureError:
            return render(request, 'phone_verification.html', {
                'status': 0,
                'message': "Verification link has expired.",
                "send": 0
            })
        except jwt.InvalidTokenError:
            return render(request, 'phone_verification.html', {
                'status': 0,
                'message': "Invalid verification link.",
                "send": 0
            })


@user_passes_test(check_user_role(["Shop Admin", "PU Admin"]))
def delivery_boy_list(request):
    shop_id_verify = Shop.objects.prefetch_related('unit_admin_user').filter(
        unit_admin_user__uuid=request.user.uuid)
    if shop_id_verify:
        shop_id = shop_id_verify[0]
    else:
        shop_id = ""
    delivery_boys = DeliveryBoys.objects.filter(shop=shop_id).order_by("-created_date")
    paginator = Paginator(delivery_boys, 6)
    page = request.GET.get("page")
    try:
        delivery_boys = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        delivery_boys = paginator.get_page(1)
    except EmptyPage:
        delivery_boys = paginator.get_page(paginator.num_pages)
    context = {"delivery_boy_data": delivery_boys, "orders_active": "active"}
    return render(request, "delivery_boy_list.html", context)



@require_POST
@login_required
@user_passes_test(check_user_role(["Shop Admin"]))
def delivery_boy_delete(request, delivery_boy_id):

    delivery_boy = DeliveryBoys.objects.filter(pk=delivery_boy_id)
    if delivery_boy:
        delivery_boy.delete()
    return redirect("delivery_boy_list")


@login_required
@user_passes_test(check_user_role(["Shop Admin"]))
def delivery_boy_edit(request, delivery_boy_id):
    errors = []
    delivery_boy = DeliveryBoys.objects.filter(pk=delivery_boy_id).first()
    if request.method == "POST":
        form = DeliveryBoyForm(request.POST,  instance=delivery_boy)
        if form.is_valid():
            delivery_boy = form.save()
            delivery_boy.status = "not verified"
            delivery_boy.save()
            return redirect("delivery_boy_list")

        else:
            errors.append(form.errors)
    else:
        form = DeliveryBoyForm(instance=delivery_boy)
    context = {"delivery_boy_form": form, "orders_active": "active"}
    return render(request,"delivery_boy_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Shop Admin"]))
def delivery_boy_add(request):
    errors = []
    if request.method == "POST":
        shop_id_verify = Shop.objects.prefetch_related('unit_admin_user').filter(
            unit_admin_user__uuid=request.user.uuid)
        if shop_id_verify:
            shop_id = shop_id_verify[0]
        else:
            shop_id = ""
        form = DeliveryBoyForm(request.POST)
        if form.is_valid():
            delivery_boy = form.save()
            delivery_boy.shop = shop_id
            delivery_boy.save()
            return redirect("delivery_boy_list")
        else:
            errors.append(form.errors)
            context = {
                "errors": errors,
                "delivery_boy_form": form,
                "orders_active": "active"
            }
            return render(request, "delivery_boy_add.html", context)
    else:
        form = DeliveryBoyForm()

    context = {
        "errors": errors,
        "delivery_boy_form": form,
        "orders_active": "active"

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

#pip install twilio
def sms(body,to_phone):
    from twilio.rest import Client

    account_sid ="ACfc9c614f2bef8ec1f28de11cb0c817ce"
    auth_token = "1ee4f85a13e7475e7b236daca7017721"
    fromph = "+14178043450"
    to_phone= str(to_phone)
    # Here we'll build a new Twilio_client with different credentials
    twilio_client = Client(account_sid, auth_token)

    message = twilio_client.messages.create(
        to=to_phone,
        from_= fromph,
        body=body)


@login_required
@user_passes_test(check_user_role(["Shop Admin", "PU Admin"]))
def order_list(request, order_id = None):
    try:
        shop_id_verify = Shop.objects.filter(
            unit_admin_user__uuid=request.user.uuid)
        if shop_id_verify:
            shop_id = shop_id_verify[0]
        else:
            shop_id = ""
        errors = []
        field_name = request.COOKIES.get('field_name')
        sort_order = request.COOKIES.get('sort_order')


        if request.method == "POST":
            order_delivery = OrderDelivery.objects.filter(order=order_id).first()
            order = Orders.objects.filter(pk=order_id).first()
            form = CourierDetailsForm(request.POST, instance=order_delivery)
            if form.is_valid():
                delivery_data = form.save()
                delivery_data.order = order
                delivery_data.delivery_type = "Courier Delivery"
                delivery_data.save()
                if order.order_status == "Order Packed":
                    order.order_status = "Despatched"
                    order.save()

                    title = "Order Despatched"
                    description = "Your Order Despatched Successfully"
                    try:
                        initialize_fcm_app()
                        send_notification(order.user_uuid.fcm_token, order, title, description, order.user_uuid)
                    except:
                        pass

                #send notification



                #.........................
                return JsonResponse({
                    'status': 'success',
                    'order_id': order_id,
                    'OrderID': order.order_ID,
                })


            else:
                errors.append(form.errors)
                return JsonResponse({'status': 'fail', 'errors': form.errors})
        search_query = request.GET.get('search', "")
        order_date = request.GET.get('product_date', "")
        order_status = request.GET.get('product_status', "")
        sort_order_data = request.GET.get('sort_order', "")
        if not sort_order_data:
            sort_order_data = sort_order
        field_name_data = request.GET.get('field_name', "")
        if not field_name_data:
            field_name_data = field_name

        if shop_id:
            order_list = Orders.objects.filter(store_uuid=shop_id, order_type__in = ["Local Orders", "Pick Up"]).exclude(order_status="New Order").order_by('-created_date')
        else:

            order_list = Orders.objects.filter(order_type = "Long Distance Orders").exclude(order_status = "New Order").order_by(
                '-created_date')

        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            if search_query:
                order_list = order_list.filter(
                    Q(order_ID__icontains=search_query) |
                    Q(order_type__icontains=search_query) |
                    Q(order_status__icontains=search_query) |
                    Q(user_uuid__first_name__icontains=search_query)
                ).order_by('-created_date')

            if order_date:
                formatted_date = datetime.strptime(order_date, "%Y-%m-%d")
                order_list = order_list.filter(created_date__date=formatted_date)
            if order_status:
                order_list = order_list.filter(product_status=order_status)

            if sort_order_data and field_name_data:
                if sort_order_data == 'asc':
                    if field_name_data == 'user_uuid':
                        order_list = order_list.order_by(field_name_data + '__first_name')
                    else:
                        order_list = order_list.order_by(field_name_data)
                else:
                    if field_name_data == 'user_uuid':
                        order_list = order_list.order_by('-' + field_name_data + '__first_name')
                    else:
                        order_list = order_list.order_by('-' + field_name_data)

        paginator = Paginator(order_list, 6)
        page = request.GET.get('page')

        try:
            orders = paginator.get_page(page)
        except (PageNotAnInteger, TypeError):
            orders = paginator.get_page(1)
        except EmptyPage:
            orders = paginator.get_page(paginator.num_pages)

        base_url = reverse('order_list')
        query_params = request.GET.copy()
        if 'page' in query_params:
            del query_params['page']
        pagination_links = [
            {
                'page_number': page_number,
                'url': f"{base_url}?{query_params.urlencode(safe='/')}&page={page_number}",
            }
            for page_number in orders.paginator.page_range
        ]
        form = CourierDetailsForm()
        try:
            ongoing_orders = DeliveryBoys.objects.filter(status='verified', shop = shop_id)
        except:
            ongoing_orders = []

        context = {
            "courier_form": form,
            "order_data": orders,
            'search_query': search_query,
            'date': order_date,
            'product_status': order_status,
            'pagination_links': pagination_links,
            "ongoing_orders": ongoing_orders,
            "orders_active": "active"

        }

        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            tbody = render_to_string('order_list_page.html',
                                     {"order_data": orders, 'pagination_links': pagination_links,
                                      "ongoing_orders": ongoing_orders})
            pagination = render_to_string('order_list_pagination.html', {"order_data": orders})
            return JsonResponse({'tbody': tbody, "pagination": pagination})

        errors = []

        # context = {
        #     "order_data": orders,
        #     'search_query': search_query,
        #     'date': order_date,
        #     'product_status': order_status,
        #     'pagination_links': pagination_links,
        #     "ongoing_orders": ongoing_orders,
        #     "errors": errors,
        #     "courier_form": form,
        #     "orders_active": "active",
        #     "modal_active": "active"
        # }
        # return render(request, "order_list.html", context)


        response = render(request, "order_list.html", context)
        # response.delete_cookie('field_name', path = r'/adminportal/orders', domain = '127.0.0.1')
        # response.delete_cookie('sort_order', path = r'/adminportal/orders', domain = '127.0.0.1')
        # response.set_cookie('field_name', 'created_date')
        # response.set_cookie('sort_order', 'desc')
        # if field_name_data:
        #
        #     response.set_cookie('field_name', field_name_data)
        #     response.set_cookie('sort_order', sort_order_data)
        # else:

        return response
    #
    except IndexError:
        context = {
            "order_data": [],
            "orders_active": "active"

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



#
#
#
#

@login_required
@user_passes_test(check_user_role(["PU Admin"]))
def courier_details_edit(request, order_id):
    csrf = request.POST.get('csrfmiddlewaretoken')
    errors = []
    button_status = "false"
    order_delivery = OrderDelivery.objects.filter(order=order_id).first()

    if order_delivery:
        form = CourierDetailsForm(instance = order_delivery)
        if order_delivery.order.order_status =="Order Packed":
            button_status = "true"

    else:
        order = Orders.objects.filter(uuid=order_id).first()
        order_delivery = OrderDelivery.objects.create(delivery_type= "Courier Delivery", order = order)
        form = CourierDetailsForm(instance = order_delivery)
        if order.order_status == "Order Packed":
            button_status = "true"




    courier_form = render_to_string('courier_edit_form.html',
                     {'courier_form':form , "order_id" : order_id, "button_status" : button_status})

    return JsonResponse({'success': True,'form':courier_form})


class ShipperAutocomplete(autocomplete.Select2QuerySetView):
    def get_result_label(self, item):
        # Customize the format of the autocomplete options
        return f"{item.team_member_name}"

    def get_queryset(self):
        ongoing_orders = DeliveryBoys.objects.filter(status='verified', delivery_boy_status='not assigned')
        if self.q:
            ongoing_orders = ongoing_orders.filter(team_member_name__istartswith=self.q)

        return ongoing_orders

def save_shipper(request):

    if request.method == 'POST':
        shipper_uuid = request.POST.get('shipper_uuid')
        page = request.POST.get('page')
        search = request.POST.get('search')
        product_date = request.POST.get('product_date')
        try:
            shipper = DeliveryBoys.objects.filter(pk=shipper_uuid).first()
            # if shipper.delivery_boy_status == "assigned":
            #     return JsonResponse({"sucess": False, 'message': 'Shipper Already Assigned'})
            order_uuid = request.POST.get('order_uuid')
            order=Orders.objects.filter(uuid=order_uuid).first()
            if order.order_status in ["Viewed", "New Order"]:
                return JsonResponse({'success': False,'message':'Order not confirmed'})
            if order.order_status == 'Delivered':
                return JsonResponse({'success': False,'message':'Order already delivered'})
            if order.order_status == 'Failed':
                return JsonResponse({'success': False, 'message': 'Order Failed'})
            if order.order_status == "Delivery Assigned":
                return JsonResponse({'success': False, 'message': 'Order already Assigned'})
            order.order_status="Delivery Assigned"
            order.order_assigntime = timezone.now()
            order.delivery_boy = shipper_uuid

            delivery_boy=OrderDelivery.objects.get_or_create(delivery_boy=shipper, order=order,  defaults={'delivery_type': order.order_type})
            shipper.delivery_boy_status = 'assigned'
            shipper.save()
            order.save()
            # send notification
            try:
                whatsapp_msg = f"You are Assigned to the Order {order.order_ID}"
                delivery_boy = DeliveryBoys.objects.filter(id =order.delivery_boy).first()
                if delivery_boy:
                    drop_address = str(order.drop_address.name) + ", " + str(order.drop_address.house_number_or_name)+", "+str(order.drop_address.street)+ " "+ str(order.drop_address.land_mark)+ ", "+str(order.drop_address.city)+ " "+ str(order.drop_address.district)+", "+str(order.drop_address.state_or_province)+" "+str(order.drop_address.pin_code)
                    pick_up_address = str(order.store_uuid.unit_name) + "(" + str(order.store_uuid.unit_code) + "), "+str(order.store_uuid.unit_location)+","+str(order.store_uuid.street)+ ", " +str(order.store_uuid.city)+" "+ str(order.store_uuid.district)+", "+str(order.store_uuid.state_or_province)
                    START_LAT = order.drop_address.latitude
                    START_LNG = order.drop_address.longitude
                    DEST_LAT = order.store_uuid.latitude
                    DEST_LNG = order.store_uuid.longitude
                    google_place_link = f"https://www.google.com/maps/dir/{START_LAT},{START_LNG}/{DEST_LAT},{DEST_LNG}"
                    data = {"pick_up_address": pick_up_address, "drop_address": drop_address, "google_place_link": google_place_link}
                    data = send_whatsapp_message_delivery_boy(delivery_boy.phone_number,delivery_boy.team_member_name, data)
            except Exception as e:
                print(e)
            try:
                initialize_fcm_app()
                title = "Order Assigned"
                description = "Your Order Assigned Successfully, Delivery Boy will reach you shortly!"
                send_notification(order.user_uuid.fcm_token, order, title, description, order.user_uuid)
            except:
                pass

            # .........................
            return JsonResponse({'success': "True", 'page': page, 'search': search, 'product_date': product_date})
        except:
            return JsonResponse({'success': "False", 'page': page, 'search': search, 'product_date': product_date})

    else:
        return JsonResponse({'success': "False"})

def save_order_status(request):
    if request.method == 'POST':
        page = request.POST.get('page')
        search = request.POST.get('search')
        product_date = request.POST.get('product_date')
        try:
            order_uuid = request.POST.get('order_uuid')
            status = request.POST.get('selected_value').strip()
            order = Orders.objects.filter(uuid=order_uuid).first()
            order.order_status = status
            order.save()
            if status  == "Order Packed":
                try:
                    combined_datetime = datetime.combine(order.delivery_slot_date, order.delivery_slot_time)
                except:
                    combined_datetime = datetime.now()
                time_dif_with_del_slot = combined_datetime.astimezone() - datetime.now().astimezone()
                duration_in_s_data = time_dif_with_del_slot.total_seconds()
                hours_del = divmod(duration_in_s_data, 3600)[0]


                if hours_del < 0:
                    order.color_status = "Red"
                    order.color_status_updation_time = datetime.now()
                    order.save()

                elif hours_del < 1 and hours_del > 0:
                    order.color_status = "Orange"
                    order.color_status_updation_time = datetime.now()
                    order.save()
                else:
                    order.color_status = "White"
                    order.color_status_updation_time = datetime.now()
                    order.save()
            if status == "Failed":
                order.color_status = "Dark Red"
                order.color_status_updation_time = datetime.now()
                order.save()
                try:
                    shipper_uuid = order.delivery_boy
                    shipper = DeliveryBoys.objects.filter(pk=shipper_uuid).first()
                    if shipper.delivery_boy_status == "assigned":
                        shipper.delivery_boy_status = "not assigned"
                        shipper.save()
                except:
                    pass

            if status in ["Delivery Assinged", "Despatched", "Delivered"]:
                order.color_status = "White"
                order.color_status_updation_time = datetime.now()
                order.save()

                # if order status delivered
                if status == "Delivered":
                    try:
                        shipper_uuid = order.delivery_boy
                        shipper = DeliveryBoys.objects.filter(pk=shipper_uuid).first()
                        if shipper.delivery_boy_status == "assigned":
                            shipper.delivery_boy_status = "not assigned"
                            shipper.save()
                    except:
                        pass


            order.save()
            # send notification
            try:
                initialize_fcm_app()
            except:
                pass
            if status == "Order Packed":
                description = "Your Order Packed Successfully, Delivery Boy will pick your order shortly!"
            elif status == "Delivery Assigned":
                description = "Your Order Assigned Successfully, your order will reach your foot steps shortly!"
            elif status == "Delivered":
                description = "Your Order Delivered Successfully, Please give your valuable feed for better future endevours!"
            elif status == 'Failed':
                description = "Sorry! Your Order Failed!"
            else:
                description = "Your Order Status will be updated soon!"
            title = status
            try:

                send_notification(order.user_uuid.fcm_token, order, title, description, order.user_uuid)




            except Exception as e:
                print(e)

                pass

            return JsonResponse({'status': 'success', 'page': page,  'search': search, 'product_date': product_date})
        except Exception as e:
            return JsonResponse({'status': 'fail', 'msg': str(e), 'page': page, 'search': search, 'product_date': product_date})
        
@csrf_exempt
def save_customorder_status(request):
    if request.method == 'POST':
        try:
            order_uuid = request.POST.get('order_uuid')
            status = request.POST.get('selected_value')

            order = Orders.objects.filter(uuid=order_uuid).first()

            if not order:
                return JsonResponse({'status': 'fail', 'msg': 'Order not found'})

            # Ensure the status cannot be changed once set to "Contacted"
            if order.order_status == "Contacted":
                return JsonResponse({'status': 'fail', 'msg': 'Order status cannot be changed after being set to Contacted'})

            order.order_status = status
            order.save()

            return JsonResponse({'status': 'success'})
        except Exception as e:
            return JsonResponse({'status': 'fail', 'msg': str(e)})
        
@csrf_exempt  # Remove this if CSRF token is handled properly in the frontend
def save_customorder_data(request):

    if request.method == 'POST':
        
        uuid = request.POST.get('order_ID')  # Ensure the key name matches the form field
        order = Orders.objects.filter(order_ID=uuid).first()  # Fetch existing order
        
        if not order:
            return JsonResponse({'status': 'fail', 'msg': 'Order not found'})
        
        # Bind the form to update the existing order instance
        form = CustomOrderForm(request.POST, instance=order)
        
        if form.is_valid():
            form.save()  # This will update the existing order
            return JsonResponse({'status': 'success', 'message': 'Order updated successfully'})
        else:
            return JsonResponse({'status': 'error', 'errors': form.errors})

    return JsonResponse({'status': 'error', 'message': 'Invalid request method'})


def order_status_update_to_viewed(request, orderID):
    if request.method == 'POST':
        page = request.POST.get('page')
        search = request.POST.get('search')
        product_date = request.POST.get('product_date')
        try:
            order = Orders.objects.filter(order_ID=orderID).first()
            if order.order_status == 'Confirmed':
                order.order_status = 'Viewed'
                order.save()
                # send notification

                title = "Order Viewed"
                description = "Your Order Viewed by the Merchant and will be packed soon!"
                try:
                    initialize_fcm_app()
                    send_notification(order.user_uuid.fcm_token, order, title, description, order.user_uuid)
                except Exception as e:
                    print(e)

                    pass
                return JsonResponse({'status': 'success',  'page': page, 'search': search, 'product_date': product_date})
            return JsonResponse({'status': 'fail',  'page': page, 'search': search, 'product_date': product_date})


        except Exception as e:
            return JsonResponse({'status': 'fail' , 'msg': str(e), 'page': page, 'search': search, 'product_date': product_date})

def coupon_list(request):
    coupon = Coupons.objects.order_by("-created_at")
    paginator = Paginator(coupon, 6)
    page = request.GET.get("page")
    try:
        coupon_list_data = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        coupon_list_data = paginator.get_page(1)
    except EmptyPage:
        coupon_list_data = paginator.get_page(paginator.num_pages)
    context = {"coupon_data": coupon_list_data, "promotion_active": "active"}
    return render(request, "coupon_list.html", context)

def coupon_delete(request, coupon_id):
    coupon = Coupons.objects.filter(pk=coupon_id)

    if coupon:
        ads = Ads.objects.filter(Coupon = coupon_id)

        if ads:
            messages.add_message(request, messages.WARNING,
                                 "Your coupon used in ads! couldn't delete coupon")
            # messages.error(request, "Your coupon used in ads! couldn't delete coupon")
        else:
            coupon.delete()
    return redirect("list_coupons")

def coupon_edit(request, coupon_id):
    errors = []

    coupon = Coupons.objects.filter(pk=coupon_id).first()
    if request.method == "POST":
        post_data = request.POST.copy()
        if '' in post_data.getlist('ApplicableCategory', None):
            category_list = post_data.getlist('ApplicableCategory', None)
            if category_list:
                category_list.remove('')
            post_data.setlist('ApplicableCategory', category_list)

        if '' in post_data.getlist('ApplicableSubCategory', None):
            sub_category_list = post_data.getlist('ApplicableSubCategory', None)
            if sub_category_list:
                sub_category_list.remove('')
            post_data.setlist('ApplicableSubCategory', sub_category_list)
        if '' in post_data.getlist('ApplicableProduct', None):
            product_list = post_data.getlist('ApplicableProduct', None)
            if product_list:
                product_list.remove('')
            post_data.setlist('ApplicableProduct', product_list)

        if '' in post_data.getlist('ApplicableSku', None):
            sku_list = post_data.getlist('ApplicableSku', None)
            if sku_list:
                sku_list.remove('')
            post_data.setlist('ApplicableSku', sku_list)


        coupon_on = post_data.get("CouponOn", None)


        try:
            if coupon_on == "Category":
                del(post_data['ApplicableSubCategory'])
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif coupon_on == "SubCategory":
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif coupon_on == "Product":
                del(post_data['ApplicableSku'])
        except:
            pass




        form = CouponForm(post_data, request.FILES, instance=coupon)


        if form.is_valid():
            if request.POST.get('image', ''):
                form.instance.Icon = None
            if request.POST.get("CouponType") == "amount":
                form.instance.DiscountPercentage=None
                form.instance.MaxDiscountAmountForPercentage=None
            else:
                form.instance.DiscountAmount=None
            try:
                form.save()
            except  ValidationError as e:
                error_data = e.message_dict
                form.add_error(list(error_data.keys())[0], e.messages[0])
                return JsonResponse({"success": False, 'errors': form.errors})

            return JsonResponse({'success': True})

        else:
            errors.append(form.errors)
            return JsonResponse({'success': False, 'errors': form.errors})
    else:
        form = CouponForm(instance=coupon)
    context = {
        "errors": errors,
        "coupon_form": form,
        "coupon_id" : coupon.pk,
        "promotion_active": "active",
        "coupon_data": coupon.CouponOn,
        "coupon_type":coupon.CouponType
    }
    return render(request,"coupon_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def coupon_add(request):
    errors = []
    if request.method == "POST":
        post_data = request.POST.copy()
        if '' in post_data.getlist('ApplicableCategory', None):
            category_list = post_data.getlist('ApplicableCategory', None)
            if category_list:
                category_list.remove('')
            post_data.setlist('ApplicableCategory', category_list)

        if '' in post_data.getlist('ApplicableSubCategory', None):
            sub_category_list = post_data.getlist('ApplicableSubCategory', None)
            if sub_category_list:
                sub_category_list.remove('')
            post_data.setlist('ApplicableSubCategory', sub_category_list)
        if '' in post_data.getlist('ApplicableProduct', None):
            product_list = post_data.getlist('ApplicableProduct', None)
            if product_list:
                product_list.remove('')
            post_data.setlist('ApplicableProduct', product_list)

        if '' in post_data.getlist('ApplicableSku', None):
            sku_list = post_data.getlist('ApplicableSku', None)
            if sku_list:
                sku_list.remove('')
            post_data.setlist('ApplicableSku', sku_list)


        coupon_on = post_data.get("CouponOn", None)


        try:
            if coupon_on == "Category":
                del(post_data['ApplicableSubCategory'])
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif coupon_on == "SubCategory":
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif coupon_on == "Product":
                del(post_data['ApplicableSku'])
        except:
            pass

        coupon_form = CouponForm(post_data, request.FILES)



        if coupon_form.is_valid():
            if request.POST.get('image', ''):
                coupon_form.instance.Icon = None
            if request.POST.get("CouponType") == "amount":
                coupon_form.instance.DiscountPercentage=None
                coupon_form.instance.MaxDiscountAmountForPercentage=None
            else:
                coupon_form.instance.DiscountAmount=None

            try:
                coupon_form.save()
            except  ValidationError as e:
                error_data = e.message_dict
                coupon_form.add_error(list(error_data.keys())[0], e.messages[0])
                return JsonResponse({"success": False, 'errors': coupon_form.errors})
            return JsonResponse({'success': True })
        else:
            errors.append(coupon_form.errors)
            return JsonResponse({'success': False, 'errors': coupon_form.errors})

    else:
        coupon_form = CouponForm()
        errors = []
    context = {
        "errors": errors,
        "coupon_form": coupon_form,
        "promotion_active": "active",
        "coupon_data": "Category",
        "coupon_type": "amount"
    }
    return render(request, "coupon_add.html", context)

@user_passes_test(check_user_role(["Super Admin", "NBC Admin", "PU Admin"]))
def delivery_slot_list(request):
    # shop_id_verify = Shop.objects.prefetch_related('unit_admin_user').filter(
    #     unit_admin_user__uuid=request.user.uuid)
    # shop_id = shop_id_verify[0]

    delivery_slots = DeliverySlot.objects.order_by('-created_at') #.filter(shop = shop_id)
    paginator = Paginator(delivery_slots, 6)
    page = request.GET.get("page")
    try:
        delivery_slot = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        delivery_slot = paginator.get_page(1)
    except EmptyPage:
        delivery_slot = paginator.get_page(paginator.num_pages)
    context = {"delivery_slot_data": delivery_slot, "orders_active": "active"}
    return render(request, "delivery_slot_list.html", context)



@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delivery_slot_delete(request, delivery_slot_id):

    delivery_slot = DeliverySlot.objects.filter(pk=delivery_slot_id)
    if delivery_slot:
        delivery_slot.delete()
    return redirect("delivery_slot_list")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delivery_slot_edit(request, delivery_slot_id):
    errors = []

    delivery_slot = DeliverySlot.objects.filter(pk=delivery_slot_id).first()
    if request.method == "POST":
        form = DeliverySlotForm(request.POST,  instance=delivery_slot) #request = request
        if form.is_valid():
            del_slot = form.save()

            return redirect("delivery_slot_list")

        else:
            errors.append(form.errors)
    else:
        form = DeliverySlotForm(instance=delivery_slot) # , request = request
    context = {"delivery_slot_form": form, "orders_active": "active"}
    return render(request,"delivery_slot_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delivery_slot_add(request):
    errors = []

    if request.method == "POST":
        form = DeliverySlotForm(request.POST) #, request = request
        if form.is_valid():
            del_slot = form.save()
            return redirect("delivery_slot_list")
        else:
            errors.append(form.errors)
            context = {
                "errors": errors,
                "delivery_slot_form": form,
                "orders_active": "active"
            }
            return render(request, "delivery_slot_add.html", context)
    else:
        form = DeliverySlotForm() #request = request

    context = {
        "errors": errors,
        "delivery_slot_form": form,
        "orders_active": "active"

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


def discount_list(request):
    discount = Discount.objects.order_by("-created_at")
    paginator = Paginator(discount, 6)
    page = request.GET.get("page")
    try:
        discount_list_data = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        discount_list_data = paginator.get_page(1)
    except EmptyPage:
        discount_list_data = paginator.get_page(paginator.num_pages)
    context = {"discount_data": discount_list_data, "promotion_active": "active"}
    return render(request, "discount_list.html", context)

def discount_delete(request, discount_id):
    discount = Discount.objects.filter(pk=discount_id)
    if discount:
        ads = Ads.objects.filter(Discount=discount_id)
        messages.add_message(request, messages.WARNING,
                                 "Your Discount used in ads! couldn't delete discount")
            # messages.error(request, "Your coupon used in ads! couldn't delete coupon")
    else:
        discount.delete()
    return redirect("list_discounts")

def discount_edit(request, discount_id):
    errors = []

    discount = Discount.objects.filter(pk=discount_id).first()
    if request.method == "POST":
        post_data = request.POST.copy()

        if '' in post_data.getlist('ApplicableCategory', None):
            category_list = post_data.getlist('ApplicableCategory', None)
            if category_list:
                category_list.remove('')
            post_data.setlist('ApplicableCategory', category_list)

        if '' in post_data.getlist('ApplicableSubCategory', None):
            sub_category_list = post_data.getlist('ApplicableSubCategory', None)
            if sub_category_list:
                sub_category_list.remove('')
            post_data.setlist('ApplicableSubCategory', sub_category_list)
        if '' in post_data.getlist('ApplicableProduct', None):
            product_list = post_data.getlist('ApplicableProduct', None)
            if product_list:
                product_list.remove('')
            post_data.setlist('ApplicableProduct', product_list)

        if '' in post_data.getlist('ApplicableSku', None):
            sku_list = post_data.getlist('ApplicableSku', None)
            if sku_list:
                sku_list.remove('')
            post_data.setlist('ApplicableSku', sku_list)


        discount_on = post_data.get("DiscountOn", None)


        try:
            if discount_on == "Category":
                del(post_data['ApplicableSubCategory'])
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif discount_on == "SubCategory":
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif discount_on == "Product":
                del(post_data['ApplicableSku'])
        except:
            pass

        form = DiscountForm(post_data, request.FILES, instance=discount)
        if form.is_valid():

            if request.POST.get('image2', ''):
                form.instance.StandardImage = None
            if request.POST.get('image3', ''):
                form.instance.BannerImage = None
            form.save()
            return JsonResponse({'success': True})

        else:
            errors.append(form.errors)
            return JsonResponse({'success': False, 'errors': form.errors})
    else:
        form = DiscountForm(instance=discount)
    context = {
        "errors": errors,
        "discount_form": form,
        "discount_id": discount.pk,
        "promotion_active": "active",
        "discount_data": discount.DiscountOn
    }
    return render(request,"discount_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def discount_add(request):
    errors = []
    if request.method == "POST":
        post_data = request.POST.copy()
        if '' in post_data.getlist('ApplicableCategory', None):
            category_list = post_data.getlist('ApplicableCategory', None)
            if category_list:
                category_list.remove('')
            post_data.setlist('ApplicableCategory', category_list)

        if '' in post_data.getlist('ApplicableSubCategory', None):
            sub_category_list = post_data.getlist('ApplicableSubCategory', None)
            if sub_category_list:
                sub_category_list.remove('')
            post_data.setlist('ApplicableSubCategory', sub_category_list)
        if '' in post_data.getlist('ApplicableProduct', None):
            product_list = post_data.getlist('ApplicableProduct', None)
            if product_list:
                product_list.remove('')
            post_data.setlist('ApplicableProduct', product_list)

        if '' in post_data.getlist('ApplicableSku', None):
            sku_list = post_data.getlist('ApplicableSku', None)
            if sku_list:
                sku_list.remove('')
            post_data.setlist('ApplicableSku', sku_list)

        discount_on = post_data.get("DiscountOn", None)


        try:
            if discount_on == "Category":
                del(post_data['ApplicableSubCategory'])
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif discount_on == "SubCategory":
                del(post_data['ApplicableProduct'])
                del(post_data['ApplicableSku'])

            elif discount_on == "Product":
                del(post_data['ApplicableSku'])
        except:
            pass

        discount_form = DiscountForm(post_data, request.FILES)
        if discount_form.is_valid():
            if request.POST.get('image2', ''):
                discount_form.instance.StandardImage = None
            if request.POST.get('image3', ''):
                discount_form.instance.BannerImage = None
            discount_form.save()
            return JsonResponse({'success': True })
        else:
            errors.append(discount_form.errors)
            return JsonResponse({'success': False, 'errors': discount_form.errors})

    else:
        discount_form = DiscountForm()
        errors = []
    context = {
        "errors": errors,
        "discount_form": discount_form,
        "promotion_active": "active",
        "discount_data": "Category"
    }
    return render(request, "discount_add.html", context)

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def image_field_style(request):
    link_1 = request.GET.get('image_link_1', '/media/icons/icon.jpg')
    link_2 = request.GET.get('image_link_2', '/media/standard_images/standard_image.jpg')
    link_3 = request.GET.get('image_link_3', '/media/banners/banner.jpg')

    image_field1 = render_to_string('image_field.html', {'class_name': 'upload', 'image_reset_button': 'image_reset_button1', 'field_name' : 'Icon'})
    image_field2 = render_to_string('image_field.html', {'class_name': 'upload2', 'image_reset_button': 'image_reset_button2', 'field_name' : 'StandardImage',"link":  link_2})
    image_field3 = render_to_string('image_field.html', {'class_name': 'upload3', 'image_reset_button': 'image_reset_button3', 'field_name' : 'BannerImage',"link":  link_3})
    return JsonResponse({'image_field1':image_field1, 'image_field2': image_field2, 'image_field3': image_field3, "link_1":  link_1, "link_2":  link_2,"link_3":  link_3 })



@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def ad_list(request):
    ad = Ads.objects.order_by("-created_at")
    paginator = Paginator(ad, 6)
    page = request.GET.get("page")
    try:
        ad_list_data = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        ad_list_data = paginator.get_page(1)
    except EmptyPage:
        ad_list_data = paginator.get_page(paginator.num_pages)
    context = {"ad_data": ad_list_data, "promotion_active": "active"}
    return render(request, "ad_list.html", context)

def ad_delete(request, ad_id):
    ad = Ads.objects.filter(pk=ad_id)
    if ad:
        ad.delete()
    return redirect("list_ad")

def ad_edit(request, ad_id):
    errors = []

    ad = Ads.objects.filter(pk=ad_id).first()
    if request.method == "POST":

        form = AdForm(request.POST, request.FILES, instance=ad)

        coupon = request.POST.get("Coupon", "")
        discount = request.POST.get("Discount", "")

        product = request.POST.get("Product", "")



        if form.is_valid():
            ad = form.save(commit=False)
            if ad.AdType == "Coupon":
                try:
                    coupon_instance = Coupons.objects.filter(pk = coupon).first()
                    ad.Coupon = coupon_instance
                except:
                    pass


            elif ad.AdType == "Discount":
                try:
                    discount_instance = Discount.objects.filter(pk = discount).first()
                    ad.Discount = discount_instance
                except:
                    pass

            elif ad.AdType == "Product":
                try:
                    product_instance = Products.objects.filter(pk = product).first()
                    ad.Product =product_instance
                except:
                    pass

            if request.POST.get('image2', ''):
                form.instance.StandardImage = None
            if request.POST.get('image3', ''):
                form.instance.BannerImage = None
            ad.save()
            return redirect('list_ad')

        else:
            errors.append(form.errors)
    else:
        form = AdForm(instance=ad)
    context = {
        "errors": errors,
        "ad_form": form,
        "promotion_active": "active",
        "ad_data": ad.AdType
    }
    return render(request,"ad_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def ad_add(request):
    errors = []
    if request.method == "POST":

        form = AdForm(request.POST, request.FILES)

        coupon = request.POST.get("Coupon", "")
        discount = request.POST.get("Discount", "")

        product = request.POST.get("Product", "")

        if form.is_valid():
            ad = form.save(commit=False)
            if ad.AdType == "Coupon":
                try:
                    coupon_instance = Coupons.objects.filter(pk = coupon).first()
                    ad.Coupon = coupon_instance
                except:
                    pass


            elif ad.AdType == "Discount":
                try:
                    discount_instance = Discount.objects.filter(pk = discount).first()
                    ad.Discount = discount_instance
                except:
                    pass

            elif ad.AdType == "Product":
                try:
                    product_instance = Products.objects.filter(pk = product).first()
                    ad.Product = product_instance
                except:
                    pass
            if request.POST.get('image2', ''):
                form.instance.StandardImage = None
            if request.POST.get('image3', ''):
                form.instance.BannerImage = None
            form.save()

            return redirect('list_ad')
        else:
            errors.append(form.errors)

            context = {
                "errors": errors,
                "ad_form": form,
                "promotion_active": "active",
                "ad_data": form.instance.AdType
            }
    else:
        form = AdForm()
        errors = []
        context = {
        "errors": errors,
        "ad_form": form,
        "promotion_active": "active",
        "ad_data" : "Discount"
        }
    return render(request, "ad_add.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def custom_product_add(request):
    errors = []


    if request.method == "POST":
        custom_product_form = CustomProductForm(request.POST, request.FILES)
        if custom_product_form.is_valid():
            custom_product = custom_product_form.save()

            # Handle image uploads
            images = request.FILES.getlist('images')
            for image in images:
                CustomProductImage.objects.create(custom_product=custom_product, image=image)

            # Handle video uploads
            videos = request.FILES.getlist('videos')
            for video in videos:
                CustomProductVideo.objects.create(custom_product=custom_product, video=video)

            try:
                log_user = request.user
                log_type = "product"
                message = "Custom Product Added"
                description = f"Custom Product {custom_product.item_name}  with code {custom_product.item_code} added "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass

            # After saving, redirect to the listing page
            return redirect('custom_product_listing')  # This line redirects to the product listing page

        else:
            errors.append(custom_product_form.errors)
    else:
        custom_product_form = CustomProductForm()

    context = {
        "errors": errors,
        "custom_product_form": custom_product_form
    }

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

# Custom Product Listing View
# @login_required
# @user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def custom_product_listing(request):
    # Fetch all the custom products (with pagination if needed)
    product_data = CustomProduct.objects.all()
    return render(request, 'custom_product_list.html', {'product_data': product_data})


# Delete Custom Product View
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delete_custom_product(request, product_id):
    product = get_object_or_404(CustomProduct, pk=product_id)
    product_data = product
    
    if request.method == 'POST':
        # Delete the product
        product.delete()
        try:
            log_user = request.user
            log_type = "product"
            message = "Custom Product deleted"
            description = f"Custom product {product_data.item_name}  with code {product_data.item_code} deleted "
            LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message,
                                            description=description)
        except Exception as e:
            print(e)
            pass
        return redirect('custom_product_listing')  # Redirect to the listing page after deletion
    
    return render(request, 'delete_confirmation.html', {'product': product})


# class Customorder_placing(APIView):
#     def generate_unique_order_id(self):
#         """Generate a unique order ID."""
#         while True:
#             order_id = f"ID{random.randint(100, 999)}{random.choice(string.ascii_uppercase)}{random.choice(string.ascii_uppercase)}"
#             # Ensure order ID is unique by checking if it already exists in the database
#             if not Orders.objects.filter(order_ID=order_id).exists():
#                 return order_id
            
#     def post(self, request, id):
#         try:
#             custom_product = get_object_or_404(CustomProduct, pk=id)
#             description = request.data.get("description")
#             message = request.data.get("message")
#             store_uuid = request.data.get("store_uuid")

#             if not description or not message or not store_uuid:
#                 return Response({"error": "All fields are required!"}, status=status.HTTP_400_BAD_REQUEST)

#             user = request.user
#             shop = get_object_or_404(Shop, uuid=store_uuid)
#             if not user.is_authenticated:
#                 return Response({"error": "User is not authenticated"}, status=status.HTTP_401_UNAUTHORIZED)

#             print(custom_product, user, description, message,shop)

#             # Create the order
#             new_order = Orders.objects.create(
#                 order_ID=self.generate_unique_order_id(),
#                 custom_product=custom_product,
#                 order_type="Custom Orders",
#                 user_uuid=user,
#                 store_uuid=shop,
#                 description=description,
#                 message=message,
#                 order_status="Enquiry",
#                 color_status="White"
#             )

#             return Response(
#                 {"message": "Custom order created successfully!", "order_id": new_order.order_ID},
#                 status=status.HTTP_201_CREATED
#             )

#         except Exception as e:
#             return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def custom_product_edit(request, product_id):
    errors = []
    custom_product = get_object_or_404(CustomProduct, pk=product_id)
    custom_product_form = CustomProductForm(request.POST or None, request.FILES or None, instance=custom_product)

    if request.method == "POST":
        if custom_product_form.is_valid():
            custom_product = custom_product_form.save()

            # Handle image uploads
            images = request.FILES.getlist('images')
            for image in images:
                CustomProductImage.objects.create(custom_product=custom_product, image=image)

            # Handle video uploads
            videos = request.FILES.getlist('videos')
            for video in videos:
                CustomProductVideo.objects.create(custom_product=custom_product, video=video)

            try:
                log_user = request.user
                log_type = "product"
                message = "Custom Product Updated"
                description = f"Product {custom_product.item_name}  with code {custom_product.item_code} updated "
                LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
            except:
                pass

            return redirect('custom_product_listing')  # Redirect to the listing page after saving

        else:
            errors.append(custom_product_form.errors)

    context = {
        "errors": errors,
        "custom_product_form": custom_product_form,
        "custom_product": custom_product
    }

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

@login_required
def delete_custom_image(request, product_id, image_id):
    image = get_object_or_404(CustomProductImage, id=image_id)
    custom_product_id = image.custom_product.id  # type: ignore
    image.delete()
    try:
        log_user = request.user
        log_type = "product"
        message = "Custom Product Image deleted"
        description = f"Custom product {image.custom_product.item_name}  with code {image.custom_product.item_code} deleted its image"
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
    except:
        pass
    return redirect('custom_product_edit', product_id=custom_product_id)


@login_required
def delete_custom_video(request, product_id, video_id):
    video = get_object_or_404(CustomProductVideo, id=video_id)
    custom_product_id = video.custom_product.id   # type: ignore
    video.delete()
    try:
        log_user = request.user
        log_type = "product"
        message = "Custom Product Video deleted"
        description = f"Custom product {video.custom_product.item_name}  with code {video.custom_product.item_code} deleted its video"
        LoggingOperation.objects.create(user=log_user, log_type=log_type, message=message, description=description)
    except Exception as e:
        print(e)
        pass
    return redirect('custom_product_edit', product_id=custom_product_id)

@login_required
def production_unit(request):
    production_unit = ProductionUnit.objects.order_by("-created_at")
    paginator = Paginator(production_unit, 10)
    page = request.GET.get("page")
    try:
        production_unit = paginator.get_page(page)
    except (PageNotAnInteger, TypeError):
        production_unit = paginator.get_page(1)
    except EmptyPage:
        production_unit = paginator.get_page(paginator.num_pages)
    context = {"production_unit_data": production_unit, "sales_unit_active": "active"}
    return render(request, "production_unit_list.html", context)



@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def production_unit_add(request):
    errors = []
    if request.method == "POST":
        production_unit_form = ProductionUnitForm(request.POST)
        if production_unit_form.is_valid():
            production_unit_form.save()
            return redirect("production_unit_list")
        else:
            errors.append(production_unit_form.errors)
            context = {
                "errors": errors,
                "production_unit_form": production_unit_form,
                "show_modal": "modal_hide",
                "sales_unit_active": "active"
            }
            return render(request, "production_unit_add.html", context)
    else:
        production_unit_form = ProductionUnitForm()
        errors = []
    context = {
        "errors": errors,
        "production_unit_form": production_unit_form,
        "sales_unit_active": "active"
    }
    return render(request, "production_unit_add.html", context)


@require_POST
@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def production_unit_delete(request, pu_id):
    pu = ProductionUnit.objects.filter(pk=pu_id)
    if pu:
        pu.delete()
    return redirect("production_unit_list")


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def production_unit_edit(request, pu_id=None):
    pu = get_object_or_404(ProductionUnit, pk=pu_id)
    errors = []
    if request.method == "POST":
        pu_form = ProductionUnitForm(request.POST, instance=pu)
        if pu_form.is_valid() :
            pu_form.save()
            return redirect("production_unit_list")
        else:
            errors.append(pu_form.errors)
    else:
        pu_form = ProductionUnitForm(instance=pu)
    context = {"pu_form": pu_form, "sales_unit_active": "active"}
    return render(request, "production_unit_edit.html", context)


@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def faq(request):
    faqs = FAQ.objects.all()
    return render(request, "faq.html",{'faqs': faqs})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def add_faq(request):
    if request.method == 'POST':
        form = FAQForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('faq')  
        else:
            messages.error(request, 'There was an error with your form submission.')
    else:
        form = FAQForm()
    
    return render(request, 'add_faq.html', {'form': form})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def edit_faq(request, faq_id):
    faq = get_object_or_404(FAQ, id=faq_id) 
    if request.method == 'POST':
        form = FAQForm(request.POST, instance=faq)
        if form.is_valid():
            form.save()
            return redirect('faq')  
        else:
            messages.error(request, 'There was an error with your form submission.')
    else:
        form = FAQForm(instance=faq)
    
    return render(request, 'edit_faq.html', {'form': form, 'faq': faq})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delete_faq(request, faq_id):
    faq = get_object_or_404(FAQ, id=faq_id) 
    faq.delete()  
    return redirect('faq') 

    #return render(request, 'delete_faq.html', {'faq': faq})

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def about_us(request):
    about_us = AboutUs.objects.first()  
    contact_us = ContactUs.objects.first()
    app_url = AppUrl.objects.first()
    privacy_policy = PrivacyPolicy.objects.first() 
    terms_and_conditions = TermsAndConditions.objects.first()  
    if request.method == 'POST':
        if 'edit_about_us' in request.POST:
            about_us_form = AboutUsForm(request.POST, request.FILES, instance=about_us)  # Include request.FILES for image upload
            if about_us_form.is_valid():
                about_us_form.save()
        elif 'edit_contact_us' in request.POST:
            contact_us_form = ContactUsForm(request.POST, instance=contact_us)
            if contact_us_form.is_valid():
                contact_us_form.save()
        elif 'edit_app_url' in request.POST:
            app_url_form = AppUrlForm(request.POST, instance=app_url)
            if app_url_form.is_valid():
                app_url_form.save()
        elif 'edit_privacy_policy' in request.POST:
            privacy_policy_form = PrivacyPolicyForm(request.POST, instance=privacy_policy)
            if privacy_policy_form.is_valid():
                privacy_policy_form.save()
        elif 'edit_terms_conditions' in request.POST:
            terms_conditions_form = TermsAndConditionsForm(request.POST, instance=terms_and_conditions)
            if terms_conditions_form.is_valid():
                terms_conditions_form.save()

        return redirect('about_us')  # After saving, redirect to the page again

    # Create forms with current data
    about_us_form = AboutUsForm(instance=about_us)
    contact_us_form = ContactUsForm(instance=contact_us)
    app_url_form = AppUrlForm(instance=app_url)
    privacy_policy_form = PrivacyPolicyForm(instance=privacy_policy)
    terms_conditions_form = TermsAndConditionsForm(instance=terms_and_conditions)

    return render(request, 'about_us.html', {
        'about_us': about_us,
        'contact_us': contact_us,
        'app_url': app_url,
        'privacy_policy': privacy_policy,
        'terms_and_conditions': terms_and_conditions,
        'about_us_form': about_us_form,
        'contact_us_form': contact_us_form,
        'app_url_form': app_url_form,
        'privacy_policy_form': privacy_policy_form,
        'terms_conditions_form': terms_conditions_form,
    })

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def privacy_policy_view(request):
    policy = PrivacyPolicy.objects.first()
    form = PrivacyPolicyForm(request.POST or None, instance=policy)

    if request.method == 'POST' and form.is_valid():
        form.save()
        return redirect('privacy_policy')

    return render(request, 'privacy_policy.html', {
        'form': form,
        'policy': policy,
    })

    
def terms_conditions_view(request):
    terms = TermsAndConditions.objects.first()
    form = TermsAndConditionsForm(request.POST or None, instance=terms)

    if request.method == 'POST' and form.is_valid():
        form.save()
        return redirect('terms_and_conditions')

    return render(request, 'terms_conditions.html', {
        'form': form,
        'terms': terms,
    })

@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def delivery_settings(request):
    return render(request, "delivery_settings.html")


#


@login_required
@user_passes_test(check_user_role(["Shop Admin", "PU Admin"]))
def custom_orders(request, order_id = None):
    try:
        shop_id_verify = Shop.objects.prefetch_related('unit_admin_user').filter(
            unit_admin_user__uuid=request.user.uuid)
        shop_id = shop_id_verify[0]
        errors = []
        field_name = request.COOKIES.get('field_name')
        sort_order = request.COOKIES.get('sort_order')
        search_query = request.GET.get('search', "")
        order_date = request.GET.get('product_date', "")
        order_status = request.GET.get('product_status', "")
        sort_order_data = request.GET.get('sort_order', "")
        if not sort_order_data:
            sort_order_data = sort_order
        field_name_data = request.GET.get('field_name', "")
        if not field_name_data:
            field_name_data = field_name
        order_list = Orders.objects.filter(store_uuid=shop_id, order_type= "Custom Orders").exclude(order_status = "New Order").order_by('-created_date')

        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            if search_query:
                order_list = order_list.filter(
                    Q(order_ID__icontains=search_query) |
                    Q(order_type__icontains=search_query) |
                    Q(order_status__icontains=search_query) |
                    Q(user_uuid__first_name__icontains=search_query)
                ).order_by('-created_date')
            if order_date:
                formatted_date = datetime.strptime(order_date, "%Y-%m-%d")
                order_list = order_list.filter(created_date__date=formatted_date)
            if order_status:
                order_list = order_list.filter(product_status=order_status)

            if sort_order_data and field_name_data:
                if sort_order_data == 'asc':
                    if field_name_data == 'user_uuid':
                        order_list = order_list.order_by(field_name_data + '__first_name')
                    else:
                        order_list = order_list.order_by(field_name_data)
                else:
                    if field_name_data == 'user_uuid':
                        order_list = order_list.order_by('-' + field_name_data + '__first_name')
                    else:
                        order_list = order_list.order_by('-' + field_name_data)

        paginator = Paginator(order_list, 6)

        page = request.GET.get('page')

        try:
            orders = paginator.get_page(page)
        except (PageNotAnInteger, TypeError):
            orders = paginator.get_page(1)
        except EmptyPage:
            orders = paginator.get_page(paginator.num_pages)

        base_url = reverse('custom_orders')
        query_params = request.GET.copy()
        if 'page' in query_params:
            del query_params['page']
        pagination_links = [
            {
                'page_number': page_number,
                'url': f"{base_url}?{query_params.urlencode(safe='/')}&page={page_number}",
            }
            for page_number in orders.paginator.page_range
        ]

        form = CustomOrderForm()
        ongoing_orders = DeliveryBoys.objects.filter(status='verified', shop = shop_id)
        context = {
            "order_form": form,
            "order_data": orders,
            'search_query': search_query,
            'date': order_date,
            'product_status': order_status,
            'pagination_links': pagination_links,
            "orders_active": "active",
            "ongoing_orders": ongoing_orders

        }
        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            tbody = render_to_string('custom_order_list_page.html',
                                     {"order_data": orders, 'pagination_links': pagination_links, "ongoing_orders": ongoing_orders})
            pagination = render_to_string('order_list_pagination.html', {"order_data": orders})
            return JsonResponse({'tbody': tbody, "pagination": pagination})


        response = render(request, "custom_orders.html", context)
        return response
    #
    except IndexError:
        context = {
            "order_data": [],
            "orders_active": "active"

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



@login_required
@user_passes_test(check_user_role(["Shop Admin"]))
def custom_order_edit(request):
    if request.method == "POST":
        orderID = request.POST.get("order_ID")  # Using .get() to avoid KeyError
        custom_orders = Orders.objects.filter(order_ID=orderID).first()

        if not custom_orders:
            return JsonResponse({'status': 'fail', 'message': 'Order not found'}, status=404)

        form = CustomOrderForm(request.POST, instance=custom_orders)

        if form.is_valid():
            grand_total = request.POST.get("grand_total", "0")  # Ensure value exists
            form.save()
            try:
                # razorpay_client = razorpay.Client(auth=(settings.RAZORPAY_KEY_ID, settings.RAZORPAY_KEY_SECRET))
                # razorpay_order = razorpay_client.payment_link.create({
                #     "upi_link": True,
                #     "amount": grand_total,
                #     "currency": "INR",
                #     "description": "For custom order payment purpose",
                #     "customer": {
                #         "name": f"{request.user.first_name} {request.user.last_name}",
                #         "email": request.user.email,
                #         "contact": request.user.phone_number
                #     },
                #     "notify": {"sms": True, "email": True},
                #     "reminder_enable": True,
                #     "notes": {"orderID": orderID}
                # })

                # Payment.objects.create(
                #     order=custom_orders,
                #     razorpay_order_id=razorpay_order["id"],
                #     payment_status="pending",  # payment status pending
                # )
                pass


            except Exception as e:
                form.add_error("order_ID", "Payment link creation failed!")
                return JsonResponse({'status': 'fail', 'errors': form.errors})

            # **Ensure Order Status is updated to "Bill Created"**
            custom_orders.order_status = "Bill Created"
            custom_orders.save()  # Save the updated status

            title = "Bill Created"
            description = f"Bill Created for your custom order {orderID}"
            try:
                initialize_fcm_app()
                send_notification(custom_orders.user_uuid.fcm_token, custom_orders, title, description, custom_orders.user_uuid)
            except Exception as e:
                print(e)

                pass

            return JsonResponse({
                'status': 'success',
                'order_id': custom_orders.uuid,
                'OrderID': custom_orders.order_ID
            })
        # return redirect('custom_orders')
        return JsonResponse({'status': 'fail', 'errors': form.errors})

    elif request.method == "GET":
        order_id = request.GET.get('order_id')
        custom_orders = Orders.objects.filter(uuid=order_id).first()

        if custom_orders:
            form = CustomOrderForm(instance=custom_orders)
        else:
            form = CustomOrderForm()

        form_data = render_to_string('order_status_update_form.html', {'order_form': form, "order_id": order_id, 'order_status': custom_orders.order_status})
        return JsonResponse({'success': True, 'form': form_data})

    return JsonResponse({'status': 'fail', 'message': 'Invalid request method'}, status=400)




@login_required
@user_passes_test(check_user_role(["Super Admin", "NBC Admin"]))
def system_settings(request):
    return render(request, "system_settings.html")






@csrf_exempt
async def custom_order_payment(request):
    if request.method == "POST":
        try:
            data = await request.json()
            body = request.body.decode('utf-8')
            received_signature = request.headers.get("X-Razorpay-Signature")

            # Compute HMAC SHA256 signature
            generated_signature = hmac.new(
                RAZORPAY_WEBHOOK_SECRET.encode(),
                body.encode(),
                hashlib.sha256
            ).hexdigest()

            # Compare signatures
            if hmac.compare_digest(generated_signature, received_signature):
                event_data = json.loads(body)  # Parse JSON data
                orderID = data["notes"].get("orderID", "")
                if orderID:
                    custom_orders = Orders.objects.filter(order_ID=orderID).first()
                    custom_orders.order_status = "Confirmed"
                    custom_orders.save()
                    Payment.objects.create(
                        order=custom_orders,
                        razorpay_order_id=data["order_id"],
                        payment_status="paid",  # payment status pending
                    )

                return JsonResponse({"status": "success"}, status=200)
            else:
                return JsonResponse(
                        {"status": 0, "message": "Payment verification failed"}, status=400
                    )
        except Exception as e:
            return JsonResponse({
                "status":0, "message" : "Something went wrong!", "error": str(e)
            }, status= 400)

    else:
        return JsonResponse({'status': 'fail', 'errors': "Method not allowed"}, status = 403)



def choice_list(request):

    choice = request.GET.get('choice')


    if choice == 'Discount':
        discount_choice = [{"id": i.id, "name": i.DiscountName} for i in Discount.objects.all()]
        try:
            if discount_choice:
                return JsonResponse({"tables": list(discount_choice), "type": choice},
                                    safe=False)
            else:
                return JsonResponse({"tables": [], "type": choice}, safe=False)

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

    if choice == "Coupon":
        coupon_choice = [{"id": i.id, "name":i.CouponName} for i in Coupons.objects.all()]
        try:
            if coupon_choice:
                return JsonResponse({"tables": list(coupon_choice), "type": choice},
                                    safe=False)
            else:
                return JsonResponse({"tables": [], "type": choice}, safe=False)

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


    if choice == 'Product':

        product_choice = [{"id": i.id, "name": i.item_name} for i in Products.objects.all()]
        try:
            if product_choice:
                return JsonResponse({"tables": list(product_choice), "type": choice},
                                    safe=False)
            else:
                return JsonResponse({"tables": [], "type": choice}, safe=False)

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



def my_polling_task(request):
    # Add your polling logic here, such as fetching data from an API
    today = date.today()
    orders = Orders.objects.filter(order_status__in=["Confirmed", "Viewed", "Order Packed"])
    status_excluded = ["Delivery Assigned", "Despatched", "Contacted", "Bill Created", "Delivered", "Failed"]
    for i in orders:
        try:
            if(i.delivery_slot_time and i.delivery_slot_time):
                combined_datetime = datetime.combine(i.delivery_slot_date, i.delivery_slot_time)
                time_dif_with_del_slot = combined_datetime.astimezone() - datetime.now().astimezone()
                duration_in_s_data = time_dif_with_del_slot.total_seconds()
                hours_del = duration_in_s_data/3600

            else:
                hours_del = 0


            if i.order_status == 'Confirmed' or i.order_status == 'Viewed':


                if hours_del < 2:
                    if i.order_status != 'Order Packed' and i.order_status not in status_excluded:
                        i.color_status = "Yellow"
                        i.color_status_updation_time = datetime.now()
                        i.save()

                if hours_del <= 0:
                    if i.order_status not in status_excluded:
                        i.color_status = "Red"
                        i.color_status_updation_time = datetime.now()
                        i.save()

                if hours_del < 1 and hours_del > 0:
                    if i.order_status not in status_excluded:
                        i.color_status = "Orange"
                        i.color_status_updation_time = datetime.now()
                        i.save()

            if i.order_status == 'Order Packed':

                if hours_del <= 0:
                    if i.order_status not in status_excluded:
                        i.color_status = "Red"
                        i.color_status_updation_time = datetime.now()
                        i.save()

                if hours_del < 1 and hours_del > 0:
                    if i.order_status not in status_excluded:
                        i.color_status = "Orange"
                        i.color_status_updation_time = datetime.now()
                        i.save()


            if i.order_status == 'Failed':
                i.color_status = "Dark Red"
                i.color_status_updation_time = datetime.now()
                i.save()
        except:
            pass

    return JsonResponse({"Status": True})



def list_communication(request):
    msg = Communication.objects.select_related("user", "message").prefetch_related("message__ads").order_by("-created_at")
    paginator = Paginator(msg, 6)
    page = request.GET.get("page")
    msg_list_data = paginator.get_page(page) 

    context = {"msg_data": msg_list_data, "promotion_active": "active"}
    return render(request, "communication_list.html", context)



def send_message(request):
    if request.method == 'POST':
        form = MessageForm(request.POST)
        if form.is_valid():
            msg_form = form.save()
            customers = Users.objects.filter(user_type="Customer")

            for customer in customers:
                if customer.email and customer.phone_number:
                    if msg_form.message_type == 'sms':
                        try:
                            smsmsg=Message.objects.filter(message_type='email').order_by("-created_at").first()
                            sms(f"Dear {customer.first_name},\nSurpricing offer for you from Navya🎉 \n{smsmsg.message}\n{smsmsg.ads.AdDescription}","+919961073407")
                            # send_sms(f"Navya Bakers Offer",customer.phone_number) #phone_number must contain+91
                            Communication.objects.create(user=customer, message=msg_form)
                        except Exception as e:
                            print("SMS Error:", e)
                    
                    elif msg_form.message_type == 'email':
                        try:
                            # send_email_communication(msg_form, customer.email)
                            emailmsg=Message.objects.filter(message_type='email').order_by("-created_at").first()
                            # print(emailmsg,emailmsg.message,emailmsg.ads.AdTitle,emailmsg.ads.AdDescription)
                            subject = emailmsg.ads.AdTitle
                            email_body  = f"Dear {customer.first_name},\nwe are providing\n{emailmsg.message}\n{emailmsg.ads.AdDescription}"
                            to_email = [customer.email]
                            media_root = settings.MEDIA_ROOT 
                            filepath = os.path.join(media_root,str(emailmsg.ads.BannerImage))

                            send_email_attachment(subject,email_body ,to_email,filepath)
                            Communication.objects.create(user=customer, message=msg_form)
                        except Exception as e:
                            print("Email Error:", e)
                    
                    else:
                        try:
                            # send_whatsapp_message(msg_form, customer.phone_number)
                            send_whatsapp_message(918111848903,msg_form.ads.AdTitle,customer.first_name, msg_form.ads.AdDescription)  #7994035508
                            Communication.objects.create(user=customer, message=msg_form)
                        except Exception as e:
                            print("WhatsApp Error:", e)
                
            return redirect('communication_list')
        else:
            print("Form Errors:", form.errors)

    else:
        form = MessageForm()
    return render(request, 'send_message.html', {'form': form})


# def send_email_communication(msg, to_email):
#     subject = msg.ads.AdTitle
#     message = f"{msg.message} {msg.ads.AdDescription}"
#     to_email = [to_email]  # Wrap in a list

#     send_mail(
#         subject=subject,
#         message=message,
#         from_email=settings.EMAIL_HOST_USER,
#         recipient_list=to_email,
#         fail_silently=False,
#     )
#     print("Email Sent Successfully!")

def send_email_attachment(subject,body, to_email,filepath):
    mail = EmailMessage(subject=subject, body=body, from_email=settings.EMAIL_HOST_USER, to=to_email)
    mail.attach_file(filepath)
    mail.send()


def send_whatsapp_message(number,message_name,name,data):
    url = f"https://graph.facebook.com/v17.0/{PHONE_NUMBER_ID}/messages"

    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "Content-Type": "application/json"
    }

    payload = {
        "messaging_product": "whatsapp",
        "to": str(number),
        "type": "template",
        "template": {
            "name": "navya_communication",
            "language": {"code": "en_US"},
            "components": [
                {
                    "type": "header",
                    "parameters": [{"type": "text", "text": message_name}]
                },
                {
                    "type": "body",
                    "parameters": [
                        {"type": "text", "text": name},
                        {"type": "text", "text": data}
                    ]
                }
            ]
        }
    }

    response = requests.post(url, headers=headers, data=json.dumps(payload))

    if response.status_code == 200:
        print("Message sent successfully!", response.text)
    else:
        print("Failed to send message:", response.status_code, response.text)

# Usage







def send_whatsapp_message_delivery_boy(number,name,data):
    url = f"https://graph.facebook.com/v17.0/{PHONE_NUMBER_ID}/messages"
    pickup_address = data.get("pick_up_address", "")
    drop_address = data.get("drop_address", "")
    google_place_link = data.get("google_place_link", "")

    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "Content-Type": "application/json"
    }

    payload = {
        "messaging_product": "whatsapp",
        "to": number,
        "type": "template",
        "template": {
            "name": "navya_delivery_temp01",
            "language": {
                "code": "en_US"
            },
            "components": [
                {
                    "type": "header",
                    "parameters": [
                        {
                            "type": "text",
                            "text": name
                        }
                    ]
                },
                {
                    "type": "body",
                    "parameters": [
                        {
                            "type": "text",
                            "text": pickup_address
                        },
                        {
                            "type": "text",
                            "text":drop_address
                        },
                        {
                            "type": "text",
                            "text": google_place_link
                        }
                    ]
                }
            ]
        }
    }

    response = requests.post(url, headers=headers, data=json.dumps(payload))

    if response.status_code == 200:
        print("Message sent successfully!", response.text)
    else:
        print("Failed to send message:", response.status_code, response.text)

@api_view(['POST'])
def coupon_subcategory_list(request):

    try:

        category_ids = request.data.get('category', None)
        sub_category_ids = request.data.get('sub_category', None)
        product_ids = request.data.get('product', None)
        sku_ids = request.data.get('sku', None)
        trigger =  request.data.get('trigger', None)
        if '' in category_ids:
            category_ids.remove('')
        if '' in sub_category_ids:
            sub_category_ids.remove('')
        if '' in product_ids:
            product_ids.remove('')
        if '' in sku_ids:
            sku_ids.remove('')

        if trigger == "category":
            categories = ProductCategory.objects.values('uuid', 'category_name')
            for i in categories:
                if str(i["uuid"]) in category_ids:
                    i["checked"] = "True"
                else:
                    i["checked"] = "False"
            subcategories = ProductSubCategory.objects.filter(category_id__in =category_ids).values('uuid', 'sub_category_name')

            for j in subcategories:
                if str(j["uuid"]) in sub_category_ids:
                    j["checked"] = "True"
                else:
                    j["checked"] = "False"
            products = Products.objects.filter(item_category__in = category_ids).values('id', 'item_name')

            for k in products:
                if str(k["id"]) in product_ids:
                    k["checked"] = "True"
                else:
                    k["checked"] = "False"


            sku = SKU.objects.filter(product__item_category__in = category_ids).values('id', 'sku_name')

            for l in sku:
                if str(l["id"]) in sku_ids:
                    l["checked"] = "True"
                else:
                    l["checked"] = "False"

            return JsonResponse({"categories": list(categories), "sub_categories": list(subcategories), "products": list(products), "sku": list(sku), "trigger": trigger}, safe=False)

        elif trigger == "sub_category":
            categories = ProductCategory.objects.values('uuid', 'category_name')
            for i in categories:
                if str(i["uuid"]) in category_ids:
                    i["checked"] = "True"
                else:
                    i["checked"] = "False"
            subcategories = ProductSubCategory.objects.filter(category_id__in=category_ids).values('uuid',
                                                                                                   'sub_category_name')

            for j in subcategories:
                if str(j["uuid"]) in sub_category_ids:
                    j["checked"] = "True"
                else:
                    j["checked"] = "False"
            products = Products.objects.filter(item_sub_category__in=sub_category_ids).values('id', 'item_name')

            for k in products:
                if str(k["id"]) in product_ids:
                    k["checked"] = "True"
                else:
                    k["checked"] = "False"

            sku = SKU.objects.filter(product__item_sub_category__in=sub_category_ids).values('id', 'sku_name')

            for l in sku:
                if str(l["id"]) in sku_ids:
                    l["checked"] = "True"
                else:
                    l["checked"] = "False"

            return JsonResponse(
                {"categories": list(categories), "sub_categories": list(subcategories), "products": list(products),
                 "sku": list(sku), "trigger": trigger}, safe=False)

        elif trigger ==  "product":
            categories = ProductCategory.objects.values('uuid', 'category_name')
            for i in categories:
                if str(i["uuid"]) in category_ids:
                    i["checked"] = "True"
                else:
                    i["checked"] = "False"
            subcategories = ProductSubCategory.objects.filter(category_id__in=category_ids).values('uuid',
                                                                                                   'sub_category_name')

            for j in subcategories:
                if str(j["uuid"]) in sub_category_ids:
                    j["checked"] = "True"
                else:
                    j["checked"] = "False"
            products = Products.objects.filter(item_sub_category__in=sub_category_ids).values('id', 'item_name')
            for k in products:
                if str(k["id"]) in product_ids:
                    k["checked"] = "True"
                else:
                    k["checked"] = "False"

            sku = SKU.objects.filter(product_id__in=product_ids).values('id', 'sku_name')

            for l in sku:
                if str(l["id"]) in sku_ids:
                    l["checked"] = "True"
                else:
                    l["checked"] = "False"

            return JsonResponse(
                {"categories": list(categories), "sub_categories": list(subcategories), "products": list(products),
                 "sku": list(sku), "trigger": trigger}, safe=False)


    except Exception as e:
        return JsonResponse({"status": False, "error": str(e)}, safe = False)
