"""
Simple test script for rollover state transition property
"""
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
from users.models import CustomUser

def test_rollover_state_transition():
    """
    Test Property 13: Rollover state transition
    
    For any loan that undergoes rollover, the original loan should have status
    set to 'rolled_over' AND is_rolled_over flag set to true.
    """
    print("Testing rollover state transition property...")
    
    # Create test user
    try:
        user = CustomUser.objects.get(username='testuser_rollover_simple')
    except CustomUser.DoesNotExist:
        user = CustomUser.objects.create_user(
            username='testuser_rollover_simple',
            email='test_rollover_simple@example.com',
            phone_number='+254700000099',
            first_name='Test',
            last_name='User'
        )
    
    # Create test product
    try:
        product = LoanProduct.objects.get(name='Test Product Rollover Simple')
    except LoanProduct.DoesNotExist:
        product = LoanProduct.objects.create(
            name='Test Product Rollover Simple',
            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'],
            rollover_fee_percentage=Decimal('5.0'),
            max_rollover_count=3,
            max_rollover_days=30
        )
    
    # Test case 1: Rollover sets both status and flag
    print("\nTest 1: Rollover sets both status and flag")
    principal_amount = Decimal('10000')
    duration_days = 30
    
    app = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=principal_amount,
        requested_duration=duration_days,
        purpose='Test',
        status='approved'
    )
    
    interest_amount = principal_amount * Decimal('0.10')
    processing_fee = principal_amount * Decimal('0.05')
    total_amount = principal_amount + interest_amount + processing_fee
    
    original_loan = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app,
        borrower=user,
        principal_amount=principal_amount,
        interest_amount=interest_amount,
        processing_fee=processing_fee,
        total_amount=total_amount,
        disbursement_date=timezone.now(),
        due_date=timezone.now() + timedelta(days=duration_days),
        duration_days=duration_days,
        status='active',
        is_rolled_over=False
    )
    
    print(f"  Created loan {original_loan.loan_number}")
    print(f"  Initial status: {original_loan.status}, is_rolled_over: {original_loan.is_rolled_over}")
    
    # Simulate rollover
    original_loan.status = 'rolled_over'
    original_loan.is_rolled_over = True
    original_loan.save()
    
    # Refresh from database
    original_loan.refresh_from_db()
    
    print(f"  After rollover status: {original_loan.status}, is_rolled_over: {original_loan.is_rolled_over}")
    
    # Verify
    assert original_loan.status == 'rolled_over', \
        f"Expected status='rolled_over', got '{original_loan.status}'"
    assert original_loan.is_rolled_over is True, \
        f"Expected is_rolled_over=True, got {original_loan.is_rolled_over}"
    
    print("  ✓ Test 1 passed: Both status and flag are set correctly")
    
    # Test case 2: Cannot set rolled over loan back to active
    print("\nTest 2: Cannot set rolled over loan back to active")
    
    app2 = LoanApplication.objects.create(
        application_number=f'APP-{uuid.uuid4().hex[:6]}',
        borrower=user,
        loan_product=product,
        requested_amount=principal_amount,
        requested_duration=duration_days,
        purpose='Test',
        status='approved'
    )
    
    loan2 = Loan.objects.create(
        loan_number=f'LOAN-{uuid.uuid4().hex[:6]}',
        application=app2,
        borrower=user,
        principal_amount=principal_amount,
        interest_amount=interest_amount,
        processing_fee=processing_fee,
        total_amount=total_amount,
        disbursement_date=timezone.now(),
        due_date=timezone.now() + timedelta(days=duration_days),
        duration_days=duration_days,
        status='rolled_over',
        is_rolled_over=True
    )
    
    print(f"  Created rolled over loan {loan2.loan_number}")
    
    # Try to set status back to active (should fail)
    loan2.status = 'active'
    
    try:
        loan2.save()
        print("  ✗ Test 2 failed: Should have raised ValueError")
        assert False, "Should have raised ValueError"
    except ValueError as e:
        if 'rolled over loan cannot be set back to active' in str(e).lower():
            print(f"  ✓ Test 2 passed: Correctly prevented setting rolled over loan to active")
        else:
            print(f"  ✗ Test 2 failed: Wrong error message: {e}")
            raise
    
    # Cleanup
    print("\nCleaning up test data...")
    original_loan.delete()
    app.delete()
    loan2.delete()
    app2.delete()
    
    print("\n✓ All rollover state transition tests passed!")

if __name__ == '__main__':
    test_rollover_state_transition()
