from django.test import TestCase
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils import timezone
from datetime import timedelta, date

from .models import Company, CostCenter, EmployeeProfile, VacationRequest
from .utils import calculate_vacation_balance

class VacationSystemTestCase(TestCase):
    def setUp(self):
        """Set up test data"""
        # Create company
        self.company = Company.objects.create(
            name="Kuttner Test",
            cnpj="12.345.678/0001-90",
            address="Test Address",
            is_active=True
        )
        
        # Create cost center
        self.cost_center = CostCenter.objects.create(
            company=self.company,
            code="CC001",
            name="Test Department",
            is_active=True
        )
        
        # Create users and profiles
        # Admin user
        self.admin_user = User.objects.create_user(
            username="admin",
            email="admin@kuttner.com.br",
            password="adminpass",
            first_name="Admin",
            last_name="User"
        )
        self.admin_profile = EmployeeProfile.objects.create(
            user=self.admin_user,
            role=EmployeeProfile.USER_ROLE_ADMIN,
            company=self.company,
            cost_center=self.cost_center,
            employee_id="ADM001",
            hire_date=timezone.now().date() - timedelta(days=500),
            is_active=True
        )
        
        # Manager user
        self.manager_user = User.objects.create_user(
            username="manager",
            email="manager@kuttner.com.br",
            password="managerpass",
            first_name="Manager",
            last_name="User"
        )
        self.manager_profile = EmployeeProfile.objects.create(
            user=self.manager_user,
            role=EmployeeProfile.USER_ROLE_MANAGER,
            company=self.company,
            cost_center=self.cost_center,
            employee_id="MGR001",
            hire_date=timezone.now().date() - timedelta(days=400),
            is_active=True
        )
        
        # Employee user
        self.employee_user = User.objects.create_user(
            username="employee",
            email="employee@kuttner.com.br",
            password="employeepass",
            first_name="Employee",
            last_name="User"
        )
        self.employee_profile = EmployeeProfile.objects.create(
            user=self.employee_user,
            role=EmployeeProfile.USER_ROLE_EMPLOYEE,
            company=self.company,
            cost_center=self.cost_center,
            employee_id="EMP001",
            hire_date=timezone.now().date() - timedelta(days=450),
            is_active=True
        )
        
    def test_user_roles_redirect(self):
        """Test that users are redirected to the correct dashboard"""
        # Admin login and redirect
        self.client.login(username="admin", password="adminpass")
        response = self.client.get(reverse('dashboard'))
        self.assertRedirects(response, reverse('admin_dashboard'))
        self.client.logout()
        
        # Manager login and redirect
        self.client.login(username="manager", password="managerpass")
        response = self.client.get(reverse('dashboard'))
        self.assertRedirects(response, reverse('manager_dashboard'))
        self.client.logout()
        
        # Employee login and redirect
        self.client.login(username="employee", password="employeepass")
        response = self.client.get(reverse('dashboard'))
        self.assertRedirects(response, reverse('employee_dashboard'))
        self.client.logout()
    
    def test_vacation_calculation(self):
        """Test vacation balance calculation"""
        # More than 1 year of work = 30 days
        balance = calculate_vacation_balance(self.employee_profile)
        self.assertEqual(balance, 30)
        
        # Create an approved vacation request
        start_date = timezone.now().date() + timedelta(days=40)
        end_date = start_date + timedelta(days=14)
        
        VacationRequest.objects.create(
            employee=self.employee_profile,
            start_date=start_date,
            end_date=end_date,
            status=VacationRequest.STATUS_APPROVED,
            selling_days=5
        )
        
        # Balance should be reduced by 15 days (vacation) + 5 days (sold) = 20 days
        new_balance = calculate_vacation_balance(self.employee_profile)
        self.assertEqual(new_balance, 10)
    
    def test_request_vacation(self):
        """Test creating a vacation request"""
        self.client.login(username="employee", password="employeepass")
        
        start_date = (timezone.now().date() + timedelta(days=40)).isoformat()
        end_date = (timezone.now().date() + timedelta(days=50)).isoformat()
        
        response = self.client.post(reverse('request_vacation'), {
            'start_date': start_date,
            'end_date': end_date,
            'selling_days': 3
        })
        
        # Should redirect to dashboard after successful request
        self.assertRedirects(response, reverse('employee_dashboard'))
        
        # Verify request was created
        self.assertEqual(VacationRequest.objects.count(), 1)
        vacation = VacationRequest.objects.first()
        self.assertEqual(vacation.employee, self.employee_profile)
        self.assertEqual(vacation.status, VacationRequest.STATUS_PENDING)
        self.assertEqual(vacation.selling_days, 3)
    
    def test_approve_vacation(self):
        """Test approving a vacation request"""
        # Create a pending vacation request
        vacation = VacationRequest.objects.create(
            employee=self.employee_profile,
            start_date=timezone.now().date() + timedelta(days=40),
            end_date=timezone.now().date() + timedelta(days=50),
            status=VacationRequest.STATUS_PENDING,
            selling_days=0
        )
        
        # Login as manager
        self.client.login(username="manager", password="managerpass")
        
        # Approve request
        response = self.client.post(reverse('review_request', args=[vacation.id]), {
            'action': 'approve'
        })
        
        # Should redirect to dashboard
        self.assertRedirects(response, reverse('manager_dashboard'))
        
        # Verify request was approved
        vacation.refresh_from_db()
        self.assertEqual(vacation.status, VacationRequest.STATUS_APPROVED)
        self.assertEqual(vacation.approved_by, self.manager_profile)
