# myapp/tasks.py
import traceback
from celery import shared_task
from django.core.mail import send_mail
import logging
from shops.models import Shop
from products.models import Products, SKU, SalesUnitProductSelection, ProductCategory, ProductSubCategory
from orders.models import NotificationStat, Orders, Payment
from firebase_admin import messaging
from firebase_admin import credentials
from accounts.models import Users
import firebase_admin
import requests
from django.conf import settings
import json
from django.utils import timezone
from datetime import timedelta
@shared_task
def shop_add_celery_status_check(shop_id):
    logging.info("Celery job started")
    try:
        shop = Shop.objects.filter(uuid = shop_id).first()
        for sku_product in Products.objects.filter():
            sku_sub_category = sku_product.item_sub_category
            sku_category = sku_product.item_category
            # 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


            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 l in sku_data:
                    sku_sales = SalesUnitProductSelection.objects.filter(sku=l, 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 m in sku_sub_category_data:
                    sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=m,
                                                                                      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 n in sku_category_data:
                    sku_category_sales = SalesUnitProductSelection.objects.filter(sku=n, 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)


    except Exception as e:
        logging.error(f"Celery Shop Creation : {e}")
    logging.info("Celery Shop Delete Status Change Completed")


# @shared_task
# def send_whatsapp_message(number, message_name, name, msg,orderID):
#     logging.info("Whatsapp sending via celery")
#     try:
#         number = '+919656399354'
#         url = f"https://graph.facebook.com/v17.0/{settings.whatsapp_PHONE_NUMBER_ID}/messages"

#         headers = {
#             "Authorization": f"Bearer {settings.whatsapp_ACCESS_TOKEN}",
#             "Content-Type": "application/json"
#         }

#         payload = {
#             "messaging_product": "whatsapp",
#             "to": 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": orderID},
#                             {"type": "text", "text": name},
#                             {"type": "text", "text": msg}
#                         ]
#                     }
#                 ]
#             }
#         }

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

#         if response.status_code == 200:
#             logging.info(f"Message sent successfully!, {response.text}")

#         else:
#             logging.error(f"Failed to send message:, {response.status_code}, {response.text}")
#     except Exception as e:
#         logging.error(f"Whatsapp Message Sending Error: {e}")

@shared_task
def send_whatsapp_message(number, orderID, name, template_name):
    
    logging.info(f"🔔 WhatsApp Task Triggered | Number: {number}")

    url = f"https://graph.facebook.com/v21.0/{settings.WHATSAPP_PHONE_NUMBER_ID}/messages"

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


    # WhatsApp does NOT accept "+" sign
    number = number.replace("+", "")


    payload = {
        "messaging_product": "whatsapp",
        "to": number,
        "type": "template",
        "template": {
            "name": template_name,
            "language": {"code": "en"},
            "components": [
                {
                    "type": "body",
                    "parameters": [
                        {"type": "text", "text": name},
                        {"type": "text", "text": orderID},
                    ]
                }
            ]
        }
    }

    # 🔥 Send POST request
    response = requests.post(url, headers=headers, json=payload)

    print("STATUS:", response.status_code)
    print("RESPONSE:", response.text)


@shared_task
def send_otp_whatsapp_message(number, otp):
    url = f"https://graph.facebook.com/v21.0/{settings.WHATSAPP_PHONE_NUMBER_ID}/messages"

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

    number = number.replace("+", "")

    payload = {
        "messaging_product": "whatsapp",
        "to": number,
        "type": "template",
        "template": {
            "name": "otp_verification",
            "language": {
                "code": "en"
            },
            "components": [
                # BODY
                {
                    "type": "body",
                    "parameters": [
                        {
                            "type": "text",
                            "text": otp   # {{1}} in body
                        }
                    ]
                },
                # BUTTON (URL)
                {
                    "type": "button",
                    "sub_type": "url",
                    "index": "0",
                    "parameters": [
                        {
                            "type": "text",
                            "text": otp   # {{1}} in button URL
                        }
                    ]
                }
            ]
        }
    }

    response = requests.post(url, headers=headers, json=payload)
    logging.info(f"OTP WhatsApp Status: {response.status_code}, Response: {response.text}")




# delivery  boy whatsapp message sending
@shared_task
def send_whatsapp_message_delivery_boy(number, name, data):
    logging.info("Whatsapp sending via celery")
    try:
        url = f"https://graph.facebook.com/v17.0/{settings.whatsapp_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", "")
        order_id = data.get("orderID", "")

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

        payload = {
            "messaging_product": "whatsapp",
            "recipient_type": "individual",
            "to": number,
            "type": "template",
            "template": {
                "name": "navya_update_1",
                "language": {
                    "code": "en_US"
                },
                "components": [

                    {
                        "type": "body",
                        "parameters": [
                            {
                                "type": "text",
                                "text": order_id
                            },
                            {
                                "type": "text",
                                "text": pickup_address
                            },
                            {
                                "type": "text",
                                "text": drop_address
                            }
                        ]
                    },
                     {
                        "type": "button",
                        "sub_type": "url",
                        "index": "0",
                        "parameters": [
                            {
                                "type": "text",
                                "text": google_place_link
                            }
                        ]
                    }

                ]
            }
        }

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

        if response.status_code == 200:
            logging.info(f"Message sent successfully!, {response.text}")
        else:
            logging.error(f"Failed to send message:, {response.status_code}, {response.text}")
    except Exception as e:
        logging.error(f"Whatsapp Message Sending Error: {e}")


