#!/usr/bin/env python
"""
Test script to verify registration fees calculation and fix any issues
"""
import os
import sys
import django

# Setup Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

from django.utils import timezone
from django.db.models import Sum, Count
from users.models import CustomUser
from reports.enhanced_models import RegistrationFeePayment
from reports.comprehensive_reports import ComprehensiveReportsService
from datetime import datetime, timedelta

def test_registration_fees():
    """Test and debug registration fees calculation"""
    
    print("=== Registration Fees Analysis ===\n")
    
    # Initialize the reports service
    reports_service = ComprehensiveReportsService()
    
    # 1. Check CustomUser registration fees
    print("1. Checking CustomUser registration fees...")
    
    all_users_with_fees = CustomUser.objects.filter(
        role='borrower',
        registration_fee_amount__gt=0
    ).exclude(registration_fee_amount__isnull=True)
    
    print(f"   Total users with registration fee amount set: {all_users_with_fees.count()}")
    
    paid_users = all_users_with_fees.filter(registration_fee_paid=True)
    print(f"   Users who have paid registration fees: {paid_users.count()}")
    
    unpaid_users = all_users_with_fees.filter(registration_fee_paid=False)
    print(f"   Users with unpaid registration fees: {unpaid_users.count()}")
    
    # Show some examples
    if paid_users.exists():
        print("\n   Sample paid users:")
        for user in paid_users[:5]:
            print(f"     - {user.get_full_name()}: KES {user.registration_fee_amount} "
                  f"(Paid: {user.registration_fee_payment_date or 'Date not set'})")
    
    if unpaid_users.exists():
        print("\n   Sample unpaid users:")
        for user in unpaid_users[:5]:
            print(f"     - {user.get_full_name()}: KES {user.registration_fee_amount} (Unpaid)")
    
    # 2. Check RegistrationFeePayment model
    print("\n2. Checking RegistrationFeePayment model...")
    
    try:
        fee_payments = RegistrationFeePayment.objects.all()
        print(f"   Total registration fee payment records: {fee_payments.count()}")
        
        if fee_payments.exists():
            total_from_payments = fee_payments.aggregate(total=Sum('amount_paid'))['total'] or 0
            print(f"   Total amount from payment records: KES {total_from_payments:,.2f}")
            
            print("\n   Sample payment records:")
            for payment in fee_payments[:5]:
                print(f"     - {payment.customer.get_full_name()}: KES {payment.amount_paid} "
                      f"on {payment.payment_date}")
    except Exception as e:
        print(f"   Error accessing RegistrationFeePayment: {e}")
    
    # 3. Test current month calculation
    print("\n3. Testing current month registration fees calculation...")
    
    current_month_report = reports_service.get_registration_fees_report()
    print(f"   Current month total income: KES {current_month_report['summary']['total_registration_income']:,.2f}")
    print(f"   Current month total registrations: {current_month_report['summary']['total_registrations']}")
    print(f"   Current month average fee: KES {current_month_report['summary']['average_registration_fee']:,.2f}")
    
    # 4. Test all-time calculation
    print("\n4. Testing all-time registration fees calculation...")
    
    # Get all-time data by using a very early start date
    all_time_report = reports_service.get_registration_fees_report(
        start_date=datetime(2020, 1, 1).date(),
        end_date=timezone.now().date()
    )
    print(f"   All-time total income: KES {all_time_report['summary']['total_registration_income']:,.2f}")
    print(f"   All-time total registrations: {all_time_report['summary']['total_registrations']}")
    print(f"   All-time average fee: KES {all_time_report['summary']['average_registration_fee']:,.2f}")
    
    # 5. Show detailed breakdown
    print("\n5. Detailed breakdown of fees found:")
    if all_time_report.get('fees'):
        print(f"   Found {len(all_time_report['fees'])} fee records:")
        for i, fee in enumerate(all_time_report['fees'][:10]):  # Show first 10
            print(f"     {i+1}. {fee['customer_name']}: KES {fee['amount']} "
                  f"({fee['source']}) - {fee['payment_date']}")
        if len(all_time_report['fees']) > 10:
            print(f"     ... and {len(all_time_report['fees']) - 10} more")
    else:
        print("   No fee records found in the report")
    
    # 6. Manual calculation for verification
    print("\n6. Manual verification calculation...")
    
    # Calculate from CustomUser directly
    user_total = CustomUser.objects.filter(
        role='borrower',
        registration_fee_paid=True,
        registration_fee_amount__gt=0
    ).aggregate(total=Sum('registration_fee_amount'))['total'] or 0
    
    user_count = CustomUser.objects.filter(
        role='borrower',
        registration_fee_paid=True,
        registration_fee_amount__gt=0
    ).count()
    
    print(f"   Direct CustomUser calculation: KES {user_total:,.2f} from {user_count} users")
    
    # Calculate from RegistrationFeePayment directly
    try:
        payment_total = RegistrationFeePayment.objects.aggregate(total=Sum('amount_paid'))['total'] or 0
        payment_count = RegistrationFeePayment.objects.count()
        print(f"   Direct RegistrationFeePayment calculation: KES {payment_total:,.2f} from {payment_count} payments")
        
        combined_total = user_total + payment_total
        combined_count = user_count + payment_count
        print(f"   Combined total: KES {combined_total:,.2f} from {combined_count} records")
    except Exception as e:
        print(f"   Error calculating from RegistrationFeePayment: {e}")
        combined_total = user_total
        combined_count = user_count
        print(f"   Using only CustomUser data: KES {combined_total:,.2f} from {combined_count} records")
    
    # 7. Recommendations
    print("\n7. Recommendations:")
    
    if combined_total == 0:
        print("   ❌ No registration fees found. Possible issues:")
        print("      - No clients have registration_fee_paid=True")
        print("      - No clients have registration_fee_amount > 0")
        print("      - Date filtering is too restrictive")
        print("      - Database connection issues")
        
        # Check if there are any users at all
        total_users = CustomUser.objects.filter(role='borrower').count()
        print(f"      - Total borrower users in system: {total_users}")
        
        if total_users > 0:
            users_with_amounts = CustomUser.objects.filter(
                role='borrower',
                registration_fee_amount__gt=0
            ).count()
            print(f"      - Users with registration fee amounts: {users_with_amounts}")
            
            if users_with_amounts > 0:
                print("      ✅ Solution: Update users to mark registration fees as paid")
                print("         You can do this in the admin panel or client update forms")
            else:
                print("      ✅ Solution: Set registration fee amounts for clients")
                print("         Add registration fee amounts when creating/updating clients")
    else:
        print("   ✅ Registration fees are being calculated correctly!")
        print(f"      - Total income: KES {combined_total:,.2f}")
        print(f"      - Total records: {combined_count}")
        
        if current_month_report['summary']['total_registration_income'] == 0:
            print("   ⚠️  Current month shows 0 - this might be due to:")
            print("      - No fees paid in current month")
            print("      - Payment dates not set correctly")
            print("      - Date filtering logic needs adjustment")

