from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase
from rest_framework import status
from organisations.models import Organisation, OrganisationBranch
from customers.models import Customer
from users.models import Staff
from ledgers.models import OrganisationSubAccount
from .models import (
    ExternalLoanProduct, ExternalLoanSector, ExternalLoanApplication,
    ExternalLoanApproval, ExternalLoanDisbursement, ExternalLoanSettings
)

User = get_user_model()

class ExternalLoanModelTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        self.organisation = Organisation.objects.create(
            name='Test Organisation',
            short_name='TEST'
        )
        
    def test_external_loan_product_creation(self):
        """Test external loan product creation"""
        product = ExternalLoanProduct.objects.create(
            product_name='Test External Loan',
            int_rate=12.5,
            int_method='declining',
            loan_period=12,
            period_type='m',
            max_loan_amt=100000,
            min_loan_amt=10000,
            organisation=self.organisation,
            added_by=self.user
        )
        self.assertEqual(product.product_name, 'Test External Loan')
        self.assertEqual(product.int_rate, 12.5)
        self.assertTrue(product.is_active)
        
    def test_external_loan_sector_creation(self):
        """Test external loan sector creation"""
        sector = ExternalLoanSector.objects.create(
            name='Agriculture',
            description='Agricultural loans',
            organisation=self.organisation,
            added_by=self.user
        )
        self.assertEqual(sector.name, 'Agriculture')
        self.assertTrue(sector.is_active)

class ExternalLoanAPITests(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        self.organisation = Organisation.objects.create(
            name='Test Organisation',
            short_name='TEST'
        )
        self.client.force_authenticate(user=self.user)
        
    def test_external_loan_product_list(self):
        """Test external loan product list endpoint"""
        response = self.client.get('/api/external-loans/products/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
    def test_external_loan_application_list(self):
        """Test external loan application list endpoint"""
        response = self.client.get('/api/external-loans/applications/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
    def test_external_loan_dashboard(self):
        """Test external loan dashboard endpoint"""
        response = self.client.get('/api/external-loans/dashboard/')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('summary', response.data)
        
    def test_external_loan_calculator(self):
        """Test external loan calculator endpoint"""
        data = {
            'loan_amount': 50000,
            'interest_rate': 12.5,
            'loan_period': 12,
            'interest_method': 'declining'
        }
        response = self.client.post('/api/external-loans/calculator/', data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('total_interest', response.data)
        self.assertIn('monthly_payment', response.data)

class ExternalLoanHelperTests(TestCase):
    def test_loan_calculation_flat(self):
        """Test flat interest calculation"""
        from .helper import calculate_external_loan_schedule
        
        schedule = calculate_external_loan_schedule(
            loan_amount=100000,
            interest_rate=12,
            loan_period=12,
            interest_method='flat'
        )
        
        self.assertEqual(len(schedule), 12)
        self.assertEqual(schedule[0]['payment_number'], 1)
        self.assertGreater(schedule[0]['total_payment'], 0)
        
    def test_loan_calculation_declining(self):
        """Test declining balance calculation"""
        from .helper import calculate_external_loan_schedule
        
        schedule = calculate_external_loan_schedule(
            loan_amount=100000,
            interest_rate=12,
            loan_period=12,
            interest_method='declining'
        )
        
        self.assertEqual(len(schedule), 12)
        self.assertEqual(schedule[0]['payment_number'], 1)
        self.assertGreater(schedule[0]['total_payment'], 0)
        # In declining balance, early payments have more interest
        self.assertGreater(schedule[0]['interest_payment'], schedule[-1]['interest_payment'])
        
    def test_application_validation(self):
        """Test external loan application validation"""
        from .helper import validate_external_loan_application
        
        # Test missing required fields
        errors = validate_external_loan_application({})
        self.assertGreater(len(errors), 0)
        
        # Test invalid loan amount
        errors = validate_external_loan_application({
            'loan_amount': 0,
            'loan_purpose': 'Test',
            'customer': 1,
            'external_loan_product': 1
        })
        self.assertIn('Loan amount must be greater than 0', errors)