# email sending
@shared_task
def email_sending(subject, message, from_email, recipient_list, fail_silently):
    logging.info(f"Email sending via celery")
    print(f"Email sending via celery to {recipient_list}")
    try:
        send_mail(subject=subject,
                  message=message,
                  from_email=from_email,
                  recipient_list=recipient_list,
                  fail_silently=fail_silently, )
    except Exception as e:
        logging.info(f"Delivery boy assigning Email Sending Failed: {e}")


def notification_stat_post(Order, Notification_title, sendTo,description ):

    try:

        user = Users.objects.filter(uuid = sendTo).first()
        orders = Orders.objects.filter(uuid = Order).first()
        notification_data = NotificationStat.objects.create(Sendmsg=Notification_title, OrderID=orders,
                                                            sendTo=user, Description= description)
        notification_data.save()
    except Exception as e:
        logging.info(f"Notification History Creation Failed: {e}")


        pass
# notification sending
@shared_task
def send_notification(fcmToken, OrderID, title, description, sendTo, OrderUUID):
    logging.info("notification sending via celery")
    notification_stat_post(OrderUUID, title, sendTo, description)
    
    try:
        if not firebase_admin._apps:
            cred = credentials.Certificate(
                r"/var/www/html/Testing_prj/Navya-Bakers/constants/navyabakers-1d955-firebase-adminsdk-fbsvc-d2f9578075.json")
            firebase_admin.initialize_app(cred)

        # Create the message with notification field (this is important)
        message = messaging.Message(
            notification=messaging.Notification(
                title=title,
                body=description,
            ),
            data={
                "title": title, 
                "description": description, 
                "orderID": OrderID,
                "type": "Order Update"
            },
            android=messaging.AndroidConfig(
                priority='high'
            ),
            apns=messaging.APNSConfig(
                headers={"apns-priority": "10"},  # Changed from "5" to "10"
                payload=messaging.APNSPayload(
                    aps=messaging.Aps(
                        badge=99, 
                        alert=messaging.ApsAlert(title=title, body=description),
                        sound="default"
                    )
                )
            ),
            token=fcmToken
        )

        # Send the message
        response = messaging.send(message)
        logging.info(f"✅ Notification sent successfully: {response}")
        
    except messaging.UnregisteredError as e:
        logging.error(f"FCM token is no longer valid: {e}")
        # You might want to remove the invalid token from your database here
        
    except messaging.SenderIdMismatchError as e:
        logging.error(f"Sender ID mismatch: {e}")
        
    except messaging.ThirdPartyAuthError as e:
        logging.error(f"Third party authentication error: {e}")
        
    except messaging.QuotaExceededError as e:
        logging.error(f"Quota exceeded: {e}")
        
    except messaging.InvalidArgumentError as e:
        logging.error(f"Invalid arguments: {e}")
        
    except Exception as e:
        logging.error(f"Error sending notification: {e}")

