"""Sentence Transformers 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 SentenceTransformersProvider(BaseEmbeddingProvider):
    """
    Sentence Transformers embedding provider.

    Uses HuggingFace sentence-transformers models for local embeddings.
    No API key required, runs entirely locally.
    """

    provider_name = "Sentence Transformers"
    provider_key = "SENTENCE_TRANSFORMERS"
    requires_api_key = False
    supports_local = True
    default_model = "all-MiniLM-L6-v2"

    # Available models with metadata
    AVAILABLE_MODELS = {
        "all-MiniLM-L6-v2": {
            "dimensions": 384,
            "description": "Fast, lightweight model. Good for general use.",
            "max_seq_length": 256,
        },
        "all-mpnet-base-v2": {
            "dimensions": 768,
            "description": "Higher quality, slower. Best accuracy.",
            "max_seq_length": 384,
        },
        "multi-qa-MiniLM-L6-cos-v1": {
            "dimensions": 384,
            "description": "Optimized for question-answering tasks.",
            "max_seq_length": 512,
        },
        "paraphrase-multilingual-MiniLM-L12-v2": {
            "dimensions": 384,
            "description": "Supports multiple languages.",
            "max_seq_length": 128,
        },
    }

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

        Args:
            model: Model name (defaults to all-MiniLM-L6-v2)
            settings_snapshot: Optional settings snapshot
            **kwargs: Additional parameters (device, etc.)

        Returns:
            SentenceTransformerEmbeddings instance
        """
        from langchain_community.embeddings import (
            SentenceTransformerEmbeddings,
        )

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

        # Get device setting (cpu or cuda)
        device = kwargs.get("device")
        if device is None:
            device = get_setting_from_snapshot(
                "embeddings.sentence_transformers.device",
                default="cpu",
                settings_snapshot=settings_snapshot,
            )

        logger.info(
            f"Creating SentenceTransformerEmbeddings with model={model}, device={device}"
        )

        return SentenceTransformerEmbeddings(
            model_name=model,
            model_kwargs={"device": device},
        )

    @classmethod
    def is_available(
        cls, settings_snapshot: Optional[Dict[str, Any]] = None
    ) -> bool:
        """
        Check if Sentence Transformers is available.

        Since sentence-transformers is a required dependency, this always returns True.
        This method exists for API consistency with other providers.
        """
        return True

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

        Note: Since there's no centralized API for Sentence Transformers,
        we return a curated list of commonly used models. Users can also
        specify any model name from HuggingFace directly in settings.
        """
        return [
            {
                "value": model,
                "label": f"{model} ({info['dimensions']}d) - {info['description']}",
            }
            for model, info in cls.AVAILABLE_MODELS.items()
        ]
