from decimal import Decimal

from django.db.models.signals import post_save
from django.db.models.signals import (
    pre_delete,
    post_delete,
    pre_save,
)
from django.dispatch import receiver

from core.apps.eggs.models import (
    CourierProduct,
    Group,
    Invoice,
    Party,
    Monitoring,
)
from core.apps.eggs.models import OrderItems


@receiver(post_save, sender=CourierProduct)
def update_group_quantity(sender, instance, created, **kwargs):
    if created:
        group = Group.objects.get(id=instance.group_id.id)
        if instance.count > group.quantity:
            raise ValueError("Count cannot be greater than group quantity")
        else:
            group.quantity -= instance.count
            group.party_id.remaining_count -= instance.count
            group.party_id.courier_eggs += instance.count
            group.party_id.save()
            group.save()


@receiver(post_save, sender=OrderItems)
def update_order_price(sender, instance, created, **kwargs):
    if created:
        group_instance = instance.group_id
        order_instance = instance.order_id

        if instance.sale_type == "optom":
            order_instance.price += (
                group_instance.wholesale_price * instance.count
            )
        elif instance.sale_type == "dona":
            order_instance.price += group_instance.unit_price * instance.count

        order_instance.save()
        # narxni chegirma bilan kamaytirish
        order_instance.price -= instance.discount if instance.discount else 0
        order_instance.save()
        # foydani hisoblash
        group_instance.party_id.benefit += order_instance.price
        group_instance.party_id.save()

        # sotilgan mahsulotlar sonini
        group_instance.party_id.sold_count += instance.count
        # group_instance.party_id.sold_count = (
        #     group_instance.party_id.count
        #     - group_instance.party_id.remaining_count
        # )
        group_instance.party_id.save()
        # sof foydani hisoblash
        group_instance.party_id.profit = (
            group_instance.party_id.benefit
            - group_instance.party_id.sold_count * group_instance.entry_price
        )
        group_instance.party_id.save()

        price_paid = (
            Decimal(order_instance.price_paid)
            if order_instance.price_paid
            else Decimal("0")
        )

        Monitoring.objects.create(
            content_object=instance,
            action="order_created",
            user_id=instance.order_id.courier_id.user_id,
            created_who=f"{instance.order_id.courier_id.user_id.first_name} {instance.order_id.courier_id.user_id.last_name}",
            created_by=instance.order_id.market_id.name,
            reason=f"Buyurtma: {instance.order_id.price}",
            comment="Kirim",
            price=(
                instance.order_id.price_paid
                if instance.order_id.price_paid
                else 0
            ),
        )

        # qarzni hisoblash
        order_instance.debt = order_instance.price - price_paid
        order_instance.save()
        # to'langan narxni hisoblash
        order_instance.price_paid = order_instance.price - Decimal(
            order_instance.debt
        )
        order_instance.save()

        if order_instance.market_id:
            # bozor qarzini hisoblash
            market_instance = order_instance.market_id
            market_instance.debt_unpaid += Decimal(order_instance.debt)
            market_instance.save()
            # bozor to'langan narxni hisoblash
            market_instance.debt_paid += price_paid
            market_instance.save()


# @receiver(post_save, sender=OrderItems)
# def update_order_price(sender, instance, created, **kwargs):
#     if created:
#         group_instance = instance.group_id
#         order_instance = instance.order_id
#
#         # Ensure all numeric values are Decimal
#         count = Decimal(instance.count)
#         wholesale_price = Decimal(group_instance.wholesale_price)
#         unit_price = Decimal(group_instance.unit_price)
#         discount = Decimal(instance.discount) if instance.discount else Decimal('0')
#
#         if instance.sale_type == "optom":
#             order_instance.price += wholesale_price * count
#         elif instance.sale_type == "dona":
#             order_instance.price += unit_price * count
#
#         order_instance.price -= discount
#         order_instance.save()
#
#         # Update party benefit
#         group_instance.party_id.benefit += order_instance.price
#         group_instance.party_id.save()
#
#         # Ensure price_paid and debt are Decimals
#         price_paid = Decimal(order_instance.price_paid) if order_instance.price_paid else Decimal('0')
#         debt = Decimal(order_instance.debt) if order_instance.debt else Decimal('0')
#
#         order_instance.debt = order_instance.price - price_paid
#         order_instance.save()
#         order_instance.price_paid = order_instance.price - debt
#         order_instance.save()
#
#         # Update market debt
#         if order_instance.market_id:
#             market_instance = order_instance.market_id
#             market_instance.debt_unpaid += order_instance.debt
#             market_instance.save()
#             market_instance.debt_paid += order_instance.price_paid
#             market_instance.save()


@receiver(post_save, sender=Group)
def update_party_on_group_change(sender, instance, created, **kwargs):
    if created:
        quantity_change = instance.quantity

        party_instance = instance.party_id

        party_instance.count += instance.quantity
        party_instance.cost += instance.entry_price * instance.quantity
        party_instance.save()
        party_instance.remaining_count += instance.quantity
        party_instance.save()
    else:
        pass
    #     old_group = Group.objects.get(pk=instance.pk)
    #     quantity_change = instance.quantity - old_group.quantity
    #
    # party_instance = instance.party_id
    # if party_instance:
    #     party_instance.remaining_count += quantity_change
    #     party_instance.save()
    #     party_instance.sold_count = (
    #             party_instance.count - party_instance.remaining_count
    #     )
    #     party_instance.save()
    #     party_instance.profit = party_instance.benefit - (
    #             party_instance.sold_count * instance.entry_price
    #     )
    #     party_instance.save()


@receiver(pre_delete, sender=Group)
def update_party_on_group_delete(sender, instance, **kwargs):
    party_instance = instance.party_id
    if party_instance:
        quantity_change = instance.quantity
        party_instance.count -= quantity_change
        party_instance.remaining_count += quantity_change
        party_instance.sold_count = (
            party_instance.count - party_instance.remaining_count
        )
        party_instance.save()


@receiver(post_save, sender=Invoice)
@receiver(post_delete, sender=Invoice)
def invoice_changed(sender, instance, **kwargs):
    if instance.party_id:
        instance.party_id.update_total_cost()


@receiver(pre_save, sender=Party)
def party_cost_changed(sender, instance, **kwargs):
    if instance.pk:
        old_party = Party.objects.get(pk=instance.pk)
        if old_party.cost != instance.cost:
            if (
                not hasattr(instance, "_updating_total_cost")
                or not instance._updating_total_cost
            ):
                instance._updating_total_cost = True
                instance.update_total_cost()
                instance._updating_total_cost = False
