"""
Management command to simulate M-Pesa payments for testing
"""
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from loans.models import Loan, MpesaTransaction
from decimal import Decimal
import uuid

User = get_user_model()


class Command(BaseCommand):
    help = 'Simulate M-Pesa payments for testing the integration'

    def add_arguments(self, parser):
        parser.add_argument(
            '--customer-id',
            type=str,
            help='Customer ID to simulate payment for',
        )
        parser.add_argument(
            '--amount',
            type=float,
            default=1000.0,
            help='Payment amount (default: 1000)',
        )
        parser.add_argument(
            '--phone',
            type=str,
            help='Phone number to use (default: customer\'s phone)',
        )
        parser.add_argument(
            '--loan-number',
            type=str,
            help='Specific loan number to pay (optional)',
        )

    def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Simulating M-Pesa payment...'))
        
        # Get customer
        customer_id = options.get('customer_id')
        if not customer_id:
            # Find a customer with active loans
            customer = User.objects.filter(
                role='borrower',
                loans__status='active'
            ).first()
            
            if not customer:
                self.stdout.write(self.style.ERROR('No customers with active loans found'))
                return
        else:
            # Try to find customer by ID number first, then by database ID
            try:
                customer = User.objects.get(id_number=customer_id, role='borrower')
            except User.DoesNotExist:
                try:
                    customer = User.objects.get(id=customer_id, role='borrower')
                except User.DoesNotExist:
                    self.stdout.write(self.style.ERROR(f'Customer with ID number or database ID {customer_id} not found'))
                    return
        
        # Get payment details
        amount = Decimal(str(options.get('amount', 1000.0)))
        phone = options.get('phone') or customer.phone_number
        loan_number = options.get('loan_number')
        
        if not phone:
            self.stdout.write(self.style.ERROR('No phone number available for customer'))
            return
        
        # Get customer's active loans
        active_loans = Loan.active_objects.filter(
            borrower=customer,
            status='active'
        ).order_by('due_date')
        
        if not active_loans.exists():
            self.stdout.write(self.style.ERROR(f'No active loans found for customer {customer.get_full_name()}'))
            return
        
        self.stdout.write(f'Customer: {customer.get_full_name()} (ID: {customer.id})')
        self.stdout.write(f'Phone: {phone}')
        self.stdout.write(f'Amount: KES {amount:,.2f}')
        self.stdout.write(f'Active Loans: {active_loans.count()}')
        
        # Show loan details
        for loan in active_loans:
            outstanding = loan.outstanding_amount
            self.stdout.write(f'  - {loan.loan_number}: KES {outstanding:,.2f} (Due: {loan.due_date.strftime("%Y-%m-%d")})')
        
        # Create simulated M-Pesa transaction
        trans_id = f"SIM{uuid.uuid4().hex[:8].upper()}"
        
        # Simulate C2B callback data
        callback_data = {
            'TransID': trans_id,
            'TransTime': '20241008120000',  # Current timestamp
            'TransAmount': float(amount),
            'BusinessShortCode': '4159523',
            'BillRefNumber': loan_number or customer.id_number or str(customer.id),
            'InvoiceNumber': '',
            'OrgAccountBalance': 1000000.0,
            'ThirdPartyTransID': '',
            'MSISDN': phone,
            'FirstName': customer.first_name or 'Test',
            'MiddleName': '',
            'Last Name': customer.last_name or 'Customer'
        }
        
        # Create M-Pesa transaction
        mpesa_transaction = MpesaTransaction.objects.create(
            transaction_type='c2b',
            amount=amount,
            phone_number=phone,
            trans_id=trans_id,
            trans_time='20241008120000',
            business_short_code='4159523',
            bill_ref_number=loan_number or customer.id_number or str(customer.id),
            invoice_number='',
            org_account_balance=Decimal('1000000.00'),
            third_party_trans_id='',
            msisdn=phone,
            first_name=customer.first_name or 'Test',
            middle_name='',
            last_name=customer.last_name or 'Customer',
            status='confirmed',
            raw_confirmation_data=callback_data,
            is_automatic=True,
            payment_source='automatic'
        )
        
        self.stdout.write(f'Created M-Pesa transaction: {trans_id}')
        
        # Process the payment
        self.stdout.write('Processing payment...')
        success = mpesa_transaction.process_payment()
        
        if success:
            self.stdout.write(self.style.SUCCESS('Payment processed successfully!'))
            
            # Show updated loan status
            self.stdout.write('\nUpdated Loan Status:')
            for loan in active_loans:
                loan.refresh_from_db()
                outstanding = loan.outstanding_amount
                self.stdout.write(f'  - {loan.loan_number}: KES {outstanding:,.2f} (Status: {loan.status})')
            
            # Show created repayments
            if mpesa_transaction.repayment:
                self.stdout.write(f'\nRepayment created: {mpesa_transaction.repayment.receipt_number}')
                self.stdout.write(f'Amount: KES {mpesa_transaction.repayment.amount:,.2f}')
                self.stdout.write(f'Payment Source: {mpesa_transaction.repayment.get_payment_source_display()}')
            
        else:
            self.stdout.write(self.style.ERROR('Payment processing failed'))
            self.stdout.write(f'Error: {mpesa_transaction.processing_notes}')
        
        self.stdout.write(f'\nTransaction ID: {trans_id}')
        self.stdout.write('You can view this transaction in the admin panel.')
