"""OpenAI embedding provider."""

from typing import Any, Dict, List, Optional

from langchain_core.embeddings import Embeddings
from loguru import logger

from ....config.thread_settings import get_setting_from_snapshot
from ..base import BaseEmbeddingProvider


class OpenAIEmbeddingsProvider(BaseEmbeddingProvider):
    """
    OpenAI embedding provider.

    Uses OpenAI API for cloud-based embeddings.
    Requires API key.
    """

    provider_name = "OpenAI"
    provider_key = "OPENAI"
    requires_api_key = True
    supports_local = False
    default_model = "text-embedding-3-small"

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

        Args:
            model: Model name (defaults to text-embedding-3-small)
            settings_snapshot: Optional settings snapshot
            **kwargs: Additional parameters (api_key, etc.)

        Returns:
            OpenAIEmbeddings instance

        Raises:
            ValueError: If API key is not configured
        """
        from langchain_openai import OpenAIEmbeddings

        # Get API key
        api_key = kwargs.get("api_key")
        if api_key is None:
            api_key = get_setting_from_snapshot(
                "embeddings.openai.api_key",
                default=None,
                settings_snapshot=settings_snapshot,
            )

        if not api_key:
            logger.error("OpenAI API key not found in settings")
            raise ValueError(
                "OpenAI API key not configured. "
                "Please set embeddings.openai.api_key in settings."
            )

        # Get model from settings if not specified
        if model is None:
            model = get_setting_from_snapshot(
                "embeddings.openai.model",
                default=cls.default_model,
                settings_snapshot=settings_snapshot,
            )

        # Get optional parameters
        base_url = kwargs.get("base_url")
        if base_url is None:
            base_url = get_setting_from_snapshot(
                "embeddings.openai.base_url",
                default=None,
                settings_snapshot=settings_snapshot,
            )

        dimensions = kwargs.get("dimensions")
        if dimensions is None:
            dimensions = get_setting_from_snapshot(
                "embeddings.openai.dimensions",
                default=None,
                settings_snapshot=settings_snapshot,
            )

        logger.info(f"Creating OpenAIEmbeddings with model={model}")

        # Build parameters
        params = {
            "model": model,
            "openai_api_key": api_key,
        }

        if base_url:
            params["openai_api_base"] = base_url

        # For text-embedding-3 models, dimensions can be customized
        if dimensions and model.startswith("text-embedding-3"):
            params["dimensions"] = int(dimensions)

        return OpenAIEmbeddings(**params)

    @classmethod
    def is_available(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> bool:
        """Check if OpenAI embeddings are available."""
        try:
            # Check for API key
            api_key = get_setting_from_snapshot(
                "embeddings.openai.api_key",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            return bool(api_key)
        except Exception:
            return False

    @classmethod
    def get_available_models(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> List[Dict[str, str]]:
        """Get list of available OpenAI embedding models from API."""
        try:
            from openai import OpenAI

            # Get API key
            api_key = get_setting_from_snapshot(
                "embeddings.openai.api_key",
                default=None,
                settings_snapshot=settings_snapshot,
            )

            if not api_key:
                logger.warning("OpenAI API key not configured")
                return []

            # Create client and fetch models
            client = OpenAI(api_key=api_key)
            models_response = client.models.list()

            # Filter for embedding models only
            embedding_models = []
            for model in models_response.data:
                model_id = model.id
                # OpenAI embedding models typically have "embedding" in the name
                if "embedding" in model_id.lower():
                    embedding_models.append(
                        {
                            "value": model_id,
                            "label": model_id,
                        }
                    )

            return embedding_models

        except Exception:
            logger.exception("Error fetching OpenAI embedding models")
            return []
