# apps/banking/signals.py
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.db import transaction
from django.db.models import Sum
from .models import Transaction as BankingTransaction, Account


@receiver(post_save, sender=BankingTransaction)
def update_account_balances_on_transaction_create(sender, instance, created, **kwargs):
    """Met à jour les soldes des comptes lors de la création ou modification d'une transaction."""
    if created:
        # Nouvelle transaction - mettre à jour les soldes
        with transaction.atomic():
            # Décrémenter le compte source
            from_account = instance.from_account
            from_account.balance -= instance.amount
            from_account.save(update_fields=['balance', 'updated_at'])
            
            # Incrémenter le compte destination
            to_account = instance.to_account
            to_account.balance += instance.amount
            to_account.save(update_fields=['balance', 'updated_at'])
            
            print(f"✅ Soldes mis à jour: {from_account.name} (-{instance.amount}) | {to_account.name} (+{instance.amount})")


@receiver(post_delete, sender=BankingTransaction)
def update_account_balances_on_transaction_delete(sender, instance, **kwargs):
    """Remet à jour les soldes des comptes lors de la suppression d'une transaction."""
    with transaction.atomic():
        # Restaurer le compte source
        from_account = instance.from_account
        from_account.balance += instance.amount
        from_account.save(update_fields=['balance', 'updated_at'])
        
        # Décrémenter le compte destination
        to_account = instance.to_account
        to_account.balance -= instance.amount
        to_account.save(update_fields=['balance', 'updated_at'])
        
        print(f"🔄 Soldes restaurés après suppression: {from_account.name} (+{instance.amount}) | {to_account.name} (-{instance.amount})")


def recalculate_account_balance(account):
    """Recalcule le solde d'un compte basé sur toutes ses transactions."""
    incoming = BankingTransaction.objects.filter(
        to_account=account
    ).aggregate(total=Sum('amount'))['total'] or 0
    
    outgoing = BankingTransaction.objects.filter(
        from_account=account
    ).aggregate(total=Sum('amount'))['total'] or 0
    
    calculated_balance = incoming - outgoing
    
    # Mettre à jour le solde
    account.balance = calculated_balance
    account.save(update_fields=['balance', 'updated_at'])
    
    return calculated_balance


def sync_all_account_balances():
    """Synchronise tous les soldes de comptes avec leurs transactions."""
    print("🔄 Synchronisation de tous les soldes de comptes...")
    
    updated_count = 0
    for account in Account.objects.all():
        old_balance = account.balance
        new_balance = recalculate_account_balance(account)
        
        if old_balance != new_balance:
            print(f"📊 {account.name}: {old_balance} → {new_balance} FCFA")
            updated_count += 1
        else:
            print(f"✅ {account.name}: {new_balance} FCFA (déjà correct)")
    
    print(f"✅ Synchronisation terminée: {updated_count} compte(s) mis à jour.")
    return updated_count
