"""
Management command to fix account balances for existing paid payments.

This command will:
1. Find all payments marked as 'ausgezahlt' (paid)
2. Check if corresponding bank transactions exist
3. Create missing bank transactions
4. Update account balances to reflect all paid payments

Usage:
    python manage.py fix_account_balances
"""

from django.core.management.base import BaseCommand
from django.utils import timezone
from decimal import Decimal

from stiftung.models import DestinataerUnterstuetzung, BankTransaction, StiftungsKonto


class Command(BaseCommand):
    help = 'Fix account balances for existing paid payments'

    def add_arguments(self, parser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be done without making changes',
        )
        parser.add_argument(
            '--account',
            type=str,
            help='Only process payments for specific account (by kontoname)',
        )

    def handle(self, *args, **options):
        dry_run = options['dry_run']
        account_filter = options.get('account')
        
        self.stdout.write(
            self.style.SUCCESS('🔍 Analyzing paid payments and account balances...')
        )
        
        if dry_run:
            self.stdout.write(
                self.style.WARNING('DRY RUN MODE - No changes will be made')
            )
        
        # Get all paid payments
        paid_payments_query = DestinataerUnterstuetzung.objects.filter(
            status='ausgezahlt'
        ).select_related('konto', 'destinataer')
        
        if account_filter:
            paid_payments_query = paid_payments_query.filter(
                konto__kontoname__icontains=account_filter
            )
        
        paid_payments = paid_payments_query.all()
        
        self.stdout.write(f"Found {paid_payments.count()} paid payments")
        
        # Group payments by account
        accounts_data = {}
        missing_transactions = []
        
        for payment in paid_payments:
            konto_id = payment.konto.id
            if konto_id not in accounts_data:
                accounts_data[konto_id] = {
                    'konto': payment.konto,
                    'payments': [],
                    'total_paid': Decimal('0.00'),
                    'missing_transactions': []
                }
            
            accounts_data[konto_id]['payments'].append(payment)
            accounts_data[konto_id]['total_paid'] += payment.betrag
            
            # Check if bank transaction exists for this payment
            existing_transaction = BankTransaction.objects.filter(
                konto=payment.konto,
                betrag=-payment.betrag,  # Negative for outgoing payment
                kommentare__contains=f'Unterstützung {payment.id}'
            ).first()
            
            if not existing_transaction:
                accounts_data[konto_id]['missing_transactions'].append(payment)
                missing_transactions.append(payment)
        
        # Report findings
        self.stdout.write("\n📊 ANALYSIS RESULTS:")
        self.stdout.write("=" * 50)
        
        for account_data in accounts_data.values():
            konto = account_data['konto']
            payments_count = len(account_data['payments'])
            total_paid = account_data['total_paid']
            missing_count = len(account_data['missing_transactions'])
            
            self.stdout.write(f"\n🏦 {konto.bank_name} - {konto.kontoname}")
            self.stdout.write(f"   Current Balance: €{konto.saldo}")
            self.stdout.write(f"   Paid Payments: {payments_count} (Total: €{total_paid})")
            self.stdout.write(f"   Missing Transactions: {missing_count}")
            
            if missing_count > 0:
                expected_balance = konto.saldo - sum(p.betrag for p in account_data['missing_transactions'])
                self.stdout.write(
                    self.style.WARNING(f"   Expected Balance after fix: €{expected_balance}")
                )
        
        if not missing_transactions:
            self.stdout.write(
                self.style.SUCCESS("\n✅ All paid payments have corresponding transactions!")
            )
            return
        
        self.stdout.write(f"\n⚠️ Found {len(missing_transactions)} payments without transactions")
        
        if not dry_run:
            self.stdout.write("\n🔧 CREATING MISSING TRANSACTIONS...")
            
            created_count = 0
            for payment in missing_transactions:
                # Create bank transaction
                transaction = BankTransaction.objects.create(
                    konto=payment.konto,
                    datum=payment.ausgezahlt_am or payment.faellig_am,
                    valuta=payment.ausgezahlt_am or payment.faellig_am,
                    betrag=-payment.betrag,  # Negative for outgoing payment
                    waehrung='EUR',
                    verwendungszweck=f"Unterstützungszahlung: {payment.beschreibung or payment.destinataer.get_full_name()}",
                    empfaenger_zahlungspflichtiger=payment.empfaenger_name or payment.destinataer.get_full_name(),
                    iban_gegenpartei=payment.empfaenger_iban or '',
                    transaction_type='ueberweisung',
                    status='verified',
                    kommentare=f'Nachträglich erstellt für Unterstützung {payment.id} - Zahlung vom {payment.ausgezahlt_am or payment.faellig_am}',
                )
                
                # Update account balance
                payment.konto.saldo -= payment.betrag
                payment.konto.saldo_datum = payment.ausgezahlt_am or payment.faellig_am
                payment.konto.save()
                
                created_count += 1
                self.stdout.write(
                    f"   ✅ Created transaction for {payment.destinataer.get_full_name()}: €{payment.betrag}"
                )
            
            self.stdout.write(
                self.style.SUCCESS(f"\n🎉 Successfully created {created_count} transactions and updated account balances!")
            )
            
            # Show final balances
            self.stdout.write("\n📈 UPDATED ACCOUNT BALANCES:")
            for account_data in accounts_data.values():
                if account_data['missing_transactions']:
                    konto = account_data['konto']
                    konto.refresh_from_db()  # Get updated balance
                    self.stdout.write(f"   {konto.bank_name} - {konto.kontoname}: €{konto.saldo}")
        
        else:
            self.stdout.write("\n📝 DRY RUN - Would create the following transactions:")
            for payment in missing_transactions:
                self.stdout.write(
                    f"   - {payment.destinataer.get_full_name()}: €{payment.betrag} "
                    f"on {payment.ausgezahlt_am or payment.faellig_am} "
                    f"from {payment.konto.kontoname}"
                )