from django.db.models import Sum
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from apps.product.models import QuotaDistribution
from .models import InventoryEntry, InventoryQuotaSaleItem


def calculate_warehouse_entry(quota_distribution):
    total_entry = quota_distribution.inventory_entry.aggregate(
        total=Sum('weight')
    )['total'] or 0

    quota_distribution.warehouse_entry = total_entry
    quota_distribution.save(update_fields=['warehouse_entry'])


def warehouse_sold_and_balance(quota_distribution: QuotaDistribution):
    total_sold = quota_distribution.sale_items.aggregate(
        total=Sum('weight')
    )['total'] or 0

    quota_distribution.been_sold = total_sold
    quota_distribution.warehouse_balance = quota_distribution.warehouse_entry - total_sold
    if quota_distribution.warehouse_balance >= 0:

        # calculate extra sales & mines total extra sales weight from new inventory entry
        # and set the warehouse balance
        extra_sales = quota_distribution.extra_sales.all()
        total_extra_sales_weight = extra_sales.aggregate(total=Sum('weight'))['total'] or 0
        if quota_distribution.free_sale_balance != 0:
            if quota_distribution.warehouse_balance >= quota_distribution.free_sale_balance:
                quota_distribution.warehouse_balance -= total_extra_sales_weight
                quota_distribution.free_sale_balance = 0
            else:
                quota_distribution.free_sale_balance -= quota_distribution.warehouse_balance
                quota_distribution.warehouse_balance = 0

        # calculate pre_sales & mines total pre_sales weight from new inventory entry
        # and set the warehouse balance
        pre_sales = quota_distribution.pre_sales.all()
        total_pre_sales_weight = pre_sales.aggregate(total=Sum('weight'))['total'] or 0
        if total_pre_sales_weight != 0:
            if quota_distribution.warehouse_balance >= quota_distribution.pre_sale_balance:
                quota_distribution.warehouse_balance -= total_pre_sales_weight
                quota_distribution.pre_sale_balance = 0
            else:
                quota_distribution.pre_sale_balance -= quota_distribution.warehouse_balance
                quota_distribution.warehouse_balance = 0
    quota_distribution.save(update_fields=['been_sold', 'warehouse_balance', 'free_sale_balance', 'pre_sale_balance'])


@receiver(post_save, sender=InventoryEntry)
@receiver(post_delete, sender=InventoryEntry)
def update_distribution_warehouse_entry(sender, instance, **kwargs):
    calculate_warehouse_entry(instance.distribution)
    warehouse_sold_and_balance(instance.distribution)


@receiver(post_save, sender=InventoryQuotaSaleItem)
@receiver(post_delete, sender=InventoryQuotaSaleItem)
def update_distribution_warehouse_sold_and_balance(sender, instance: InventoryQuotaSaleItem, **kwargs):
    if instance.quota_distribution and not instance.quota_distribution.pre_sale:
        # if transaction status is success and warehouse management Done once, inventory_calculation set to true
        if instance.transaction.transaction_status == 'success' and instance.inventory_calculation is False:
            warehouse_sold_and_balance(
                quota_distribution=instance.quota_distribution,
            )
    else:
        print("quota distribution is null - warehouse app signals")
