from django.test import TestCase
from django.contrib.auth.models import User
from datetime import date, timedelta
from accounts.models import Employee
from .models import LeaveRequest

class LeaveRequestTests(TestCase):
    def setUp(self):
        # Create test user and employee
        self.user = User.objects.create_user(
            username='employee1',
            password='testpass123',
            first_name='John',
            last_name='Doe'
        )
        self.employee = Employee.objects.create(
            user=self.user,
            role='EMP',
            basic_pay=5000.00,
            annual_leave_days=24,
            accumulated_leave_days=20
        )
        
        # Create test leave request
        self.start_date = date(2025, 3, 20)
        self.end_date = date(2025, 3, 25)
        self.leave_request = LeaveRequest.objects.create(
            employee=self.employee,
            leave_type='ANN',
            start_date=self.start_date,
            end_date=self.end_date,
            reason='Family vacation'
        )

    def test_leave_request_creation(self):
        """Test that leave request can be created with correct attributes"""
        self.assertEqual(self.leave_request.employee, self.employee)
        self.assertEqual(self.leave_request.leave_type, 'ANN')
        self.assertEqual(self.leave_request.status, 'PENDING')
        self.assertEqual(self.leave_request.start_date, self.start_date)
        self.assertEqual(self.leave_request.end_date, self.end_date)

    def test_leave_days_calculation(self):
        """Test leave days calculation"""
        # Should be 6 days (inclusive of start and end dates)
        self.assertEqual(self.leave_request.calculate_days(), 6)
        
        # Test single day leave
        single_day = date(2025, 4, 1)
        single_leave = LeaveRequest.objects.create(
            employee=self.employee,
            leave_type='SICK',
            start_date=single_day,
            end_date=single_day,
            reason='Doctor appointment'
        )
        self.assertEqual(single_leave.calculate_days(), 1)

    def test_leave_types(self):
        """Test different types of leave requests"""
        leave_types = {
            'ANN': 'Annual Leave',
            'SICK': 'Sick Leave',
            'EMER': 'Emergency Leave'
        }
        
        for type_code, type_name in leave_types.items():
            leave = LeaveRequest.objects.create(
                employee=self.employee,
                leave_type=type_code,
                start_date=date(2025, 5, 1),
                end_date=date(2025, 5, 2),
                reason=f'Testing {type_name}'
            )
            self.assertEqual(leave.get_leave_type_display(), type_name)

    def test_leave_workflow(self):
        """Test leave request workflow states"""
        workflow_states = [
            'PENDING',
            'HR_APPROVED',
            'REG_APPROVED',
            'HR_REJECTED',
            'REG_REJECTED'
        ]
        
        for state in workflow_states:
            self.leave_request.status = state
            self.leave_request.save()
            self.assertEqual(self.leave_request.status, state)

    def test_overlapping_leave_requests(self):
        """Test creation of overlapping leave requests"""
        # Create an overlapping leave request
        overlapping_leave = LeaveRequest.objects.create(
            employee=self.employee,
            leave_type='ANN',
            start_date=date(2025, 3, 23),  # Overlaps with existing request
            end_date=date(2025, 3, 27),
            reason='Overlapping leave'
        )
        
        # Both requests should exist (business logic for preventing overlaps
        # should be implemented in forms/views, not in the model)
        self.assertTrue(LeaveRequest.objects.filter(id=self.leave_request.id).exists())
        self.assertTrue(LeaveRequest.objects.filter(id=overlapping_leave.id).exists())
