"""
Django management command to check M-Pesa callbacks and their processing status
"""
from django.core.management.base import BaseCommand
from payments.models import MpesaCallback
from loans.models import MpesaTransaction
from django.utils import timezone
from datetime import timedelta


class Command(BaseCommand):
    help = 'Check M-Pesa callbacks and their processing status'

    def add_arguments(self, parser):
        parser.add_argument(
            '--days',
            type=int,
            default=7,
            help='Number of days to look back (default: 7)',
        )
        parser.add_argument(
            '--unprocessed-only',
            action='store_true',
            help='Show only unprocessed callbacks',
        )

    def handle(self, *args, **options):
        days = options['days']
        unprocessed_only = options['unprocessed_only']
        
        self.stdout.write(self.style.SUCCESS('='*70))
        self.stdout.write(self.style.SUCCESS('M-Pesa Callback Status Check'))
        self.stdout.write(self.style.SUCCESS('='*70))
        
        # Get recent callbacks
        cutoff_date = timezone.now() - timedelta(days=days)
        callbacks = MpesaCallback.objects.filter(
            created_at__gte=cutoff_date
        ).order_by('-created_at')
        
        if unprocessed_only:
            callbacks = callbacks.filter(processed=False)
        
        count = callbacks.count()
        self.stdout.write(f'\nFound {count} callback(s) in the last {days} days\n')
        
        if count == 0:
            self.stdout.write(self.style.SUCCESS('No callbacks found.'))
            return
        
        # Display each callback
        for callback in callbacks:
            self.stdout.write('='*70)
            self.stdout.write(f'Callback ID: {callback.id}')
            self.stdout.write(f'Type: {callback.callback_type}')
            self.stdout.write(f'Date: {callback.created_at}')
            self.stdout.write(f'IP Address: {callback.ip_address or "N/A"}')
            
            # Extract key info from raw data
            if callback.raw_data:
                trans_id = callback.raw_data.get('TransID', 'N/A')
                amount = callback.raw_data.get('TransAmount', 'N/A')
                phone = callback.raw_data.get('MSISDN', 'N/A')
                self.stdout.write(f'Trans ID: {trans_id}')
                self.stdout.write(f'Amount: KES {amount}')
                self.stdout.write(f'Phone: {phone}')
            
            # Check if linked to transaction
            if callback.transaction:
                self.stdout.write(self.style.SUCCESS(
                    f'✓ Linked to Transaction: {callback.transaction.id}'
                ))
                t = callback.transaction
                self.stdout.write(f'  Status: {t.status}')
                if t.borrower:
                    self.stdout.write(f'  Borrower: {t.borrower.get_full_name()}')
                if t.loan:
                    self.stdout.write(f'  Loan: {t.loan.loan_number}')
                if t.repayment:
                    self.stdout.write(f'  Repayment: {t.repayment.receipt_number}')
            else:
                self.stdout.write(self.style.WARNING('✗ NOT LINKED to any transaction'))
                
                # Try to find matching transaction
                if callback.raw_data:
                    trans_id = callback.raw_data.get('TransID')
                    if trans_id:
                        matching = MpesaTransaction.objects.filter(trans_id=trans_id).first()
                        if matching:
                            self.stdout.write(self.style.WARNING(
                                f'  ⚠ Found matching transaction: {matching.id}'
                            ))
                            self.stdout.write('  → Callback should be linked to this transaction')
                        else:
                            self.stdout.write(self.style.ERROR(
                                '  ✗ No matching transaction found in database'
                            ))
                            self.stdout.write('  → Transaction may not have been created from this callback')
            
            # Processing status
            if callback.processed:
                self.stdout.write(self.style.SUCCESS('✓ Processed: Yes'))
            else:
                self.stdout.write(self.style.WARNING('✗ Processed: No'))
            
            # Response sent
            if callback.response_sent:
                result_code = callback.response_sent.get('ResultCode', 'N/A')
                self.stdout.write(f'Response Code: {result_code}')
            
            self.stdout.write('')
        
        # Summary
        self.stdout.write('='*70)
        self.stdout.write('SUMMARY')
        self.stdout.write('='*70)
        
        total = count
        linked = callbacks.filter(transaction__isnull=False).count()
        processed = callbacks.filter(processed=True).count()
        confirmation = callbacks.filter(callback_type='confirmation').count()
        validation = callbacks.filter(callback_type='validation').count()
        
        self.stdout.write(f'Total Callbacks: {total}')
        self.stdout.write(f'  Validation: {validation}')
        self.stdout.write(f'  Confirmation: {confirmation}')
        self.stdout.write(f'Linked to Transaction: {linked}/{total}')
        self.stdout.write(f'Marked as Processed: {processed}/{total}')
        
        unlinked = total - linked
        if unlinked > 0:
            self.stdout.write('\n' + self.style.WARNING(
                f'⚠ {unlinked} callback(s) not linked to transactions'
            ))
            self.stdout.write('\nThis means:')
            self.stdout.write('  • Callback was received but transaction was not created')
            self.stdout.write('  • Or callback processing failed')
            self.stdout.write('\nCheck the callback processing logic in payments/services.py')
        
        unprocessed = total - processed
        if unprocessed > 0:
            self.stdout.write('\n' + self.style.WARNING(
                f'⚠ {unprocessed} callback(s) not marked as processed'
            ))
        
        if linked == total and processed == total:
            self.stdout.write('\n' + self.style.SUCCESS('✓ All callbacks properly processed!'))
        
        self.stdout.write('\n')
