from datetime import datetime, date
import logging

logger = logging.getLogger(__name__)

def validar_data(data_str: str, formato: str = '%Y-%m-%d') -> bool:
    """
    Valida se uma string representa uma data válida no formato especificado.
    
    Args:
        data_str: String contendo a data
        formato: Formato esperado da data (default: YYYY-MM-DD)
        
    Returns:
        bool: True se a data é válida, False caso contrário
    """
    if not data_str:
        return True
    
    try:
        datetime.strptime(data_str, formato)
        return True
    except ValueError as e:
        logger.warning(f"Data inválida: {data_str} (formato esperado: {formato}). Erro: {e}")
        return False

def converter_data(data_str: str, formato_entrada: str = '%Y-%m-%d', formato_saida: str = None) -> date:
    """
    Converte uma string de data para um objeto date.
    
    Args:
        data_str: String contendo a data
        formato_entrada: Formato da data de entrada (default: YYYY-MM-DD)
        formato_saida: Se especificado, retorna a data como string neste formato
        
    Returns:
        date: Objeto date se formato_saida=None, string formatada caso contrário
        
    Raises:
        ValueError: Se a data for inválida
    """
    if not data_str:
        return None
        
    try:
        data = datetime.strptime(data_str, formato_entrada).date()
        
        if formato_saida:
            return data.strftime(formato_saida)
        return data
    except ValueError as e:
        logger.error(f"Erro ao converter data '{data_str}': {e}")
        raise ValueError(f"Data inválida: {data_str}. Use o formato {formato_entrada}")

def validar_sequencia_datas(data_nascimento: date = None, 
                          data_entrada: date = None,
                          data_efetivacao: date = None) -> None:
    """
    Valida a sequência lógica entre datas.
    
    Args:
        data_nascimento: Data de nascimento
        data_entrada: Data de entrada na OCI
        data_efetivacao: Data de efetivação na OCI
        
    Raises:
        ValueError: Se houver inconsistência entre as datas
    """
    hoje = date.today()
    
    # Validar datas futuras
    for nome, data in [
        ("Data de nascimento", data_nascimento),
        ("Data de entrada", data_entrada),
        ("Data de efetivação", data_efetivacao)
    ]:
        if data and data > hoje:
            logger.warning(f"{nome} no futuro: {data}")
            raise ValueError(f"{nome} não pode ser no futuro")
    
    # Validar sequência
    if data_nascimento and data_entrada and data_nascimento > data_entrada:
        logger.warning(f"Data de entrada ({data_entrada}) anterior à data de nascimento ({data_nascimento})")
        raise ValueError("Data de entrada na OCI não pode ser anterior à data de nascimento")
        
    if data_entrada and data_efetivacao and data_entrada > data_efetivacao:
        logger.warning(f"Data de efetivação ({data_efetivacao}) anterior à data de entrada ({data_entrada})")
        raise ValueError("Data de efetivação não pode ser anterior à data de entrada")

def calcular_idade(data_nascimento: date) -> int:
    """
    Calcula a idade com base na data de nascimento.
    
    Args:
        data_nascimento: Data de nascimento
        
    Returns:
        int: Idade em anos
    """
    if not data_nascimento:
        return None
        
    hoje = date.today()
    idade = hoje.year - data_nascimento.year
    
    # Ajustar se ainda não fez aniversário este ano
    if hoje.month < data_nascimento.month or \
       (hoje.month == data_nascimento.month and hoje.day < data_nascimento.day):
        idade -= 1
    
    return idade

def converter_data_br(data_str):
    """Converte string de data no formato DD/MM/YYYY para objeto date"""
    if not data_str:
        return None
    try:
        dia, mes, ano = map(int, data_str.split('/'))
        return date(ano, mes, dia)
    except (ValueError, TypeError) as e:
        return None

def converter_data_iso(data_str):
    """Converte string de data no formato YYYY-MM-DD para objeto date"""
    if not data_str:
        return None
    try:
        return datetime.strptime(data_str, '%Y-%m-%d').date()
    except (ValueError, TypeError) as e:
        return None

def formatar_data_br(data):
    """Formata objeto date para string no formato DD/MM/YYYY"""
    if not data:
        return ''
    if isinstance(data, str):
        data = converter_data_iso(data) or converter_data_br(data)
    if not data:
        return ''
    return data.strftime('%d/%m/%Y')

def formatar_data_iso(data):
    """Formata objeto date para string no formato YYYY-MM-DD"""
    if not data:
        return ''
    if isinstance(data, str):
        data = converter_data_br(data) or converter_data_iso(data)
    if not data:
        return ''
    return data.strftime('%Y-%m-%d')

def validar_data(data, data_maxima=None, data_minima=None):
    """Valida se a data está dentro do intervalo permitido"""
    if not data:
        return True
    
    if isinstance(data, str):
        data = converter_data_br(data) or converter_data_iso(data)
        if not data:
            return False
    
    hoje = date.today()
    
    if data_maxima and data > data_maxima:
        return False
    if data_minima and data < data_minima:
        return False
    if data > hoje:
        return False
    
    return True 