"""
Simple Django management command to fix all unmatched M-Pesa payments
This is a convenience wrapper that reprocesses all pending transactions
"""
from django.core.management.base import BaseCommand
from loans.models import MpesaTransaction


class Command(BaseCommand):
    help = 'Fix all unmatched M-Pesa payments (reprocess pending transactions)'

    def add_arguments(self, parser):
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be processed without actually processing',
        )

    def handle(self, *args, **options):
        dry_run = options['dry_run']
        
        self.stdout.write(self.style.SUCCESS('='*70))
        self.stdout.write(self.style.SUCCESS('Fix Unmatched M-Pesa Payments'))
        self.stdout.write(self.style.SUCCESS('='*70))
        
        # Find all transactions that need processing
        # Include: no loan, no repayment, or failed status
        from django.db.models import Q
        
        pending = MpesaTransaction.objects.filter(
            Q(loan__isnull=True) |  # No loan matched
            Q(repayment__isnull=True) |  # No repayment created
            Q(status='failed')  # Failed transactions
        ).filter(
            status__in=['confirmed', 'validated', 'pending', 'failed']
        ).order_by('-created_at')
        
        count = pending.count()
        self.stdout.write(f'\nFound {count} unmatched transaction(s)\n')
        
        if count == 0:
            self.stdout.write(self.style.SUCCESS('✓ No unmatched transactions found!'))
            self.stdout.write('\nAll M-Pesa payments are properly matched and processed.')
            return
        
        # Show details
        self.stdout.write('Unmatched Transactions:')
        self.stdout.write('-'*70)
        for t in pending:
            self.stdout.write(f'  {t.trans_id}')
            self.stdout.write(f'    Amount: KES {t.amount}')
            self.stdout.write(f'    Phone: {t.phone_number or t.msisdn}')
            self.stdout.write(f'    Date: {t.created_at}')
            if t.processing_notes:
                self.stdout.write(f'    Notes: {t.processing_notes}')
            self.stdout.write('')
        
        if dry_run:
            self.stdout.write(self.style.WARNING('\n--dry-run mode: No changes made'))
            self.stdout.write('\nTo actually process these transactions, run:')
            self.stdout.write('  python manage.py fix_mpesa_payments')
            return
        
        # Confirm before processing
        self.stdout.write('\n' + '='*70)
        self.stdout.write('This will attempt to:')
        self.stdout.write('  1. Match each transaction to a borrower')
        self.stdout.write('  2. Match to an active loan')
        self.stdout.write('  3. Create repayment records')
        self.stdout.write('  4. Update loan balances')
        self.stdout.write('  5. Send notifications')
        self.stdout.write('='*70)
        
        confirm = input('\nProceed with processing? (yes/no): ')
        if confirm.lower() != 'yes':
            self.stdout.write(self.style.WARNING('\nCancelled. No changes made.'))
            return
        
        # Process transactions
        self.stdout.write('\n' + '='*70)
        self.stdout.write('Processing Transactions...')
        self.stdout.write('='*70 + '\n')
        
        success_count = 0
        failed_count = 0
        
        for transaction in pending:
            self.stdout.write('-'*70)
            self.stdout.write(f'Processing: {transaction.trans_id}')
            self.stdout.write(f'  Amount: KES {transaction.amount}')
            self.stdout.write(f'  Phone: {transaction.phone_number or transaction.msisdn}')
            
            try:
                # Clear previous matching to force re-matching
                transaction.borrower = None
                transaction.loan = None
                transaction.processing_notes = ''
                transaction.save()
                
                # Process the payment
                success = transaction.process_payment()
                transaction.refresh_from_db()
                
                if success and transaction.loan:
                    self.stdout.write(self.style.SUCCESS(
                        f'  ✓ SUCCESS: Matched to {transaction.borrower.get_full_name()}'
                    ))
                    self.stdout.write(f'    Loan: {transaction.loan.loan_number}')
                    if transaction.repayment:
                        self.stdout.write(f'    Receipt: {transaction.repayment.receipt_number}')
                    success_count += 1
                else:
                    self.stdout.write(self.style.WARNING(
                        f'  ⚠ PARTIAL: {transaction.processing_notes}'
                    ))
                    failed_count += 1
                    
            except Exception as e:
                self.stdout.write(self.style.ERROR(f'  ✗ ERROR: {str(e)}'))
                failed_count += 1
        
        # Summary
        self.stdout.write('\n' + '='*70)
        self.stdout.write('SUMMARY')
        self.stdout.write('='*70)
        self.stdout.write(f'Total Transactions: {count}')
        self.stdout.write(self.style.SUCCESS(f'Successfully Processed: {success_count}'))
        if failed_count > 0:
            self.stdout.write(self.style.WARNING(f'Failed/Partial: {failed_count}'))
        
        if success_count > 0:
            self.stdout.write('\n' + self.style.SUCCESS('✓ Payments have been processed!'))
            self.stdout.write('\nYou can now view them at:')
            self.stdout.write('  • /loans/repayments/ - All repayments including M-Pesa')
            self.stdout.write('  • /payments/transactions/ - M-Pesa transaction details')
            self.stdout.write('  • /loans/ - Updated loan balances')
        
        if failed_count > 0:
            self.stdout.write('\n' + self.style.WARNING('⚠ Some transactions could not be processed'))
            self.stdout.write('\nCommon reasons:')
            self.stdout.write('  • Phone number not registered in system')
            self.stdout.write('  • No active loans for the borrower')
            self.stdout.write('  • Phone number format mismatch (should be fixed now)')
            self.stdout.write('\nCheck the processing notes above for details.')
        
        self.stdout.write('\n')
