
from django.core.management.base import BaseCommand
from django.utils import timezone
from decimal import Decimal
from payments.models import Payment, UnreconciledPayment
from customers.models import Customer
import json


class Command(BaseCommand):
    help = 'Find payments that should be marked as unreconciled'

    def add_arguments(self, parser):
        parser.add_argument(
            '--create-missing',
            action='store_true',
            help='Create unreconciled payment records for payments without valid customers'
        )
        parser.add_argument(
            '--days',
            type=int,
            default=30,
            help='Number of days to look back (default: 30)'
        )

    def handle(self, *args, **options):
        create_missing = options['create_missing']
        days_back = options['days']
        
        # Get date range
        end_date = timezone.now()
        start_date = end_date - timezone.timedelta(days=days_back)
        
        self.stdout.write(f"Checking payments from {start_date.date()} to {end_date.date()}")
        
        # Find M-Pesa payments that might be unreconciled
        problematic_payments = []
        
        # 1. Check for payments with invalid customer references
        mpesa_payments = Payment.objects.filter(
            payment_method='mpesa',
            created_at__gte=start_date,
            created_at__lte=end_date
        )
        
        for payment in mpesa_payments:
            issues = []
            
            # Check if payment has no customer and no invoice
            if not payment.customer and not payment.invoice:
                issues.append("No customer or invoice linked")
            
            # Check if payment has a customer but customer doesn't exist or is invalid
            if payment.customer:
                try:
                    customer = payment.customer
                    if not customer.customer_id:
                        issues.append("Customer has no customer_id")
                except:
                    issues.append("Customer relationship broken")
            
            # Check if invoice customer exists
            if payment.invoice and payment.invoice.customer:
                try:
                    customer = payment.invoice.customer
                    if not customer.customer_id:
                        issues.append("Invoice customer has no customer_id")
                except:
                    issues.append("Invoice customer relationship broken")
            
            # Check callback data for account reference issues
            if payment.mpesa_callback_data:
                try:
                    callback_data = payment.mpesa_callback_data
                    if isinstance(callback_data, str):
                        callback_data = json.loads(callback_data)
                    
                    # Extract account reference if available
                    account_ref = None
                    if 'BillRefNumber' in callback_data:
                        account_ref = callback_data['BillRefNumber']
                    
                    if account_ref:
                        # Check if customer with this ID exists
                        try:
                            Customer.objects.get(customer_id=account_ref)
                        except Customer.DoesNotExist:
                            issues.append(f"Account reference '{account_ref}' not found")
                
                except Exception as e:
                    issues.append(f"Error parsing callback data: {e}")
            
            if issues:
                problematic_payments.append({
                    'payment': payment,
                    'issues': issues
                })
        
        # 2. Check for existing unreconciled payments that might have been missed
        existing_unreconciled = UnreconciledPayment.objects.filter(
            created_at__gte=start_date,
            created_at__lte=end_date
        ).count()
        
        self.stdout.write(f"\nFound {len(problematic_payments)} potentially unreconciled payments")
        self.stdout.write(f"Existing unreconciled payment records: {existing_unreconciled}")
        
        for item in problematic_payments:
            payment = item['payment']
            issues = item['issues']
            
            self.stdout.write(f"\nPayment ID: {payment.payment_id}")
            self.stdout.write(f"Amount: KES {payment.amount}")
            self.stdout.write(f"Date: {payment.created_at}")
            self.stdout.write(f"Receipt: {payment.mpesa_receipt_number}")
            self.stdout.write(f"Issues: {', '.join(issues)}")
            
            if create_missing:
                # Check if unreconciled payment already exists
                existing = UnreconciledPayment.objects.filter(
                    transaction_id=payment.mpesa_receipt_number
                ).first()
                
                if not existing and payment.mpesa_receipt_number:
                    # Create unreconciled payment record
                    account_ref = "UNKNOWN"
                    phone = payment.mpesa_phone_number or ""
                    
                    # Try to extract from callback data
                    if payment.mpesa_callback_data:
                        try:
                            callback_data = payment.mpesa_callback_data
                            if isinstance(callback_data, str):
                                callback_data = json.loads(callback_data)
                            
                            if 'BillRefNumber' in callback_data:
                                account_ref = callback_data['BillRefNumber']
                            if 'MSISDN' in callback_data:
                                phone = callback_data['MSISDN']
                        except:
                            pass
                    
                    unreconciled = UnreconciledPayment.objects.create(
                        transaction_id=payment.mpesa_receipt_number,
                        phone_number=phone,
                        amount=payment.amount,
                        account_reference=account_ref,
                        transaction_time=payment.completed_at or payment.created_at,
                        reason='system_error',
                        notes=f"Auto-created from existing payment. Issues: {', '.join(issues)}",
                        callback_data=payment.mpesa_callback_data
                    )
                    
                    self.stdout.write(f"  → Created unreconciled payment record: {unreconciled.id}")
                else:
                    if existing:
                        self.stdout.write(f"  → Unreconciled payment already exists: {existing.id}")
                    else:
                        self.stdout.write("  → No receipt number, cannot create unreconciled record")
        
        if not create_missing:
            self.stdout.write(f"\nTo create unreconciled payment records, run with --create-missing")
        
        self.stdout.write(f"\nDone!")
