"""
Type conversion utilities.

This module provides type conversion functions that are used throughout
the codebase. It is intentionally kept free of internal dependencies to
avoid circular import issues.
"""

from typing import Any


def to_bool(value: Any, default: bool = False) -> bool:
    """
    Convert a value to boolean, handling string representations.

    This is a standalone utility for converting any value to boolean,
    centralizing the string-to-boolean conversion logic that was
    previously scattered throughout the codebase.

    Handles truthy string representations that may come from:
    - API requests
    - Configuration files
    - SQLite (which lacks native boolean type)
    - Environment variables

    Args:
        value: The value to convert
        default: Default boolean if value is None

    Returns:
        Boolean value

    Examples:
        >>> to_bool("true")
        True
        >>> to_bool("yes")
        True
        >>> to_bool("1")
        True
        >>> to_bool("false")
        False
        >>> to_bool(1)
        True
        >>> to_bool(None, default=True)
        True
    """
    if isinstance(value, bool):
        return value
    if isinstance(value, str):
        # Use strip() to handle whitespace that often appears in env vars
        # e.g., from shell parsing, config files, or copy-paste errors
        return value.strip().lower() in ("true", "1", "yes", "on", "enabled")
    if value is None:
        return default
    # For other types (int, etc.), use Python's bool conversion
    return bool(value)


def unwrap_setting(val: Any) -> Any:
    """Unwrap a setting that may be stored as ``{"value": x}`` or as ``x``.

    Settings snapshots produced by ``SettingsManager.get_all_settings``
    encode each value as a dict (``{"value": actual, "ui_element": ...}``),
    while simplified snapshots use the raw value. This helper normalizes
    a single value to its unwrapped form.

    Returns ``val["value"]`` when ``val`` is a dict with a ``"value"`` key,
    otherwise ``val`` unchanged. ``None`` is preserved (use
    ``api.settings_utils.extract_setting_value`` if you want
    default-substitution semantics).

    Lives in this dependency-free leaf module (rather than
    ``api.settings_utils``) so the many low-level callers — security/egress
    policy, the search-engine factory, notifications — can import it without
    dragging in the heavy ``api`` package ``__init__`` chain, which created
    an import cycle (``cannot import name 'PolicyDeniedError'``).
    """
    if isinstance(val, dict) and "value" in val:
        return val["value"]
    return val
