#!/usr/bin/env python
"""
Test script to verify Grazuri loan products are set up correctly
"""
import os
import django

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

from loans.models import LoanProduct
from decimal import Decimal


def test_products_exist():
    """Test that both Grazuri products exist"""
    print("\n" + "=" * 80)
    print("TEST 1: Products Exist")
    print("=" * 80)
    
    biashara = LoanProduct.objects.filter(product_type='biashara').first()
    logbook = LoanProduct.objects.filter(product_type='logbook').first()
    
    if biashara and logbook:
        print("✓ PASS: Both Grazuri products exist")
        print(f"  - Biashara Loan: {biashara.name} (ID: {biashara.id})")
        print(f"  - Log Book Loan: {logbook.name} (ID: {logbook.id})")
        return True
    else:
        print("✗ FAIL: Missing products")
        if not biashara:
            print("  - Biashara Loan not found")
        if not logbook:
            print("  - Log Book Loan not found")
        return False


def test_product_configuration():
    """Test that products have correct configuration"""
    print("\n" + "=" * 80)
    print("TEST 2: Product Configuration")
    print("=" * 80)
    
    biashara = LoanProduct.objects.filter(product_type='biashara').first()
    logbook = LoanProduct.objects.filter(product_type='logbook').first()
    
    if not biashara or not logbook:
        print("✗ FAIL: Products not found")
        return False
    
    all_pass = True
    
    # Test Biashara Loan
    print("\n--- Biashara Loan ---")
    if biashara.grazuri_account_type == 'B':
        print("✓ Account type: B (Business)")
    else:
        print(f"✗ Account type incorrect: {biashara.grazuri_account_type}")
        all_pass = False
    
    if biashara.gl_code == '11002':
        print("✓ GL Code: 11002")
    else:
        print(f"✗ GL Code incorrect: {biashara.gl_code}")
        all_pass = False
    
    if biashara.is_active:
        print("✓ Status: Active")
    else:
        print("✗ Status: Inactive")
        all_pass = False
    
    # Test Log Book Loan
    print("\n--- Log Book Loan ---")
    if logbook.grazuri_account_type == 'P':
        print("✓ Account type: P (Personal)")
    else:
        print(f"✗ Account type incorrect: {logbook.grazuri_account_type}")
        all_pass = False
    
    if logbook.gl_code == '11002':
        print("✓ GL Code: 11002")
    else:
        print(f"✗ GL Code incorrect: {logbook.gl_code}")
        all_pass = False
    
    if logbook.is_active:
        print("✓ Status: Active")
    else:
        print("✗ Status: Inactive")
        all_pass = False
    
    if all_pass:
        print("\n✓ PASS: All configuration correct")
    else:
        print("\n✗ FAIL: Some configuration incorrect")
    
    return all_pass


