"""
Config Service

Service layer for configuration management operations.
"""

from honeydb_ai.domain.interfaces import ConfigStore
from honeydb_ai.domain.models import Config
from honeydb_ai.utils.logging import get_logger, log_config_operation
from honeydb_ai.utils.validators import validate_api_key, validate_temperature, validate_max_tokens, validate_log_level


class ConfigService:
    """
    Service for configuration management.

    Coordinates configuration operations between controllers and storage layer.
    """

    def __init__(self, config_store: ConfigStore):
        """
        Initialize config service.

        Args:
            config_store: Configuration storage implementation
        """
        self.config_store = config_store
        self.logger = get_logger()

    def load_config(self) -> Config:
        """
        Load configuration.

        Returns:
            Config object with defaults for missing values

        Raises:
            ConfigurationError: If configuration is invalid
        """
        try:
            config = self.config_store.load()
            log_config_operation(self.logger, "load", True)
            return config
        except Exception as e:
            log_config_operation(self.logger, "load", False, str(e))
            raise

    def save_config(self, config: Config) -> None:
        """
        Save configuration.

        Args:
            config: Configuration to save

        Raises:
            StorageError: If save fails
        """
        try:
            self.config_store.save(config)
            log_config_operation(self.logger, "save", True)
        except Exception as e:
            log_config_operation(self.logger, "save", False, str(e))
            raise

    def update_honeydb_credentials(self, api_id: str, api_key: str) -> Config:
        """
        Update HoneyDB API credentials.

        Args:
            api_id: HoneyDB API ID
            api_key: HoneyDB API key

        Returns:
            Updated Config object

        Raises:
            ValidationError: If credentials are invalid
        """
        # Basic validation (non-empty strings)
        if not api_id or not api_id.strip():
            from honeydb_ai.domain.exceptions import ValidationError
            raise ValidationError("HoneyDB API ID cannot be empty")

        if not api_key or not api_key.strip():
            from honeydb_ai.domain.exceptions import ValidationError
            raise ValidationError("HoneyDB API key cannot be empty")

        # Load current config
        config = self.load_config()

        # Update credentials
        config.honeydb_api_id = api_id.strip()
        config.honeydb_api_key = api_key.strip()

        # Save
        self.save_config(config)

        return config

    def update_mcp_server_url(self, url: str) -> Config:
        """
        Update MCP server URL.

        Args:
            url: MCP server URL (e.g., https://honeydb.ai/sse/)

        Returns:
            Updated Config object

        Raises:
            ValidationError: If URL is invalid
        """
        if not url or not url.strip():
            from honeydb_ai.domain.exceptions import ValidationError
            raise ValidationError("MCP server URL cannot be empty")

        if not url.startswith(("http://", "https://")):
            from honeydb_ai.domain.exceptions import ValidationError
            raise ValidationError("MCP server URL must start with http:// or https://")

        config = self.load_config()
        config.mcp_server_url = url.strip()
        self.save_config(config)

        return config

    def update_api_key(self, provider: str, api_key: str) -> Config:
        """
        Update API key for an LLM provider.

        Args:
            provider: Provider name (openai, anthropic, gemini)
            api_key: New API key

        Returns:
            Updated Config object

        Raises:
            ValidationError: If API key is invalid
        """
        # Validate API key
        validate_api_key(api_key, provider)

        # Load current config
        config = self.load_config()

        # Update API key
        if provider == "openai":
            config.openai_api_key = api_key
        elif provider == "anthropic":
            config.anthropic_api_key = api_key
        elif provider == "gemini":
            config.gemini_api_key = api_key
        else:
            from honeydb_ai.domain.exceptions import ValidationError
            raise ValidationError(f"Unknown provider: {provider}")

        # Save
        self.save_config(config)

        return config

    def update_default_provider(self, provider: str) -> Config:
        """
        Update default LLM provider.

        Args:
            provider: Provider name

        Returns:
            Updated Config object
        """
        from honeydb_ai.utils.validators import validate_provider

        validate_provider(provider)

        config = self.load_config()
        config.default_provider = provider  # type: ignore
        self.save_config(config)

        return config

    def update_default_model(self, model: str) -> Config:
        """
        Update default model.

        Args:
            model: Model identifier

        Returns:
            Updated Config object
        """
        config = self.load_config()
        config.default_model = model
        self.save_config(config)

        return config

    def update_temperature(self, temperature: float) -> Config:
        """
        Update temperature setting.

        Args:
            temperature: Temperature value (0.0-2.0)

        Returns:
            Updated Config object

        Raises:
            ValidationError: If temperature is invalid
        """
        validate_temperature(temperature)

        config = self.load_config()
        config.temperature = temperature
        self.save_config(config)

        return config

    def update_max_tokens(self, max_tokens: int | None) -> Config:
        """
        Update max tokens setting.

        Args:
            max_tokens: Max tokens value or None

        Returns:
            Updated Config object

        Raises:
            ValidationError: If max_tokens is invalid
        """
        validate_max_tokens(max_tokens)

        config = self.load_config()
        config.max_tokens = max_tokens
        self.save_config(config)

        return config

    def update_theme(self, theme: str) -> Config:
        """
        Update UI theme.

        Args:
            theme: Theme setting (auto, dark, light)

        Returns:
            Updated Config object
        """
        config = self.load_config()
        config.theme = theme  # type: ignore
        self.save_config(config)

        return config

    def update_log_level(self, log_level: str) -> Config:
        """
        Update logging level.

        v2.0: Logging configuration.

        Args:
            log_level: Log level (DEBUG, INFO, WARNING, ERROR)

        Returns:
            Updated Config object

        Raises:
            ValidationError: If log level is invalid
        """
        validate_log_level(log_level)

        config = self.load_config()
        config.log_level = log_level  # type: ignore
        self.save_config(config)

        return config

    def update_verbose_tool_calls(self, verbose: bool) -> Config:
        """
        Update verbose tool calls setting.

        Args:
            verbose: Whether to show MCP tool calls during chat

        Returns:
            Updated Config object
        """
        config = self.load_config()
        config.verbose_tool_calls = verbose
        self.save_config(config)

        return config

    def config_exists(self) -> bool:
        """
        Check if configuration file exists.

        Returns:
            True if config file exists
        """
        return self.config_store.exists()

    def get_config_path(self) -> str:
        """
        Get configuration file path.

        Returns:
            Path to config file
        """
        return str(self.config_store.get_config_path())