def initialize_fcm_app():
    if not firebase_admin._apps:
        # cred = credentials.Certificate(
        #     r"C:\NavyaProject\Navya-Bakers\constants\navyabakers-1d955-firebase-adminsdk-fbsvc-d2f9578075.json")
        cred = credentials.Certificate(r"/var/www/html/Testing_prj/Navya-Bakers/constants/navyabakers-1d955-firebase-adminsdk-fbsvc-d2f9578075.json")
        firebase_admin.initialize_app(cred)


@shared_task
def sms(body, to_phone):
    from twilio.rest import Client

    account_sid =settings.TWILIO_ACCOUNT_SID
    auth_token = settings.TWILIO_AUTH_TOKEN
    fromph = settings.TWILIO_PHONE_NUMBER
    to_phone = str(to_phone)
    # Here we'll build a new Twilio_client with different credentials
    twilio_client = Client(account_sid, auth_token)

    try:
        message = twilio_client.messages.create(
            to=to_phone,
            from_=fromph,
            body=body)
        logging.info(f"Twilio SMS send to {to_phone}")
        print(f"Twilio SMS{message.sid} send to {to_phone}")
    except Exception as e:
        logging.info(f"Twilio SMS Error: {e}")


@shared_task
def shop_admin_status_update(sku_id):
    logging.info("shop availability update task started")
    try:
        sku= SKU.objects.filter(id = sku_id).first()
        # 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")

        # 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)
    except Exception as e:
        logging.info(f"Shop Admin Status Update from Celery error: {e}")
    logging.info("shop availability status update task ended")


@shared_task
def shop_admin_status_update_only_one_shop(sku_id, sales_unit_id ):
    logging.info("shop admin status update for shop from celery started")
    try:
        sku = SKU.objects.filter(id = sku_id).first()
        sales_unit = Shop.objects.filter(uuid=sales_unit_id).first()
        sku_product = SKU.objects.filter(product=sku.product, sku_status="Visible")

        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")

        if not sku_product:
            sku.product.sales_unit.remove(sales_unit)  # removing product from sku
        else:
            product_remove_flag = True
            # print(f"Iterating on Product skus : {sku_data}")
            for z in sku_product:
                sku_sales = SalesUnitProductSelection.objects.filter(sku=z,
                                                                     sales_unit=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")
                sku.product.sales_unit.remove(sales_unit)

        if not sku_category_data:
            sku.product.item_category.sales_unit.remove(sales_unit)  # removing product from sku
        else:
            product_category_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=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_category_remove_flag = False
                        break
            if product_category_remove_flag:
                # print("No visible status available removed")
                sku.product.item_category.sales_unit.remove(sales_unit)

        if not sku_sub_category_data:
            sku.product.item_sub_category.sales_unit.remove(sales_unit)  # removing product from sku
        else:
            product_sub_category_remove_flag = True
            # print(f"Iterating on Product skus : {sku_data}")
            for y in sku_sub_category_data:
                sku_sales = SalesUnitProductSelection.objects.filter(sku=y,
                                                                     sales_unit=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_sub_category_remove_flag = False
                        break
            if product_sub_category_remove_flag:
                # print("No visible status available removed")
                sku.product.item_sub_category.sales_unit.remove(sales_unit)
    except Exception as e:
        logging.info(f"sku shop admin status update error from celery : {e}")
    logging.info("shop admin status update for shop from celery ended")









@shared_task
def category_based_shop_admin_status_celery(shop_id,category_id = None):
    logging.info("category based shop admin status started")
    try:
        shop = Shop.objects.filter(uuid = shop_id).first()
        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 m in sku_category_data:
                        sku_category_sales = SalesUnitProductSelection.objects.filter(sku=m, 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)
    except Exception as e:
        logging.info(f"category based shop admin status started: {e}")
    logging.info(f"category based shop admin status ended")


def category_exist(category_id, shop):
    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 r in sku_sub_category_data:
                sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=r,
                                                                                  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)







def category_not_exist(shop):
    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 s in sku_sub_category_data:
                sku_sub_category_sales = SalesUnitProductSelection.objects.filter(sku=s,
                                                                                  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)















@shared_task
def sub_category_based_shop_admin_status_celery(shop_id, sub_category_id, category_id):
    shop = Shop.objects.filter(uuid = shop_id).first()
    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:
            category_exist(category_id, shop)
        else:
            category_not_exist(shop)






@shared_task
def category_product_list(shop_id,category_id, sub_category_id):
    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)
    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")
                        product_remove_flag = False
                        break
            if product_remove_flag:
                product.sales_unit.remove(shop)
            else:
                product.sales_unit.add(shop)

















