"""
Simple test for deleted loans page exclusivity property
"""

from django.test import TestCase
from django.utils import timezone
from datetime import timedelta
from decimal import Decimal

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


class TestDeletedLoansPageExclusivity(TestCase):
    """Test for deleted loans page exclusivity property"""
    
    def setUp(self):
        """Set up test data"""
        # Create test user
        self.user = CustomUser.objects.create_user(
            username='testuser',
            email='test@example.com',
            phone_number='+254700000000',
            first_name='Test',
            last_name='User',
            role='borrower'
        )
        
        # Create test loan product
        self.product = LoanProduct.objects.create(
            name='Test Product',
            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']
        )
    
    def create_loan(self, is_deleted=False, status='active'):
        """Helper to create a loan with specified properties"""
        # Create application
        application = LoanApplication.objects.create(
            borrower=self.user,
            loan_product=self.product,
            requested_amount=Decimal('10000'),
            requested_duration=30,
            purpose='Test loan',
            status='approved'
        )
        
        # Create loan
        loan = Loan.objects.create(
            application=application,
            borrower=self.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=status,
            is_deleted=is_deleted
        )
        
        return loan
    
    def test_property_15_deleted_loans_page_exclusivity(self):
        """
        Feature: reports-system-enhancement, Property 15: Deleted loans page exclusivity
        Validates: Requirements 5.5
        
        For any loan displayed on the deleted loans page, it should have is_deleted flag
        equal to true, and no loans with is_deleted equal to false should appear.
        """
        print("\n" + "="*80)
        print("TEST: Property 15 - Deleted Loans Page Exclusivity")
        print("="*80)
        
        # Create 4 deleted loans (should appear on deleted loans page)
        deleted_loans = []
        for i in range(4):
            loan = self.create_loan(is_deleted=True, status='active')
            deleted_loans.append(loan)
            print(f"  Created deleted loan: {loan.loan_number} (is_deleted=True)")
        
        # Create 3 active loans (should NOT appear on deleted loans page)
        active_loans = []
        for i in range(3):
            loan = self.create_loan(is_deleted=False, status='active')
            active_loans.append(loan)
            print(f"  Created active loan: {loan.loan_number} (is_deleted=False)")
        
        # Create 2 paid loans (should NOT appear on deleted loans page)
        paid_loans = []
        for i in range(2):
            loan = self.create_loan(is_deleted=False, status='paid')
            paid_loans.append(loan)
            print(f"  Created paid loan: {loan.loan_number} (is_deleted=False)")
        
        # Create 1 rolled-over loan (should NOT appear on deleted loans page)
        rolled_over_loan = self.create_loan(is_deleted=False, status='rolled_over')
        print(f"  Created rolled-over loan: {rolled_over_loan.loan_number} (is_deleted=False)")
        
        print(f"\nTotal loans created: {Loan.objects.count()}")
        print(f"  - Deleted: {len(deleted_loans)}")
        print(f"  - Active: {len(active_loans)}")
        print(f"  - Paid: {len(paid_loans)}")
        print(f"  - Rolled-over: 1")
        
        # Query for deleted loans (simulating the deleted_loans view logic)
        print("\n🔍 Querying for deleted loans (is_deleted=True)...")
        queryset = Loan.objects.filter(is_deleted=True)
        
        print(f"  Found {queryset.count()} deleted loans")
        
        # Property 1: All returned loans should have is_deleted=True
        print("\n✓ Property 1: All returned loans should have is_deleted=True")
        for loan in queryset:
            self.assertTrue(
                loan.is_deleted,
                f"Loan {loan.loan_number} appears in deleted loans page but is_deleted={loan.is_deleted}"
            )
            print(f"  ✓ Loan {loan.loan_number}: is_deleted={loan.is_deleted}")
        
        # Property 2: All deleted loans should be in the result
        print("\n✓ Property 2: All deleted loans should be in the result")
        self.assertEqual(
            queryset.count(),
            4,
            f"Expected 4 deleted loans, got {queryset.count()}"
        )
        print(f"  ✓ Count matches: {queryset.count()} == 4")
        
        # Property 3: No active loans should appear
        print("\n✓ Property 3: No active loans should appear")
        for loan in active_loans:
            self.assertNotIn(
                loan,
                queryset,
                f"Active loan {loan.loan_number} should not appear in deleted loans page"
            )
        print(f"  ✓ No active loans in results")
        
        # Property 4: No paid loans should appear
        print("\n✓ Property 4: No paid loans should appear")
        for loan in paid_loans:
            self.assertNotIn(
                loan,
                queryset,
                f"Paid loan {loan.loan_number} should not appear in deleted loans page"
            )
        print(f"  ✓ No paid loans in results")
        
        # Property 5: No rolled-over loans should appear
        print("\n✓ Property 5: No rolled-over loans should appear")
        self.assertNotIn(
            rolled_over_loan,
            queryset,
            f"Rolled-over loan {rolled_over_loan.loan_number} should not appear in deleted loans page"
        )
        print(f"  ✓ No rolled-over loans in results")
        
        # Property 6: Verify inverse - active loans page should not show deleted loans
        print("\n✓ Property 6: Active loans should not include deleted loans")
        active_queryset = Loan.objects.filter(is_deleted=False)
        print(f"  Active loans count: {active_queryset.count()}")
        
        for loan in deleted_loans:
            self.assertNotIn(
                loan,
                active_queryset,
                f"Deleted loan {loan.loan_number} should not appear in active loans"
            )
        print(f"  ✓ No deleted loans in active results")
        
        print("\n" + "="*80)
        print("✅ ALL PROPERTY TESTS PASSED")
        print("="*80)
        print("Summary:")
        print(f"  ✓ Deleted loans page shows ONLY deleted loans (is_deleted=True)")
        print(f"  ✓ All {len(deleted_loans)} deleted loans are included")
        print(f"  ✓ No active, paid, or rolled-over loans appear")
        print(f"  ✓ Active loans page excludes deleted loans")
        print("="*80 + "\n")