def test_loan_calculations():
    """Test loan calculations using direct model values"""
    print("\n" + "=" * 80)
    print("TEST 3: Loan Calculations")
    print("=" * 80)
    
    biashara = LoanProduct.objects.filter(product_type='biashara').first()
    logbook = LoanProduct.objects.filter(product_type='logbook').first()
    
    if not biashara or not logbook:
        print("✗ FAIL: Products not found")
        return False
    
    all_pass = True
    
    # Test Biashara Loan
    print("\n--- Biashara Loan Calculation ---")
    test_amount = Decimal('50000.00')
    test_duration = 90  # 3 months
    
    # Calculate using direct model values (not get_interest_rate which uses SystemSetting)
    months = Decimal('3')  # 90 days / 30
    interest = test_amount * (biashara.interest_rate / Decimal('100')) * months
    fee = test_amount * (biashara.processing_fee / Decimal('100'))
    total = test_amount + interest + fee
    
    print(f"Principal: KES {test_amount:,.2f}")
    print(f"Duration: {test_duration} days (3 months)")
    print(f"Interest Rate: {biashara.interest_rate}% monthly")
    print(f"Interest: KES {interest:,.2f}")
    print(f"Processing Fee ({biashara.processing_fee}%): KES {fee:,.2f}")
    print(f"Total: KES {total:,.2f}")
    
    # Verify
    expected_interest = Decimal('22500.00')  # 50000 * 0.15 * 3
    expected_fee = Decimal('2500.00')  # 50000 * 0.05
    expected_total = Decimal('75000.00')  # 50000 + 22500 + 2500
    
    if interest == expected_interest and fee == expected_fee and total == expected_total:
        print("✓ Calculations correct")
    else:
        print("✗ Calculations incorrect")
        print(f"  Expected interest: {expected_interest}, got: {interest}")
        print(f"  Expected fee: {expected_fee}, got: {fee}")
        print(f"  Expected total: {expected_total}, got: {total}")
        all_pass = False
    
    # Test Log Book Loan
    print("\n--- Log Book Loan Calculation ---")
    test_amount = Decimal('100000.00')
    test_duration = 180  # 6 months
    
    months = Decimal('6')  # 180 days / 30
    interest = test_amount * (logbook.interest_rate / Decimal('100')) * months
    fee = test_amount * (logbook.processing_fee / Decimal('100'))
    total = test_amount + interest + fee
    
    print(f"Principal: KES {test_amount:,.2f}")
    print(f"Duration: {test_duration} days (6 months)")
    print(f"Interest Rate: {logbook.interest_rate}% monthly")
    print(f"Interest: KES {interest:,.2f}")
    print(f"Processing Fee ({logbook.processing_fee}%): KES {fee:,.2f}")
    print(f"Total: KES {total:,.2f}")
    
    # Verify
    expected_interest = Decimal('72000.00')  # 100000 * 0.12 * 6
    expected_fee = Decimal('4000.00')  # 100000 * 0.04
    expected_total = Decimal('176000.00')  # 100000 + 72000 + 4000
    
    if interest == expected_interest and fee == expected_fee and total == expected_total:
        print("✓ Calculations correct")
    else:
        print("✗ Calculations incorrect")
        print(f"  Expected interest: {expected_interest}, got: {interest}")
        print(f"  Expected fee: {expected_fee}, got: {fee}")
        print(f"  Expected total: {expected_total}, got: {total}")
        all_pass = False
    
    if all_pass:
        print("\n✓ PASS: All calculations correct")
    else:
        print("\n✗ FAIL: Some calculations incorrect")
    
    return all_pass


def display_product_summary():
    """Display summary of all products"""
    print("\n" + "=" * 80)
    print("PRODUCT SUMMARY")
    print("=" * 80)
    
    all_products = LoanProduct.objects.all().order_by('-is_active', 'name')
    
    print(f"\nTotal Products: {all_products.count()}")
    print(f"Active: {all_products.filter(is_active=True).count()}")
    print(f"Inactive: {all_products.filter(is_active=False).count()}")
    
    print("\n--- Active Grazuri Products ---")
    grazuri = all_products.filter(product_type__in=['biashara', 'logbook'], is_active=True)
    
    for p in grazuri:
        print(f"\n{p.name}")
        print(f"  Type: {p.product_type} ({p.grazuri_account_type})")
        print(f"  GL Code: {p.gl_code}")
        print(f"  Amount: KES {p.min_amount:,.2f} - {p.max_amount:,.2f}")
        print(f"  Interest: {p.interest_rate}% monthly")
        print(f"  Fee: {p.processing_fee}%")
        print(f"  Duration: {p.min_duration}-{p.max_duration} days")
        print(f"  Collateral: {'Yes' if p.requires_collateral else 'No'}")
    
    print("\n--- Legacy Products ---")
    legacy = all_products.exclude(product_type__in=['biashara', 'logbook'])
    
    if legacy.exists():
        for p in legacy:
            status = "ACTIVE" if p.is_active else "INACTIVE"
            print(f"  • {p.name} ({p.product_type}) - {status}")
    else:
        print("  None")


def main():
    """Main test execution"""
    print("\n" + "=" * 80)
    print("GRAZURI LOAN PRODUCTS TEST SUITE")
    print("Haven Grazuri Investment Limited")
    print("=" * 80)
    
    results = []
    
    # Run tests
    results.append(test_products_exist())
    results.append(test_product_configuration())
    results.append(test_loan_calculations())
    
    # Display summary
    display_product_summary()
    
    # Final result
    print("\n" + "=" * 80)
    print("TEST RESULTS")
    print("=" * 80)
    
    total = len(results)
    passed = sum(results)
    failed = total - passed
    
    print(f"\nTotal Tests: {total}")
    print(f"Passed: {passed}")
    print(f"Failed: {failed}")
    
    if failed == 0:
        print("\n✓ ALL TESTS PASSED!")
        print("=" * 80)
        return 0
    else:
        print(f"\n✗ {failed} TEST(S) FAILED")
        print("=" * 80)
        return 1


if __name__ == '__main__':
    exit(main())
