"""
Django management command to reprocess a specific M-Pesa transaction
Useful for fixing transactions that failed to match borrower/loan
"""
from django.core.management.base import BaseCommand, CommandError
from loans.models import MpesaTransaction


class Command(BaseCommand):
    help = 'Reprocess a specific M-Pesa transaction by ID or TransID'

    def add_arguments(self, parser):
        parser.add_argument(
            'transaction_id',
            type=str,
            nargs='?',  # Make it optional
            help='Transaction ID (UUID) or M-Pesa TransID',
        )
        parser.add_argument(
            '--all-pending',
            action='store_true',
            help='Reprocess all pending/unmatched transactions',
        )

    def handle(self, *args, **options):
        if options['all_pending']:
            self.reprocess_all_pending()
        elif options['transaction_id']:
            self.reprocess_single(options['transaction_id'])
        else:
            raise CommandError('Please provide either a transaction_id or use --all-pending flag')
    
    def reprocess_single(self, transaction_id):
        """Reprocess a single transaction"""
        self.stdout.write(self.style.SUCCESS('='*70))
        self.stdout.write(self.style.SUCCESS('Reprocess M-Pesa Transaction'))
        self.stdout.write(self.style.SUCCESS('='*70))
        
        # Try to find transaction by UUID or TransID
        try:
            transaction = MpesaTransaction.objects.get(id=transaction_id)
        except MpesaTransaction.DoesNotExist:
            try:
                transaction = MpesaTransaction.objects.get(trans_id=transaction_id)
            except MpesaTransaction.DoesNotExist:
                raise CommandError(f'Transaction not found: {transaction_id}')
        
        self.stdout.write(f'\nTransaction: {transaction.trans_id}')
        self.stdout.write(f'Amount: KES {transaction.amount}')
        self.stdout.write(f'Phone: {transaction.phone_number or transaction.msisdn}')
        self.stdout.write(f'Current Status: {transaction.status}')
        self.stdout.write(f'Current Borrower: {transaction.borrower or "Not matched"}')
        self.stdout.write(f'Current Loan: {transaction.loan or "Not matched"}')
        
        if transaction.processing_notes:
            self.stdout.write(f'Previous Notes: {transaction.processing_notes}')
        
        self.stdout.write('\n' + '-'*70)
        self.stdout.write('Attempting to reprocess...')
        self.stdout.write('-'*70 + '\n')
        
        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()
            
            # Refresh from database
            transaction.refresh_from_db()
            
            self.stdout.write('\n' + '='*70)
            if success:
                self.stdout.write(self.style.SUCCESS('✓ Transaction Processed Successfully!'))
            else:
                self.stdout.write(self.style.WARNING('⚠ Transaction Processing Completed with Issues'))
            self.stdout.write('='*70)
            
            self.stdout.write(f'\nNew Status: {transaction.status}')
            self.stdout.write(f'Matched Borrower: {transaction.borrower or "Not matched"}')
            self.stdout.write(f'Matched Loan: {transaction.loan or "Not matched"}')
            self.stdout.write(f'Repayment Created: {"Yes" if transaction.repayment else "No"}')
            
            if transaction.processing_notes:
                self.stdout.write(f'\nProcessing Notes: {transaction.processing_notes}')
            
            if success:
                self.stdout.write(self.style.SUCCESS('\n✓ Payment successfully applied to loan'))
            else:
                self.stdout.write(self.style.ERROR('\n✗ Payment could not be fully processed'))
                self.stdout.write('\nPossible reasons:')
                self.stdout.write('  - Phone number not registered in system')
                self.stdout.write('  - No active loans for this borrower')
                self.stdout.write('  - Phone number format mismatch')
            
            self.stdout.write('\n')
            
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'\n✗ Error: {str(e)}'))
            raise
    
    def reprocess_all_pending(self):
        """Reprocess all pending/unmatched transactions"""
        self.stdout.write(self.style.SUCCESS('='*70))
        self.stdout.write(self.style.SUCCESS('Reprocess All Pending Transactions'))
        self.stdout.write(self.style.SUCCESS('='*70))
        
        # Find all transactions that are confirmed but not matched to a loan
        pending = MpesaTransaction.objects.filter(
            status__in=['confirmed', 'validated', 'pending'],
            loan__isnull=True
        ).order_by('-created_at')
        
        count = pending.count()
        self.stdout.write(f'\nFound {count} pending transaction(s)\n')
        
        if count == 0:
            self.stdout.write(self.style.SUCCESS('No pending transactions to process'))
            return
        
        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
                transaction.borrower = None
                transaction.loan = None
                transaction.processing_notes = ''
                transaction.save()
                
                # Process
                success = transaction.process_payment()
                transaction.refresh_from_db()
                
                if success and transaction.loan:
                    self.stdout.write(self.style.SUCCESS(f'  ✓ Matched to: {transaction.borrower} - {transaction.loan.loan_number}'))
                    success_count += 1
                else:
                    self.stdout.write(self.style.WARNING(f'  ⚠ Could not match: {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: {count}')
        self.stdout.write(self.style.SUCCESS(f'Successful: {success_count}'))
        if failed_count > 0:
            self.stdout.write(self.style.WARNING(f'Failed: {failed_count}'))
        self.stdout.write('\n')
