"""
Centralized utility for logging settings and configuration.
Controls when and how settings are logged based on environment variables.

Environment variable LDR_LOG_SETTINGS controls the verbosity:
- "none" or "false": No settings logging at all (default)
- "summary" or "info": Only log count and summary of settings
- "debug" or "full": Log complete settings (with sensitive keys redacted)
- "debug_unsafe"/"unsafe"/"raw": REMOVED for security — maps to "none" with a deprecation warning
"""

import os
from typing import Any, Dict, Optional
from loguru import logger


# Check environment variable once at module load
SETTINGS_LOG_LEVEL = os.getenv("LDR_LOG_SETTINGS", "none").lower()

# Map various values to standardized levels
if SETTINGS_LOG_LEVEL in ("false", "0", "no", "none", "off"):
    SETTINGS_LOG_LEVEL = "none"
elif SETTINGS_LOG_LEVEL in ("true", "1", "yes", "info", "summary"):
    SETTINGS_LOG_LEVEL = "summary"
elif SETTINGS_LOG_LEVEL in ("debug", "full", "all"):
    SETTINGS_LOG_LEVEL = "debug"
elif SETTINGS_LOG_LEVEL in ("debug_unsafe", "unsafe", "raw"):
    import warnings

    warnings.warn(
        f"LDR_LOG_SETTINGS={os.getenv('LDR_LOG_SETTINGS')!r} is deprecated and has been "
        "removed for security. Use 'debug' for full settings with sensitive keys redacted. "
        "Defaulting to 'none'.",
        DeprecationWarning,
        stacklevel=2,
    )
    # logger.warning() won't work here — loguru is disabled at module load time
    # (see __init__.py). Write directly to stderr so users actually see this.
    import sys

    print(
        f"WARNING: LDR_LOG_SETTINGS={os.getenv('LDR_LOG_SETTINGS')!r} is deprecated and "
        "has been removed for security. Use 'debug' for full settings with sensitive keys "
        "redacted. Defaulting to 'none'.",
        file=sys.stderr,
    )
    SETTINGS_LOG_LEVEL = "none"
else:
    # Invalid value, default to none
    SETTINGS_LOG_LEVEL = "none"


def log_settings(
    settings: Any,
    message: str = "Settings loaded",
    force_level: Optional[str] = None,
) -> None:
    """
    Centralized settings logging with conditional output based on LDR_LOG_SETTINGS env var.

    Args:
        settings: Settings object or dict to log
        message: Log message prefix
        force_level: Override the environment variable setting (for critical messages)

    Behavior based on LDR_LOG_SETTINGS:
        - "none": No output
        - "summary": Log count and basic info at INFO level
        - "debug": Log full settings at DEBUG level (sensitive keys redacted)
        - "debug_unsafe"/"unsafe"/"raw": REMOVED — maps to "none" with a deprecation warning
    """
    log_level = force_level or SETTINGS_LOG_LEVEL

    if log_level == "none":
        return

    if log_level == "summary":
        # Log only summary at INFO level
        summary = create_settings_summary(settings)
        logger.info(f"{message}: {summary}")

    elif log_level == "debug":
        # Log full settings at DEBUG level with redaction
        if isinstance(settings, dict):
            safe_settings = redact_sensitive_keys(settings)
            logger.debug(f"{message} (redacted): {safe_settings}")
        else:
            logger.debug(f"{message}: {settings}")


def redact_sensitive_keys(settings: Dict[str, Any]) -> Dict[str, Any]:
    """
    Redact sensitive keys from settings dictionary.

    Args:
        settings: Settings dictionary

    Returns:
        Settings dictionary with sensitive values redacted
    """
    sensitive_patterns = [
        "api_key",
        "apikey",
        "password",
        "secret",
        "token",
        "credential",
        "auth",
        "private",
    ]

    redacted = {}
    for key, value in settings.items():
        # Check if key contains sensitive patterns
        key_lower = key.lower()
        is_sensitive = any(
            pattern in key_lower for pattern in sensitive_patterns
        )

        if is_sensitive:
            # Redact the value
            if isinstance(value, dict) and "value" in value:
                redacted[key] = {**value, "value": "***REDACTED***"}
            elif isinstance(value, str):
                redacted[key] = "***REDACTED***"
            else:
                redacted[key] = "***REDACTED***"
        elif isinstance(value, dict):
            # Recursively redact nested dicts
            redacted[key] = redact_sensitive_keys(value)
        else:
            redacted[key] = value

    return redacted


def create_settings_summary(settings: Any) -> str:
    """
    Create a summary of settings for logging.

    Args:
        settings: Settings object or dict

    Returns:
        Summary string
    """
    if isinstance(settings, dict):
        # Count different types of settings
        search_engines = sum(1 for k in settings.keys() if "search.engine" in k)
        llm_settings = sum(1 for k in settings.keys() if "llm." in k)
        total = len(settings)

        return f"{total} total settings (search engines: {search_engines}, LLM: {llm_settings})"
    return f"Settings object of type {type(settings).__name__}"


def get_settings_log_level() -> str:
    """
    Get the current settings logging level.

    Returns:
        Current log level: "none", "summary", or "debug"
    """
    return SETTINGS_LOG_LEVEL
