from __future__ import annotations

import re
from typing import Any

_CAMEL_RE_1 = re.compile(r"([A-Z]+)([A-Z][a-z])")
_CAMEL_RE_2 = re.compile(r"([a-z0-9])([A-Z])")


def camel_to_snake(name: str) -> str:
    """Convert a camelCase or PascalCase string to snake_case."""
    s = _CAMEL_RE_1.sub(r"\1_\2", name)
    return _CAMEL_RE_2.sub(r"\1_\2", s).lower()


def snake_to_camel(name: str) -> str:
    """Convert a snake_case string to camelCase."""
    parts = name.split("_")
    return parts[0] + "".join(word.capitalize() for word in parts[1:])


def deep_camel_to_snake(data: Any) -> Any:
    """Recursively convert all dictionary keys from camelCase to snake_case."""
    if isinstance(data, dict):
        return {camel_to_snake(k): deep_camel_to_snake(v) for k, v in data.items()}
    if isinstance(data, list):
        return [deep_camel_to_snake(item) for item in data]
    return data


def deep_snake_to_camel(data: Any) -> Any:
    """Recursively convert all dictionary keys from snake_case to camelCase."""
    if isinstance(data, dict):
        return {snake_to_camel(k): deep_snake_to_camel(v) for k, v in data.items()}
    if isinstance(data, list):
        return [deep_snake_to_camel(item) for item in data]
    return data
