from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import UserProfile, StockLevelSize, ProfitRecord, StockMovement, TransactionItem

# ✅ CHANGE 1: Disable automatic signal for StockLevelSize updates
# WHY: The signal causes issues because it fires DURING transaction processing
# We manually call update_total_quantity() after ALL size deductions complete
# This prevents the signal from trying to save while we're in the middle of processing

# OLD CODE (COMMENTED OUT)
# @receiver([post_save, post_delete], sender=StockLevelSize)
# def update_stocklevel_total(sender, instance, **kwargs):
#     """Recalculate total stock when any StockLevelSize is changed or deleted."""
#     instance.stock_level.update_total_quantity()

# ✅ NEW APPROACH: We manually call update_total_quantity() in the serializer
# after each size deduction completes. This is more explicit and prevents
# race conditions where the signal tries to read/write while we're still processing.


# ✅ CHANGE 2: Keep the profit record signal (this one is fine)
# WHY: This runs AFTER the transaction is complete, so no conflicts
@receiver(post_save, sender=StockMovement)
def create_profit_record(sender, instance, created, **kwargs):
    """Automatically calculate and store profit when a sale occurs."""
    if not created:
        return  # Only handle new records

    # Only calculate profit for outgoing stock (sales)
    if instance.delta < 0:
        product = instance.product
        selling_price = product.unit_price or 0
        buying_price = product.buying_price or 0
        quantity_sold = abs(instance.delta)

        # Proper profit calculation
        profit_amount = (selling_price - buying_price) * quantity_sold
        
        # Create or update the profit record
        ProfitRecord.objects.update_or_create(
            stock_movement=instance,
            defaults={
                'product': product,
                'profit': profit_amount
            }
        )


# ✅ OPTIONAL: If you want to keep the signal but make it safer
# Uncomment this version instead of the old one:
"""
from django.db import transaction

@receiver([post_save, post_delete], sender=StockLevelSize)
def update_stocklevel_total(sender, instance, **kwargs):
    '''
    Recalculate total stock when any StockLevelSize is changed or deleted.
    
    ✅ This version uses transaction.on_commit() to prevent conflicts
    WHY: Waits until the transaction is committed before updating
    '''
    # Only update if we're not in the middle of a transaction rollback
    if kwargs.get('raw', False):
        return
    
    # Use on_commit to prevent update during transaction processing
    transaction.on_commit(
        lambda: instance.stock_level.update_total_quantity()
    )
"""

# ✅ RECOMMENDATION: 
# For now, DISABLE the StockLevelSize signal and rely on manual calls
# in the serializer. This is the safest approach and prevents all the
# issues you've been experiencing.