from django.db import transaction
from django.db.models.signals import post_save
from django.dispatch import receiver

from shop_management.models.data.advance import Advance
from shop_management.models.data.customer_balance_payment import CustomerBalancePayment
from shop_management.models.data.customer_debtor import CustomerDebtor
from shop_management.models.data.account_transfer import AccountTransfer
from shop_management.models.data.expense import Expense
from shop_management.models.data.passive_income import PassiveIncome
from shop_management.models.data.payroll import Payroll
from shop_management.models.data.purchase import Purchase, PurchaseItem
from shop_management.models.data.purchase_payment import PurchasePayment
from shop_management.models.data.purchase_return import PurchaseReturn
from shop_management.models.data.quotation import Quotation, QuotationItem
from shop_management.models.data.sale import Sale, SaleItem
from shop_management.models.data.sale_payment import SalePayment
from shop_management.models.data.sale_return import SaleReturn
from shop_management.models.data.stock_transfer import StockTransfer
from shop_management.models.data.supplier_balance_payment import SupplierBalancePayment
from shop_management.services import diary_logger


def _on_commit(fn):
    transaction.on_commit(fn)


def _reload(model, pk):
    try:
        return model.objects.get(pk=pk)
    except model.DoesNotExist:
        return None


@receiver(post_save, sender=Purchase)
def diary_log_purchase(sender, instance, **kwargs):
    pk = instance.pk
    _on_commit(lambda: diary_logger.log_purchase(_reload(Purchase, pk)))


@receiver(post_save, sender=Sale)
def diary_log_sale(sender, instance, **kwargs):
    pk = instance.pk
    _on_commit(lambda: diary_logger.log_sale(_reload(Sale, pk)))


@receiver(post_save, sender=Quotation)
def diary_log_quotation(sender, instance, **kwargs):
    pk = instance.pk
    _on_commit(lambda: diary_logger.log_quotation(_reload(Quotation, pk)))


@receiver(post_save, sender=SalePayment)
def diary_log_sale_payment(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_sale_payment(instance))


@receiver(post_save, sender=PurchasePayment)
def diary_log_purchase_payment(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_purchase_payment(instance))


@receiver(post_save, sender=CustomerBalancePayment)
def diary_log_customer_payment(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_customer_balance_payment(instance))


@receiver(post_save, sender=SupplierBalancePayment)
def diary_log_supplier_payment(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_supplier_balance_payment(instance))


@receiver(post_save, sender=StockTransfer)
def diary_log_stock_transfer(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_stock_transfer(instance))


@receiver(post_save, sender=Expense)
def diary_log_expense(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_expense(instance))


@receiver(post_save, sender=SaleReturn)
def diary_log_sale_return(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_sale_return(instance))


@receiver(post_save, sender=PurchaseReturn)
def diary_log_purchase_return(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_purchase_return(instance))


@receiver(post_save, sender=Payroll)
def diary_log_payroll(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_payroll(instance))


@receiver(post_save, sender=Advance)
def diary_log_advance(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_advance(instance))


@receiver(post_save, sender=PassiveIncome)
def diary_log_passive_income(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_passive_income(instance))


@receiver(post_save, sender=PurchaseItem)
def diary_log_purchase_item(sender, instance, **kwargs):
    if instance.purchase_id:
        pk = instance.purchase_id
        _on_commit(lambda: diary_logger.log_purchase(_reload(Purchase, pk)))


@receiver(post_save, sender=SaleItem)
def diary_log_sale_item(sender, instance, **kwargs):
    if instance.sale_id:
        pk = instance.sale_id
        _on_commit(lambda: diary_logger.log_sale(_reload(Sale, pk)))


@receiver(post_save, sender=QuotationItem)
def diary_log_quotation_item(sender, instance, **kwargs):
    if instance.quotation_id:
        pk = instance.quotation_id
        _on_commit(lambda: diary_logger.log_quotation(_reload(Quotation, pk)))


@receiver(post_save, sender=CustomerDebtor)
def diary_log_customer_debtor(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_customer_debtor(instance))


@receiver(post_save, sender=AccountTransfer)
def diary_log_account_transfer(sender, instance, **kwargs):
    _on_commit(lambda: diary_logger.log_account_transfer(instance))