def fix_registration_fee_dates():
    """Fix missing payment dates for paid registration fees"""
    
    print("\n=== Fixing Registration Fee Payment Dates ===\n")
    
    # Find users with paid fees but no payment date
    users_needing_dates = CustomUser.objects.filter(
        role='borrower',
        registration_fee_paid=True,
        registration_fee_amount__gt=0,
        registration_fee_payment_date__isnull=True
    )
    
    print(f"Found {users_needing_dates.count()} users with paid fees but no payment date")
    
    if users_needing_dates.exists():
        print("Fixing payment dates (using created_at as fallback)...")
        
        updated_count = 0
        for user in users_needing_dates:
            user.registration_fee_payment_date = user.created_at
            user.save(update_fields=['registration_fee_payment_date'])
            updated_count += 1
            
            if updated_count <= 5:  # Show first 5 examples
                print(f"  - {user.get_full_name()}: Set payment date to {user.created_at}")
        
        print(f"\n✅ Updated {updated_count} users with payment dates")
    else:
        print("✅ All paid registration fees already have payment dates")

if __name__ == "__main__":
    test_registration_fees()
    
    # Ask if user wants to fix missing dates
    if len(sys.argv) > 1 and sys.argv[1] == '--fix-dates':
        fix_registration_fee_dates()
        print("\n=== Re-testing after fixes ===")
        test_registration_fees()