@shared_task
def category_based_shop_admin_status_celery(shop_id,category_id = None):
    logging.info("category based shop admin status started")
    try:
        shop = Shop.objects.filter(uuid = shop_id).first()
        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 m in sku_category_data:
                        sku_category_sales = SalesUnitProductSelection.objects.filter(sku=m, 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)
    except Exception as e:
        logging.info(f"category based shop admin status started: {e}")
    logging.info(f"category based shop admin status ended")

@shared_task
def product_availability_shop_status_change_celery(existing_sub_category, existing_category, to_sub_category, to_category):

    logging.info("master product edit category based shop shop admin status change started")
    try:

        existing_category = ProductCategory.objects.filter(uuid = existing_category).first()
        existing_sub_category = ProductSubCategory.objects.filter(uuid = existing_sub_category).first()
        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)
    except Exception as e:
        logging.info("master product edit celery task failed: {e}")
    logging.info("master product edit celery task completed")



@shared_task
def master_product_edit_celery_task_to_update_shop_availability(product_sub_category, product_category,):
    logging.info("master product delete celery task started")
    try:
        product_sub_category = ProductSubCategory.objects.filter(uuid = product_sub_category).first()
        product_category = ProductCategory.objects.filter(uuid= product_category).first()


        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)
    except Exception as e:
        logging.info("master product delete celery task error : {e}")
    logging.info("master product delete celery task completed")


@shared_task
def update_sku_long_distance_status_check_celery(sku_id):
    logging.info("update sku status long distance started")
    sku_data = SKU.objects.filter(id = sku_id).first()
    try:
        if sku_data.sku_status == "Visible":

            sales_unit_data = SalesUnitProductSelection.objects.filter(sku=sku_data, status="Visible").first()

            if sales_unit_data:

                if sku_data.sku_expiry_duration > 30:
                    sku_data.long_distance_availability = True

                else:
                    sku_data.long_distance_availability = False

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

        if sku_data.long_distance_availability:
            Products.objects.filter(id=sku_data.product.id).update(long_distance_availability=True)
            ProductCategory.objects.filter(uuid=sku_data.product.item_category.uuid).update(
                long_distance_availability=True)
            ProductSubCategory.objects.filter(uuid=sku_data.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_data.product, sku_status="Visible",
                                                       sku_expiry_duration__gt=30)
            if not long_dist_sku_product:
                Products.objects.filter(id=sku_data.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, status="Visible").first()
                    if long_dist_sales_check:
                        Products.objects.filter(id=sku_data.product.id).update(long_distance_availability=True)
                        long_dist_product_flag = True
                        break
                if not long_dist_product_flag:
                    Products.objects.filter(id=sku_data.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_data.product.item_sub_category, sku_status="Visible",
                sku_expiry_duration__gt=30)
            if not long_dist_sku_sub_category:
                ProductSubCategory.objects.filter(uuid=sku_data.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, status="Visible").first()
                    if long_dist_sales_check_sub:
                        ProductSubCategory.objects.filter(uuid=sku_data.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_data.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_data.product.item_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
            if not long_dist_sku_category:
                ProductCategory.objects.filter(uuid=sku_data.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, status="Visible").first()
                    if long_dist_sales_check_cat:
                        ProductCategory.objects.filter(uuid=sku_data.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_data.product.item_category.uuid).update(
                        long_distance_availability=False)

    except Exception as e:
        logging.info(f"long distance sku edit status check failed : {e}")
    logging.info(f"long distance sku edit completed")


@shared_task
def long_distance_status_check_celery(sku_product_id, sku_sub_category_id,sku_category_id ):
    logging.info("update sku status long distance started")
    try:
        sku_product = Products.objects.filter(id=sku_product_id).first()
        sku_sub_category = ProductSubCategory.objects.filter(uuid=sku_sub_category_id).first()
        sku_category = ProductCategory.objects.filter(uuid=sku_category_id).first()

        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, status="Visible").first()
                if long_dist_sales_check:
                    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_sub_category,
                                                        sku_status="Visible", sku_expiry_duration__gt=30)
        if not long_dist_sku_sub_category:
            ProductSubCategory.objects.filter(uuid=sku_sub_category.uuid).update(
                long_distance_availability=False)
        else:

            long_dist_sub_category_flag = False
            for j in long_dist_sku_sub_category:
                long_dist_sales_check_sub = SalesUnitProductSelection.objects.filter(sku=j, status="Visible").first()
                if long_dist_sales_check_sub:
                    ProductSubCategory.objects.filter(uuid=sku_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_sub_category.uuid).update(
                    long_distance_availability=False)

        # category exists looking for availablility
        long_dist_sku_category = SKU.objects.filter(product__item_category=sku_category,
                                                    sku_status="Visible", sku_expiry_duration__gt=30)
        if not long_dist_sku_category:
            ProductCategory.objects.filter(uuid=sku_category.uuid).update(
                long_distance_availability=False)
        else:
            long_dist_sku_category_flag = False
            for k in long_dist_sku_category:
                long_dist_sales_check_cat = SalesUnitProductSelection.objects.filter(sku=k, status="Visible").first()
                if long_dist_sales_check_cat:
                    ProductCategory.objects.filter(uuid=sku_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_category.uuid).update(
                    long_distance_availability=False)
        logging.info("delete long distance error ended")
    except Exception as e:
        logging.info(f"delete sku status long distance Error: {e}")


