"""
Test script for Loan model updates
"""
import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

from decimal import Decimal
from django.utils import timezone
from datetime import timedelta
import uuid

from loans.models import Loan, LoanProduct, LoanApplication, Repayment
from users.models import CustomUser

def test_loan_model_updates():
    """
    Test the updated Loan model methods:
    1. amount_paid property uses calculation service
    2. outstanding_amount property uses calculation service
    3. is_in_arrears() helper method works correctly
    """
    print("Testing Loan model updates...")
    
    # Create test user
    try:
        user = CustomUser.objects.get(username='testuser_loan_model')
    except CustomUser.DoesNotExist:
        user = CustomUser.objects.create_user(
            username='testuser_loan_model',
            email='test_loan_model@example.com',
            phone_number='+254700000098',
            first_name='Test',
            last_name='User'
        )
    
    # Create test product
    try:
        product = LoanProduct.objects.get(name='Test Product Loan Model')
    except LoanProduct.DoesNotExist:
        product = LoanProduct.objects.create(
            name='Test Product Loan Model',
            product_type='boost',
            description='Test product',
            min_amount=Decimal('1000'),
            max_amount=Decimal('50000'),
            interest_rate=Decimal('10.0'),
            processing_fee=Decimal('5.0'),
            min_duration=7,
            max_duration=90,
            available_repayment_methods=['monthly']
        )
    
    # Test 1: amount_paid property
    print("\nTest 1: amount_paid property uses calculation service")
    
    app = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=Decimal('10000'),
        requested_duration=30,
        purpose='Test',
        status='approved'
    )
    
    loan = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app,
        borrower=user,
        principal_amount=Decimal('10000'),
        interest_amount=Decimal('1000'),
        processing_fee=Decimal('500'),
        total_amount=Decimal('11500'),
        disbursement_date=timezone.now(),
        due_date=timezone.now() + timedelta(days=30),
        duration_days=30,
        status='active'
    )
    
    print(f"  Created loan {loan.loan_number}")
    print(f"  Initial amount_paid: {loan.amount_paid}")
    assert loan.amount_paid == Decimal('0.00'), "Initial amount_paid should be 0"
    
    # Add a repayment
    repayment1 = Repayment.objects.create(
        loan=loan,
        amount=Decimal('5000'),
        payment_method='mpesa',
        receipt_number=f'RCP-{uuid.uuid4().hex[:8]}',
        payment_date=timezone.now()
    )
    
    # Refresh loan
    loan.refresh_from_db()
    print(f"  After first repayment: {loan.amount_paid}")
    assert loan.amount_paid == Decimal('5000'), f"Expected 5000, got {loan.amount_paid}"
    
    # Add another repayment
    repayment2 = Repayment.objects.create(
        loan=loan,
        amount=Decimal('3000'),
        payment_method='mpesa',
        receipt_number=f'RCP-{uuid.uuid4().hex[:8]}',
        payment_date=timezone.now()
    )
    
    # Refresh loan
    loan.refresh_from_db()
    print(f"  After second repayment: {loan.amount_paid}")
    assert loan.amount_paid == Decimal('8000'), f"Expected 8000, got {loan.amount_paid}"
    
    print("  ✓ Test 1 passed: amount_paid property works correctly")
    
    # Test 2: outstanding_amount property
    print("\nTest 2: outstanding_amount property uses calculation service")
    
    outstanding = loan.outstanding_amount
    expected_outstanding = Decimal('11500') - Decimal('8000')  # total - paid
    print(f"  Outstanding amount: {outstanding}")
    print(f"  Expected: {expected_outstanding}")
    assert outstanding == expected_outstanding, f"Expected {expected_outstanding}, got {outstanding}"
    
    print("  ✓ Test 2 passed: outstanding_amount property works correctly")
    
    # Test 3: is_in_arrears() method
    print("\nTest 3: is_in_arrears() helper method")
    
    # Create a loan that's not in arrears (future due date)
    app2 = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=Decimal('10000'),
        requested_duration=30,
        purpose='Test',
        status='approved'
    )
    
    loan_not_overdue = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app2,
        borrower=user,
        principal_amount=Decimal('10000'),
        interest_amount=Decimal('1000'),
        processing_fee=Decimal('500'),
        total_amount=Decimal('11500'),
        disbursement_date=timezone.now(),
        due_date=timezone.now() + timedelta(days=30),  # Future due date
        duration_days=30,
        status='active'
    )
    
    print(f"  Loan with future due date - is_in_arrears(): {loan_not_overdue.is_in_arrears()}")
    assert not loan_not_overdue.is_in_arrears(), "Loan with future due date should not be in arrears"
    
    # Create a loan that IS in arrears (past due date with outstanding balance)
    app3 = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=Decimal('10000'),
        requested_duration=30,
        purpose='Test',
        status='approved'
    )
    
    loan_overdue = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app3,
        borrower=user,
        principal_amount=Decimal('10000'),
        interest_amount=Decimal('1000'),
        processing_fee=Decimal('500'),
        total_amount=Decimal('11500'),
        disbursement_date=timezone.now() - timedelta(days=60),
        due_date=timezone.now() - timedelta(days=30),  # Past due date
        duration_days=30,
        status='active'
    )
    
    print(f"  Loan with past due date - is_in_arrears(): {loan_overdue.is_in_arrears()}")
    assert loan_overdue.is_in_arrears(), "Loan with past due date and outstanding balance should be in arrears"
    
    # Create a fully paid loan (should not be in arrears even if past due)
    app4 = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=Decimal('10000'),
        requested_duration=30,
        purpose='Test',
        status='approved'
    )
    
    loan_paid = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app4,
        borrower=user,
        principal_amount=Decimal('10000'),
        interest_amount=Decimal('1000'),
        processing_fee=Decimal('500'),
        total_amount=Decimal('11500'),
        disbursement_date=timezone.now() - timedelta(days=60),
        due_date=timezone.now() - timedelta(days=30),  # Past due date
        duration_days=30,
        status='paid'
    )
    
    # Add full repayment
    Repayment.objects.create(
        loan=loan_paid,
        amount=Decimal('11500'),
        payment_method='mpesa',
        receipt_number=f'RCP-{uuid.uuid4().hex[:8]}',
        payment_date=timezone.now()
    )
    
    loan_paid.refresh_from_db()
    print(f"  Fully paid loan - is_in_arrears(): {loan_paid.is_in_arrears()}")
    assert not loan_paid.is_in_arrears(), "Fully paid loan should not be in arrears"
    
    print("  ✓ Test 3 passed: is_in_arrears() method works correctly")
    
    print("\n✓ All Loan model update tests passed!")

if __name__ == '__main__':
    test_loan_model_updates()
