# myapp/tasks.py
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
from firebase_admin import messaging
from firebase_admin import credentials
from accounts.models import Users
import firebase_admin
import requests
from NavyaBackers import settings
import json


@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):
    logging.info("Whatsapp sending via celery")
    try:
        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": 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": 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}")







# 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")
    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("notifcation sending via celery")
    notification_stat_post(OrderUUID, title, sendTo, description)
    if not firebase_admin._apps:
        cred = credentials.Certificate(
            r"/var/www/html/Testing_prj/Navya-Bakers/constants/navyabakers-1d955-firebase-adminsdk-fbsvc-d2f9578075.json")

        # cred = credentials.Certificate(
        #     r"C:\NavyaProject\Navya-Bakers\constants\navyabakers-1d955-firebase-adminsdk-fbsvc-d2f9578075.json")

        firebase_admin.initialize_app(cred)

        #     "priority": "high",
        #     "restricted_package_name": "com.collabll.orderpickyboy"

        #     # See documentation on defining a message payload.

        message = messaging.Message(
            data={"title": title, "description": description, "orderID": OrderID},
            android=messaging.AndroidConfig(
                priority='high'

            ),
            apns=messaging.APNSConfig(headers={"apns-priority": "5"}, payload=messaging.APNSPayload(
                aps=messaging.Aps(badge=99, alert=messaging.ApsAlert(title=title, body=description, ),
                                  sound="default", custom_data={"orderID": OrderID}),
            ))
            ,

            token=fcmToken, )

        try:

            response = messaging.send(message)




        except Exception as e:
            logging.info(f"Error on Notification: {e}")
            pass


    else:
        message = messaging.Message(

            data={"title": title, "description": description, "orderID": OrderID},

            android=messaging.AndroidConfig(
                priority='high'

            ),
            apns=messaging.APNSConfig(headers={"apns-priority": "5"}, payload=messaging.APNSPayload(
                aps=messaging.Aps(badge=99, alert=messaging.ApsAlert(title=title, body=description, ),
                                  sound="default", custom_data={"orderID": OrderID}),
            ))
            ,

            token=fcmToken)
        try:

            response = messaging.send(message)

        except Exception as e:
            logging.info(f"Error on Notification: {e}")
            pass

            pass

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 = "ACc6df2dd6139dd07e9d84e78ac73f27f8"
    auth_token = "d01958dbb0ae7723b4718873add279e7"
    fromph = "+18106965991"
    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}")
    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")