@shared_task
def long_distance_master_product_edit(existing_category, existing_sub_category, product_id):
    logging.info("product category sub category change on product edit  long distance status update started")
    # sub category exists looking for availablility
    long_dist_sku_sub_category = SKU.objects.filter(product__item_sub_category__uuid=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).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).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).update(
                long_distance_availability=False)

    # category exists looking for availablility
    long_dist_sku_category = SKU.objects.filter(product__item_category__uuid=existing_category,
                                                sku_status="Visible", sku_expiry_duration__gt=30)
    if not long_dist_sku_category:
        ProductCategory.objects.filter(uuid=existing_category).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, status="Visible").first()
            if long_dist_sales_check_cat:
                ProductCategory.objects.filter(uuid=existing_category).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).update(
                long_distance_availability=False)


    product = Products.objects.filter(id = product_id).first()
    # 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, status="Visible").first()
            if long_dist_sales_check:
                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, status="Visible").first()
            if long_dist_sales_check_sub:
                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, status="Visible").first()
            if long_dist_sales_check_cat:
                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)
    logging.info("product category sub category change on product edit  long distance status update ended")




@shared_task
def sku_delete_long_distance_celery(sku_product_id, sku_sub_category_id, sku_category_id):
    logging.info("sku delete long distance status update started")

    try:
        sku_product = Products.objects.filter(id=sku_product_id).first()
        sku_sub_category = ProductSubCategory.objects.filter(uuid=sku_sub_category_id).first()
        sku_category = ProductCategory.objects.filter(uuid=sku_category_id).first()
        # 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")

        # 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)
    except Exception as e:
        logging.info(f"SKU delete Long  Distance Error: {e}")
    logging.info("sku delete long distance status update ended")

    
