"""
Configuration management for palantir-event-capture
"""

import os
from typing import Any, Dict, Optional
from pathlib import Path

from dotenv import load_dotenv

from . import defaults
from ..models.captured_models import Severity, EventType, PipelineComponent


class Settings:
    """Global settings manager"""

    def __init__(self):
        # Load environment variables from .env file if it exists
        load_dotenv()

        # Kafka Configuration
        self.KAFKA_BOOTSTRAP_SERVERS_RCA: str = self._get_env(
            "KAFKA_BOOTSTRAP_SERVERS_RCA", defaults.DEFAULT_KAFKA_BOOTSTRAP_SERVERS_RCA
        )
        self.KAFKA_EVENT_TOPIC_RCA: str = self._get_env(
            "KAFKA_EVENT_TOPIC_RCA", defaults.DEFAULT_KAFKA_EVENT_TOPIC_RCA
        )
        self.KAFKA_ENABLED_RCA: bool = self._get_env_bool(
            "KAFKA_ENABLED_RCA", defaults.DEFAULT_KAFKA_ENABLED_RCA
        )
        self.KAFKA_COMPRESSION_RCA: str = self._get_env(
            "KAFKA_COMPRESSION_RCA", defaults.DEFAULT_KAFKA_COMPRESSION_RCA
        )
        self.KAFKA_BATCH_SIZE_RCA: int = self._get_env_int(
            "KAFKA_BATCH_SIZE_RCA", defaults.DEFAULT_KAFKA_BATCH_SIZE_RCA
        )
        self.KAFKA_LINGER_MS_RCA: int = self._get_env_int(
            "KAFKA_LINGER_MS_RCA", defaults.DEFAULT_KAFKA_LINGER_MS_RCA
        )

        # Logging Configuration
        self.log_level: str = self._get_env("LOG_LEVEL", defaults.DEFAULT_LOG_LEVEL)
        self.log_to_console: bool = self._get_env_bool(
            "LOG_TO_CONSOLE", defaults.DEFAULT_LOG_TO_CONSOLE
        )
        self.log_format: str = self._get_env("LOG_FORMAT", defaults.DEFAULT_LOG_FORMAT)

        # Event Capture Settings
        self.send_to_transport: bool = self._get_env_bool(
            "SEND_TO_TRANSPORT", defaults.DEFAULT_SEND_TO_TRANSPORT
        )
        self.default_component: PipelineComponent = self._get_env_enum(
            "DEFAULT_COMPONENT", PipelineComponent, defaults.DEFAULT_COMPONENT
        )
        self.default_severity: Severity = self._get_env_enum(
            "DEFAULT_SEVERITY", Severity, defaults.DEFAULT_SEVERITY
        )
        self.default_reraise: bool = self._get_env_bool(
            "DEFAULT_RERAISE", defaults.DEFAULT_RERAISE
        )
        self.enable_stack_traces: bool = self._get_env_bool(
            "ENABLE_STACK_TRACES", defaults.DEFAULT_ENABLE_STACK_TRACES
        )
        self.max_stack_trace_length: int = self._get_env_int(
            "MAX_STACK_TRACE_LENGTH", defaults.DEFAULT_MAX_STACK_TRACE_LENGTH
        )
        
        self.use_background_transport: bool = self._get_env_bool(
            "USE_BACKGROUND_TRANSPORT", False  # Default to False for easier debugging
        )

        # Retry Configuration
        self.default_max_retries: int = self._get_env_int(
            "DEFAULT_MAX_RETRIES", defaults.DEFAULT_MAX_RETRIES
        )
        self.default_retry_delay: float = self._get_env_float(
            "DEFAULT_RETRY_DELAY", defaults.DEFAULT_RETRY_DELAY
        )
        self.default_retry_backoff: float = self._get_env_float(
            "DEFAULT_RETRY_BACKOFF", defaults.DEFAULT_RETRY_BACKOFF
        )

        # Storage Configuration
        self.storage_enabled: bool = self._get_env_bool(
            "STORAGE_ENABLED", defaults.DEFAULT_STORAGE_ENABLED
        )
        self.storage_path: Path = Path(
            self._get_env("STORAGE_PATH", defaults.DEFAULT_STORAGE_PATH)
        )

    def _get_env(self, key: str, default: Any) -> Any:
        """Get environment variable or return default"""
        return os.getenv(key, default)

    def _get_env_bool(self, key: str, default: bool) -> bool:
        """Get boolean environment variable"""
        value = os.getenv(key)
        if value is None:
            return default
        return value.lower() in ("true", "1", "yes", "on")

    def _get_env_int(self, key: str, default: int) -> int:
        """Get integer environment variable"""
        value = os.getenv(key)
        if value is None:
            return default
        try:
            return int(value)
        except ValueError:
            return default

    def _get_env_float(self, key: str, default: float) -> float:
        """Get float environment variable"""
        value = os.getenv(key)
        if value is None:
            return default
        try:
            return float(value)
        except ValueError:
            return default

    def _get_env_enum(self, key: str, enum_class: type, default: Any) -> Any:
        """Get enum environment variable"""
        value = os.getenv(key)
        if value is None:
            return default
        try:
            return enum_class(value.lower())
        except (ValueError, KeyError):
            return default

    def update(self, **kwargs: Any) -> None:
        """Update settings programmatically"""
        for key, value in kwargs.items():
            if hasattr(self, key):
                setattr(self, key, value)

    def to_dict(self) -> Dict[str, Any]:
        """Convert settings to dictionary"""
        return {
            key: value
            for key, value in self.__dict__.items()
            if not key.startswith("_")
        }


# Global settings instance
_settings: Optional[Settings] = None


def get_settings() -> Settings:
    """Get or create global settings instance"""
    global _settings
    if _settings is None:
        _settings = Settings()
    return _settings


def configure(**kwargs: Any) -> None:
    """
    Configure settings programmatically.

    Example:
        configure(
            KAFKA_BOOTSTRAP_SERVERS_RCA="localhost:9092",
            KAFKA_ENABLED_RCA=True,
            log_level="DEBUG"
        )
    """
    settings = get_settings()
    settings.update(**kwargs)


def reset_settings() -> None:
    """Reset settings to defaults (useful for testing)"""
    global _settings
    _settings = None