"""Base class for embedding providers."""

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

from langchain_core.embeddings import Embeddings


class BaseEmbeddingProvider(ABC):
    """
    Abstract base class for embedding providers.

    All embedding providers should inherit from this class and implement
    the required methods. This provides a consistent interface similar to
    the LLM provider system.
    """

    # Override these in subclasses
    provider_name = "base"  # Display name for logs/UI
    provider_key = "BASE"  # Unique identifier (uppercase)
    requires_api_key = False  # Whether this provider requires an API key
    supports_local = False  # Whether this runs locally
    default_model = None  # Default embedding model

    @classmethod
    @abstractmethod
    def create_embeddings(
        cls,
        model: Optional[str] = None,
        settings_snapshot: Optional[Dict[str, Any]] = None,
        **kwargs,
    ) -> Embeddings:
        """
        Create an embeddings instance for this provider.

        Args:
            model: Name of the embedding model to use
            settings_snapshot: Optional settings snapshot for thread-safe access
            **kwargs: Additional provider-specific parameters

        Returns:
            A LangChain Embeddings instance

        Raises:
            ValueError: If required configuration is missing
            ImportError: If required dependencies are not installed
        """
        pass

    @classmethod
    @abstractmethod
    def is_available(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> bool:
        """
        Check if this embedding provider is available and properly configured.

        Args:
            settings_snapshot: Optional settings snapshot for thread-safe access

        Returns:
            True if the provider can be used, False otherwise
        """
        pass

    @classmethod
    def get_available_models(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> List[Dict[str, str]]:
        """
        Get list of available models for this provider.

        Args:
            settings_snapshot: Optional settings snapshot

        Returns:
            List of dicts with 'value' and 'label' keys for each model
        """
        return []

    @classmethod
    def get_model_info(cls, model: str) -> Optional[Dict[str, Any]]:
        """
        Get information about a specific model.

        Args:
            model: Model identifier

        Returns:
            Dict with model metadata (dimensions, description, etc.) or None
        """
        return None

    @classmethod
    def validate_config(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> tuple[bool, Optional[str]]:
        """
        Validate the provider configuration.

        Args:
            settings_snapshot: Optional settings snapshot

        Returns:
            Tuple of (is_valid, error_message)
        """
        if not cls.is_available(settings_snapshot):
            return (
                False,
                f"{cls.provider_name} is not available or not configured",
            )
        return True, None

    @classmethod
    def get_provider_info(cls) -> Dict[str, Any]:
        """
        Get metadata about this provider.

        Returns:
            Dict with provider information
        """
        return {
            "name": cls.provider_name,
            "key": cls.provider_key,
            "requires_api_key": cls.requires_api_key,
            "supports_local": cls.supports_local,
            "default_model": cls.default_model,
        }