@shared_task(bind=True, max_retries=3, default_retry_delay=10)
def send_whatsapp_message_delivery_partner(
    self,  # Keep this for bind=True
    phone_number: str,
    delivery_partner_name: str,
    order_id: str,
    pickup_location: str,
    customer_name: str,
    customer_phone: str,
    delivery_address: str,
    google_maps_link: str,
    order_amount: str,
    payment_mode: str,
    delivery_slot: str,
    pickup_time: str,
    confirm_link: str
):
    """Send WhatsApp message to delivery partner"""
    logging.info(f"🚀 TASK STARTED: send_whatsapp_message_delivery_partner for order {order_id}")
    
    try:
        url = f"https://graph.facebook.com/v21.0/{settings.WHATSAPP_PHONE_NUMBER_ID}/messages"
        headers = {
            "Authorization": f"Bearer {settings.WHATSAPP_ACCESS_TOKEN}",
            "Content-Type": "application/json",
        }
        
        phone_number = phone_number.replace("+", "")
        logging.info(f"📱 Sending to: {phone_number}")
        
        payload = {
            "messaging_product": "whatsapp",
            "to": phone_number,
            "type": "template",
            "template": {
                "name": "delivery_boy_assign",
                "language": {"code": "en"},
                "components": [
                    {
                        "type": "body",
                        "parameters": [
                            {"type": "text", "text": delivery_partner_name},
                            {"type": "text", "text": order_id},
                            {"type": "text", "text": pickup_location},
                            {"type": "text", "text": customer_name},
                            {"type": "text", "text": customer_phone},
                            {"type": "text", "text": delivery_address},
                            {"type": "text", "text": google_maps_link},
                            {"type": "text", "text": order_amount},
                            {"type": "text", "text": payment_mode},
                            {"type": "text", "text": delivery_slot},
                            {"type": "text", "text": pickup_time},
                            {"type": "text", "text": confirm_link},
                        ]
                    }
                ]
            }
        }
        
        response = requests.post(url, headers=headers, json=payload)
        logging.info(f"WhatsApp Status: {response.status_code}")
        logging.info(f"WhatsApp Response: {response.text}")
        
        if response.status_code != 200:
            logging.error(f"❌ WhatsApp API error: {response.text}")
            raise Exception(f"WhatsApp API returned {response.status_code}")
        
        logging.info(f"✅ TASK COMPLETED: WhatsApp message sent for order {order_id}")
        return {"success": True, "order_id": order_id}
        
    except Exception as exc:
        logging.error(f"❌ WhatsApp task failed: {exc}\n{traceback.format_exc()}")
        raise self.retry(exc=exc)


@shared_task(bind=True, max_retries=3, default_retry_delay=10)
def send_delivery_assign_email(
    self,  # Keep this for bind=True
    delivery_partner_name,
    order_id,
    pickup_location,
    delivery_address,
    delivery_location,
    customer_name,
    customer_phone,
    order_amount,
    payment_mode,
    delivery_slot,
    pickup_time,
    recipient_email,
    deliverylink
):
    """Send email to delivery partner"""
    logging.info(f"🚀 TASK STARTED: send_delivery_assign_email for order {order_id}")
    
    try:
        logging.info(f"📧 Sending to: {recipient_email}")
        
        message = f"""
Hello {delivery_partner_name},

You have been assigned a new order delivery.

Order Details
-------------
Order ID        : {order_id}
Pickup Location : {pickup_location}

Customer Details
----------------
Customer Name   : {customer_name}
Customer Phone  : {customer_phone}

Delivery Address
----------------
{delivery_address}

Delivery Location
-----------------
{delivery_location}

Payment Details
---------------
Order Amount    : ₹{order_amount}
Payment Mode    : {payment_mode}

Delivery Slot   : {delivery_slot}

Delivery Confirmation Link
--------------------------  
Please confirm delivery by clicking the link below once the order is delivered:
{deliverylink}

Pickup Instruction
------------------
Please reach the pickup location by {pickup_time},
collect the payment, and update the delivery status after completion.

Thank you,
Navya Bakeshop
"""
        
        send_mail(
            subject=f"New Delivery Assigned | Order ID {order_id}",
            message=message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            recipient_list=[recipient_email],
            fail_silently=False,
        )
        
        logging.info(f"✅ TASK COMPLETED: Email sent for order {order_id}")
        return {"success": True, "order_id": order_id}
        
    except Exception as exc:
        logging.error(f"❌ Email task failed: {exc}\n{traceback.format_exc()}")
        raise self.retry(exc=exc)
    


@shared_task(bind=True, max_retries=3, default_retry_delay=10)
def check_and_verify_order_status(self, order_id):
    try:
        logging.info(f"[CELERY] Checking order {order_id}")

        order = Orders.objects.get(order_ID=order_id)
        payment = Payment.objects.filter(order=order).first()

        # If already updated → exit
        if order.order_status != "New Order" and order.order_status != "Bill Created":
            logging.info(f"[CELERY] Order {order_id} already updated → {order.order_status}")
            return

        logging.info(f"[CELERY] Order {order_id} still New Order → checking Payu")

        response = requests.post(
            f"{settings.DOMAIN}orders/double/verifiy/",
            json={"order_id": order_id},
            timeout=10,
        )

        logging.info(
            f"[CELERY] Payu verify response {response.status_code}: {response.text}"
        )

        if response.status_code != 200:
            order.order_status = "Failed"
            payment.payment_status = "Failed"
            order.save(update_fields=["order_status"])
            payment.save(update_fields=["payment_status"])
            logging.warning(f"[CELERY] Order {order_id} marked FAILED")


    except Orders.DoesNotExist:
        logging.error(f"[CELERY] Order {order_id} does not exist")

    except requests.RequestException as exc:
        logging.error(f"[CELERY] Network error: {exc}")
        raise self.retry(exc=exc)

    except Exception as exc:
        logging.exception(f"[CELERY] Unexpected error")
        raise self.retry(exc=exc)


