"""
Base interface for settings management.

This module defines the abstract base class that all settings managers
must implement, ensuring a consistent interface.
"""

from abc import ABC, abstractmethod
from typing import Any, Dict, Optional, Union


class ISettingsManager(ABC):
    """Abstract base class for settings managers."""

    @abstractmethod
    def get_setting(
        self, key: str, default: Any = None, check_env: bool = True
    ) -> Any:
        """
        Get a setting value.

        Args:
            key: Setting key
            default: Default value if setting is not found
            check_env: If true, check environment variables first

        Returns:
            Setting value or default if not found
        """
        pass

    @abstractmethod
    def set_setting(self, key: str, value: Any, commit: bool = True) -> bool:
        """
        Set a setting value.

        Args:
            key: Setting key
            value: Setting value
            commit: Whether to commit the change

        Returns:
            True if successful, False otherwise
        """
        pass

    @abstractmethod
    def get_all_settings(self) -> Dict[str, Any]:
        """
        Get all settings.

        Returns:
            Dictionary of all settings with metadata
        """
        pass

    @abstractmethod
    def create_or_update_setting(
        self, setting: Union[Dict[str, Any], Any], commit: bool = True
    ) -> Optional[Any]:
        """
        Create or update a setting.

        Args:
            setting: Setting object or dictionary
            commit: Whether to commit the change

        Returns:
            The created or updated Setting model, or None if failed
        """
        pass

    @abstractmethod
    def delete_setting(self, key: str, commit: bool = True) -> bool:
        """
        Delete a setting.

        Args:
            key: Setting key
            commit: Whether to commit the change

        Returns:
            True if successful, False otherwise
        """
        pass

    @abstractmethod
    def get_bool_setting(
        self, key: str, default: bool = False, check_env: bool = True
    ) -> bool:
        """
        Get a setting value as a boolean.

        Args:
            key: Setting key
            default: Default boolean value if setting is not found
            check_env: If true, check environment variables first

        Returns:
            Boolean value of the setting
        """
        pass

    @abstractmethod
    def get_settings_snapshot(self) -> Dict[str, Any]:
        """
        Get a simplified settings snapshot with just key-value pairs.

        Returns:
            Dictionary with setting keys mapped to their values
        """
        pass

    @abstractmethod
    def load_from_defaults_file(
        self, commit: bool = True, **kwargs: Any
    ) -> None:
        """
        Import settings from the defaults settings file.

        Args:
            commit: Whether to commit changes to database
            **kwargs: Additional arguments for import_settings
        """
        pass

    @abstractmethod
    def import_settings(
        self,
        settings_data: Dict[str, Any],
        commit: bool = True,
        overwrite: bool = True,
        delete_extra: bool = False,
    ) -> None:
        """
        Import settings from a dictionary.

        Args:
            settings_data: The raw settings data to import
            commit: Whether to commit the DB after loading
            overwrite: If true, overwrite existing settings
            delete_extra: If true, delete settings not in settings_data
        """
        pass
