"""
Django signals for the Stiftung app.
Handles automatic payment tracking and account balance updates when model instances change.
"""

from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.utils import timezone
from decimal import Decimal

from .models import DestinataerUnterstuetzung, BankTransaction


@receiver(pre_save, sender=DestinataerUnterstuetzung)
def unterstuetzung_pre_save(sender, instance, **kwargs):
    """Store the old status before saving to detect status changes"""
    if instance.pk:
        try:
            old_instance = DestinataerUnterstuetzung.objects.get(pk=instance.pk)
            instance._old_status = old_instance.status
        except DestinataerUnterstuetzung.DoesNotExist:
            instance._old_status = None
    else:
        instance._old_status = None


@receiver(post_save, sender=DestinataerUnterstuetzung)
def update_account_balance_on_payment(sender, instance, created, **kwargs):
    """
    Update account balance when a payment is marked as paid (ausgezahlt).
    Creates a corresponding bank transaction and updates the account balance.
    Prevents duplicate transactions by checking if one already exists.
    """
    # Only process if payment was just marked as paid
    old_status = getattr(instance, '_old_status', None)
    
    if instance.status == 'ausgezahlt' and old_status != 'ausgezahlt':
        # Payment was just marked as paid
        
        # Check if a transaction already exists for this payment to prevent duplicates
        existing_transaction = BankTransaction.objects.filter(
            kommentare__contains=f'Unterstützung {instance.id}'
        ).first()
        
        if existing_transaction:
            print(f"⚠️ Transaction already exists for payment {instance.id} to {instance.destinataer.get_full_name()}, skipping duplicate")
            return
        
        # Set the ausgezahlt_am date if not already set
        if not instance.ausgezahlt_am:
            instance.ausgezahlt_am = timezone.now().date()
            # Avoid infinite recursion by updating without triggering signals
            DestinataerUnterstuetzung.objects.filter(pk=instance.pk).update(
                ausgezahlt_am=instance.ausgezahlt_am
            )
        
        # Create a bank transaction for this payment
        transaction = BankTransaction.objects.create(
            konto=instance.konto,
            datum=instance.ausgezahlt_am or timezone.now().date(),
            valuta=instance.ausgezahlt_am or timezone.now().date(),
            betrag=-instance.betrag,  # Negative because it's an outgoing payment
            waehrung='EUR',
            verwendungszweck=f"Unterstützungszahlung: {instance.beschreibung or instance.destinataer.get_full_name()}",
            empfaenger_zahlungspflichtiger=instance.empfaenger_name or instance.destinataer.get_full_name(),
            iban_gegenpartei=instance.empfaenger_iban or '',
            transaction_type='ueberweisung',
            status='verified',
            referenz=f'PAY-{instance.id}',  # Unique reference to prevent duplicates
            kommentare=f'Automatisch erstellt bei Markierung als ausgezahlt für Unterstützung {instance.id}',
        )
        
        # Update account balance
        instance.konto.saldo -= instance.betrag
        instance.konto.saldo_datum = instance.ausgezahlt_am or timezone.now().date()
        instance.konto.save()
        
        print(f"✅ Account balance updated: {instance.konto.kontoname} - €{instance.betrag} (Payment to {instance.destinataer.get_full_name()}) - Transaction {transaction.id}")
    
    # Handle reversal if payment is changed from paid back to unpaid
    elif old_status == 'ausgezahlt' and instance.status != 'ausgezahlt':
        # Payment was unmarked as paid - reverse the transaction
        
        # Find and delete the corresponding bank transaction
        try:
            # Look for the transaction created for this payment
            transaction = BankTransaction.objects.filter(
                konto=instance.konto,
                betrag=-instance.betrag,
                kommentare__contains=f'Unterstützung {instance.id}'
            ).first()
            
            if transaction:
                transaction.delete()
                
                # Reverse the account balance update
                instance.konto.saldo += instance.betrag
                instance.konto.saldo_datum = timezone.now().date()
                instance.konto.save()
                
                # Clear the ausgezahlt_am date
                # Update without triggering signals
                DestinataerUnterstuetzung.objects.filter(pk=instance.pk).update(
                    ausgezahlt_am=None
                )
                
                print(f"🔄 Payment reversal: Account balance restored for {instance.destinataer.get_full_name()} - €{instance.betrag}")
        except Exception as e:
            print(f"⚠️ Error reversing payment for {instance.destinataer.get_full_name()}: {e}")


@receiver(post_save, sender=BankTransaction)
def update_account_balance_on_transaction(sender, instance, created, **kwargs):
    """
    Update account balance whenever a new bank transaction is created or modified
    (excluding transactions created by payment processing to avoid double-counting)
    """
    # Skip if this is a payment-related transaction (already handled by payment signal)
    if instance.kommentare and 'Unterstützung' in instance.kommentare:
        return
    
    if created:
        # Update the account balance based on the transaction
        instance.konto.saldo += instance.betrag  # Add the transaction amount
        instance.konto.saldo_datum = instance.valuta or instance.datum
        instance.konto.save()
        
        print(f"💰 Account balance updated from transaction: {instance.konto.kontoname} {'+ ' if instance.betrag >= 0 else '- '}€{abs(instance.betrag)}")