from django.utils import timezone
from datetime import timedelta, date
from dateutil.relativedelta import relativedelta

def calculate_vacation_balance(employee):
    """
    Calcula o saldo de férias considerando até 3 anos anteriores (36 meses),
    com base na data de admissão do colaborador.
    """
    from .models import VacationRequest
    from django.utils import timezone
    from datetime import date
    from dateutil.relativedelta import relativedelta

    # Se o colaborador está inativo, retorna saldo 0
    if not employee.is_active:
        return 0

    today = timezone.now().date()
    hire_date = employee.hire_date

    # Calcula anos completos de vínculo
    completed_years = (today.year - hire_date.year) - ((today.month, today.day) < (hire_date.month, hire_date.day))

    # Considera até no máximo os últimos 3 anos (36 meses)
    max_years_to_consider = min(completed_years, 3)
    balance = 30 * max_years_to_consider

    # Busca férias aprovadas nos últimos 36 meses
    cutoff_date = today - relativedelta(years=3)

    taken_vacations = VacationRequest.objects.filter(
        employee=employee,
        status=VacationRequest.STATUS_APPROVED,
        start_date__gte=cutoff_date
    )

    for vacation in taken_vacations:
        vacation_days = (vacation.end_date - vacation.start_date).days + 1
        balance -= (vacation_days + vacation.selling_days)

    return max(0, balance)



def get_vacation_notice_deadline(start_date):
    """
    According to Brazilian labor law, employees must be notified 
    at least 30 days before vacation starts
    """
    return start_date - timedelta(days=30)


def validate_vacation_period(start_date, end_date, employee=None):
    """
    Validate vacation request against Brazilian labor law requirements
    
    Returns (is_valid, error_message)
    """
    today = timezone.now().date()
    
    # Check if start date is at least 30 days in the future (for legal notice)
    if start_date < today + timedelta(days=30):
        return False, "A data de início deve ser no mínimo 30 dias após a solicitação."
    
    # Check if end date is after start date
    if end_date <= start_date:
        return False, "A data final deve ser posterior à data inicial."
    
    # Calculate total vacation days
    total_days = (end_date - start_date).days + 1
    
    # According to CLT, each vacation period must be at least 5 days
    if total_days < 5:
        return False, "Períodos de férias devem ter no mínimo 5 dias conforme a CLT."
    
    # Check if the employee has enough balance (if employee is provided)
    if employee:
        balance = calculate_vacation_balance(employee)
        if total_days > balance:
            return False, f"Saldo insuficiente de férias. Você possui {balance} dias disponíveis."
    
    return True, ""
