"""
Django management command to manually link M-Pesa transaction to borrower
"""
from django.core.management.base import BaseCommand, CommandError
from loans.models import MpesaTransaction
from users.models import CustomUser


class Command(BaseCommand):
    help = 'Manually link M-Pesa transaction to a borrower'

    def add_arguments(self, parser):
        parser.add_argument(
            'transaction_id',
            type=str,
            help='Transaction ID or M-Pesa TransID',
        )
        parser.add_argument(
            '--phone',
            type=str,
            help='Borrower phone number',
        )
        parser.add_argument(
            '--id-number',
            type=str,
            help='Borrower ID number',
        )
        parser.add_argument(
            '--user-id',
            type=str,
            help='Borrower user ID',
        )
        parser.add_argument(
            '--yes',
            action='store_true',
            help='Skip confirmation prompt',
        )

    def handle(self, *args, **options):
        transaction_id = options['transaction_id']
        phone = options.get('phone')
        id_number = options.get('id_number')
        user_id = options.get('user_id')
        
        self.stdout.write(self.style.SUCCESS('='*70))
        self.stdout.write(self.style.SUCCESS('Link M-Pesa Transaction to Borrower'))
        self.stdout.write(self.style.SUCCESS('='*70))
        
        # Find transaction
        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'Current Status: {transaction.status}')
        self.stdout.write(f'Current Borrower: {transaction.borrower or "Not matched"}')
        
        # Find borrower
        borrower = None
        
        if user_id:
            try:
                borrower = CustomUser.objects.get(id=user_id, role='borrower')
                self.stdout.write(f'\n✓ Found borrower by user ID: {borrower.get_full_name()}')
            except CustomUser.DoesNotExist:
                raise CommandError(f'Borrower not found with user ID: {user_id}')
        
        elif id_number:
            try:
                borrower = CustomUser.objects.get(id_number=id_number, role='borrower')
                self.stdout.write(f'\n✓ Found borrower by ID number: {borrower.get_full_name()}')
            except CustomUser.DoesNotExist:
                raise CommandError(f'Borrower not found with ID number: {id_number}')
        
        elif phone:
            # Try different phone formats
            phone_variants = [
                phone,
                phone.replace('+', ''),
                f'+{phone}' if not phone.startswith('+') else phone,
                f'254{phone[1:]}' if phone.startswith('0') else phone,
                f'+254{phone[1:]}' if phone.startswith('0') else phone,
            ]
            
            for variant in phone_variants:
                try:
                    borrower = CustomUser.objects.get(phone_number=variant, role='borrower')
                    self.stdout.write(f'\n✓ Found borrower by phone ({variant}): {borrower.get_full_name()}')
                    break
                except CustomUser.DoesNotExist:
                    continue
            
            if not borrower:
                raise CommandError(f'Borrower not found with phone: {phone}')
        
        else:
            # Interactive mode not supported in non-interactive environment
            raise CommandError(
                'No borrower specified. Use one of:\n'
                '  --phone <PHONE_NUMBER>\n'
                '  --id-number <ID_NUMBER>\n'
                '  --user-id <USER_ID>'
            )
        
        # Confirm
        self.stdout.write('\n' + '='*70)
        self.stdout.write('Linking:')
        self.stdout.write(f'  Transaction: {transaction.trans_id} (KES {transaction.amount})')
        self.stdout.write(f'  To Borrower: {borrower.get_full_name()}')
        self.stdout.write(f'  Phone: {borrower.phone_number}')
        self.stdout.write(f'  ID Number: {borrower.id_number or "N/A"}')
        self.stdout.write('='*70)
        
        # Skip confirmation if --yes flag is provided
        if not options.get('yes'):
            try:
                confirm = input('\nProceed? (yes/no): ')
                if confirm.lower() != 'yes':
                    self.stdout.write('Cancelled.')
                    return
            except EOFError:
                # Non-interactive environment, require --yes flag
                raise CommandError(
                    'Cannot prompt for confirmation in non-interactive environment. '
                    'Use --yes flag to proceed automatically.'
                )
        
        # Link and process
        self.stdout.write('\n' + '-'*70)
        self.stdout.write('Linking transaction to borrower...')
        self.stdout.write('-'*70)
        
        transaction.borrower = borrower
        transaction.save()
        
        self.stdout.write(self.style.SUCCESS('✓ Transaction linked to borrower'))
        
        # Process payment
        self.stdout.write('\n' + '-'*70)
        self.stdout.write('Processing payment...')
        self.stdout.write('-'*70 + '\n')
        
        success = transaction.process_payment()
        transaction.refresh_from_db()
        
        self.stdout.write('\n' + '='*70)
        if success:
            self.stdout.write(self.style.SUCCESS('✓ Payment Processed Successfully!'))
        else:
            self.stdout.write(self.style.WARNING('⚠ Payment Processing Completed with Issues'))
        self.stdout.write('='*70)
        
        self.stdout.write(f'\nTransaction Status: {transaction.status}')
        self.stdout.write(f'Matched Borrower: {transaction.borrower.get_full_name()}')
        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.repayment:
            self.stdout.write(f'Receipt Number: {transaction.repayment.receipt_number}')
        
        if transaction.processing_notes:
            self.stdout.write(f'\nProcessing Notes: {transaction.processing_notes}')
        
        if success and transaction.repayment:
            self.stdout.write(self.style.SUCCESS('\n✓ Payment successfully applied to loan!'))
            self.stdout.write('\nYou can now view it at:')
            self.stdout.write('  • /loans/repayments/ - Repayment record')
            self.stdout.write('  • /payments/transactions/ - Transaction details')
            self.stdout.write('  • /loans/ - Updated loan balance')
        else:
            self.stdout.write(self.style.ERROR('\n✗ Payment could not be fully processed'))
            if not transaction.loan:
                self.stdout.write('\nReason: No active loans found for this borrower')
                self.stdout.write('Check that the borrower has an active loan in the system')
        
        self.stdout.write('\n')
