"""
Management command to reconcile account balances with actual transactions.

This command will:
1. Calculate the correct balance based on all bank transactions
2. Update the account balance to match the calculated balance
3. Show discrepancies between stored and calculated balances

Usage:
    python manage.py reconcile_balances
"""

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

from stiftung.models import StiftungsKonto, BankTransaction


class Command(BaseCommand):
    help = 'Reconcile account balances with bank transactions'

    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 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('🔍 Reconciling account balances with transactions...')
        )
        
        if dry_run:
            self.stdout.write(
                self.style.WARNING('DRY RUN MODE - No changes will be made')
            )
        
        # Get accounts to process
        accounts_query = StiftungsKonto.objects.filter(aktiv=True)
        if account_filter:
            accounts_query = accounts_query.filter(kontoname__icontains=account_filter)
        
        accounts = accounts_query.all()
        
        if not accounts:
            self.stdout.write(
                self.style.ERROR('No accounts found matching criteria')
            )
            return
        
        self.stdout.write(f"Processing {accounts.count()} account(s)...")
        
        total_discrepancies = 0
        fixed_accounts = 0
        
        for account in accounts:
            self.stdout.write(f"\n🏦 {account.bank_name} - {account.kontoname}")
            self.stdout.write(f"   Stored Balance: €{account.saldo}")
            self.stdout.write(f"   Last Updated: {account.saldo_datum}")
            
            # Calculate balance from transactions
            transactions = BankTransaction.objects.filter(konto=account).order_by('datum')
            calculated_balance = Decimal('0.00')
            transaction_count = transactions.count()
            
            for transaction in transactions:
                calculated_balance += transaction.betrag
            
            self.stdout.write(f"   Transactions: {transaction_count}")
            self.stdout.write(f"   Calculated Balance: €{calculated_balance}")
            
            discrepancy = account.saldo - calculated_balance
            if discrepancy != 0:
                total_discrepancies += 1
                self.stdout.write(
                    self.style.WARNING(f"   ⚠️ Discrepancy: €{discrepancy}")
                )
                
                if not dry_run:
                    # Update the account balance
                    old_balance = account.saldo
                    account.saldo = calculated_balance
                    
                    # Update the balance date to the latest transaction date or today
                    if transactions.exists():
                        latest_transaction = transactions.order_by('-datum').first()
                        account.saldo_datum = latest_transaction.datum
                    else:
                        account.saldo_datum = timezone.now().date()
                    
                    account.save()
                    fixed_accounts += 1
                    
                    self.stdout.write(
                        self.style.SUCCESS(
                            f"   ✅ Updated: €{old_balance} → €{calculated_balance}"
                        )
                    )
                else:
                    self.stdout.write(
                        f"   📝 Would update: €{account.saldo} → €{calculated_balance}"
                    )
            else:
                self.stdout.write(
                    self.style.SUCCESS("   ✅ Balance is correct")
                )
            
            # Show recent transactions
            if transaction_count > 0:
                self.stdout.write("   Recent transactions:")
                recent = transactions.order_by('-datum')[:3]
                for trans in recent:
                    self.stdout.write(
                        f"     {trans.datum}: €{trans.betrag} - {trans.verwendungszweck[:50]}"
                    )
        
        # Summary
        self.stdout.write("\n" + "=" * 50)
        if dry_run:
            self.stdout.write(
                f"📊 Found {total_discrepancies} account(s) with balance discrepancies"
            )
            if total_discrepancies > 0:
                self.stdout.write("   Run without --dry-run to fix these discrepancies")
        else:
            if fixed_accounts > 0:
                self.stdout.write(
                    self.style.SUCCESS(
                        f"🎉 Fixed {fixed_accounts} account balance(s)"
                    )
                )
            else:
                self.stdout.write(
                    self.style.SUCCESS("✅ All account balances were already correct")
                )