@shared_task(bind=True, max_retries=3, default_retry_delay=10)
def send_whatsapp_order_message(
    self,
    phone_number,
    shop_owner_name,
    order_id,
    customer_name,
    customer_phone,
    address,
    total_amount,
    payment_method,
    delivery_mode,
    delivery_time,
):
    """
    Send WhatsApp order confirmation message to Shop Owner
    """

    logging.info(
        f"🚀 TASK STARTED: send_whatsapp_order_message for order {order_id}"
    )

    try:
        # WhatsApp API URL
        url = (
            f"https://graph.facebook.com/v21.0/"
            f"{settings.WHATSAPP_PHONE_NUMBER_ID}/messages"
        )

        # Request headers
        headers = {
            "Authorization": f"Bearer {settings.WHATSAPP_ACCESS_TOKEN}",
            "Content-Type": "application/json",
        }

        # Clean phone number
        phone_number = str(phone_number).replace("+", "").replace(" ", "").strip()

        logging.info(f"📱 Sending WhatsApp message to: {phone_number}")

        # Convert all values to string safely
        shop_owner_name = str(shop_owner_name or "")
        order_id = str(order_id or "")
        customer_name = str(customer_name or "")
        customer_phone = str(customer_phone or "")
        address = str(address or "")
        total_amount = str(total_amount or "")
        payment_method = str(payment_method or "")
        delivery_mode = str(delivery_mode or "")
        delivery_time = str(delivery_time or "")

        # WhatsApp payload
        payload = {
            "messaging_product": "whatsapp",
            "to": phone_number,
            "type": "template",
            "template": {
                "name": "orde_confrimed_shopadmin",
                "language": {
                    "code": "en"
                },
                "components": [
                    {
                        "type": "body",
                        "parameters": [
                            {"type": "text", "text": shop_owner_name},
                            {"type": "text", "text": order_id},
                            {"type": "text", "text": customer_name},
                            {"type": "text", "text": customer_phone},
                            {"type": "text", "text": address},
                            {"type": "text", "text": total_amount},
                            {"type": "text", "text": payment_method},
                            {"type": "text", "text": delivery_mode},
                            {"type": "text", "text": delivery_time},
                        ],
                    }
                ],
            },
        }

        logging.info(f"📦 Payload: {payload}")

        # Send request
        response = requests.post(
            url,
            headers=headers,
            json=payload,
            timeout=30,
        )

        logging.info(f"📨 WhatsApp Status Code: {response.status_code}")
        logging.info(f"📨 WhatsApp Response: {response.text}")

        # Success check
        if response.status_code not in [200, 201]:
            logging.error(
                f"❌ WhatsApp API Error | Status: {response.status_code} | "
                f"Response: {response.text}"
            )

            raise Exception(
                f"WhatsApp API returned {response.status_code}: {response.text}"
            )

        logging.info(
            f"✅ TASK COMPLETED: WhatsApp message sent successfully "
            f"for order {order_id}"
        )

        return {
            "success": True,
            "order_id": order_id,
            "response": response.json(),
        }

    except requests.exceptions.Timeout as exc:
        logging.error(f"⏰ WhatsApp API Timeout: {exc}")
        raise self.retry(exc=exc)

    except requests.exceptions.ConnectionError as exc:
        logging.error(f"🌐 WhatsApp API Connection Error: {exc}")
        raise self.retry(exc=exc)

    except Exception as exc:
        logging.error(
            f"❌ WhatsApp task failed for order {order_id}: {exc}\n"
            f"{traceback.format_exc()}"
        )

        raise self.retry(exc=exc)