"""
Serialization helpers for converting between Python snake_case and JavaScript camelCase.
"""
import re
from typing import Any, Dict, List, Union


def to_camel_case(snake_str: str) -> str:
    """
    Convert snake_case string to camelCase.
    
    Examples:
        event_type -> eventType
        start_time -> startTime
        is_active -> isActive
    """
    components = snake_str.split('_')
    # Keep the first component as-is, capitalize the rest
    return components[0] + ''.join(word.capitalize() for word in components[1:])


def to_snake_case(camel_str: str) -> str:
    """
    Convert camelCase string to snake_case.
    
    Examples:
        eventType -> event_type
        startTime -> start_time
        isActive -> is_active
    """
    # Insert underscore before uppercase letters and convert to lowercase
    snake = re.sub('([A-Z])', r'_\1', camel_str).lower()
    # Remove leading underscore if present
    return snake.lstrip('_')


def dict_to_camel_case(data: Union[Dict, List, Any]) -> Union[Dict, List, Any]:
    """
    Recursively convert dictionary keys from snake_case to camelCase.
    Also handles lists of dictionaries.
    
    Args:
        data: Dictionary, list, or primitive value to convert
        
    Returns:
        Converted data structure with camelCase keys
    """
    if isinstance(data, dict):
        return {to_camel_case(key): dict_to_camel_case(value) 
                for key, value in data.items()}
    elif isinstance(data, list):
        return [dict_to_camel_case(item) for item in data]
    else:
        return data


def dict_to_snake_case(data: Union[Dict, List, Any]) -> Union[Dict, List, Any]:
    """
    Recursively convert dictionary keys from camelCase to snake_case.
    Also handles lists of dictionaries.
    
    Args:
        data: Dictionary, list, or primitive value to convert
        
    Returns:
        Converted data structure with snake_case keys
    """
    if isinstance(data, dict):
        return {to_snake_case(key): dict_to_snake_case(value) 
                for key, value in data.items()}
    elif isinstance(data, list):
        return [dict_to_snake_case(item) for item in data]
    else:
        return data
