"""Anthropic LLM provider for Local Deep Research."""

from langchain_anthropic import ChatAnthropic
from loguru import logger

from ....config.thread_settings import (
    get_setting_from_snapshot as _get_setting_from_snapshot,
    NoSettingsContextError,
)
from ...llm_registry import register_llm
from ..openai_base import OpenAICompatibleProvider


def get_setting_from_snapshot(
    key, default=None, username=None, settings_snapshot=None
):
    """Get setting from context only - no database access from threads.

    This is a wrapper around the shared function that enables fallback LLM check.
    """
    return _get_setting_from_snapshot(
        key, default, username, settings_snapshot, check_fallback_llm=True
    )


class AnthropicProvider(OpenAICompatibleProvider):
    """Anthropic provider for Local Deep Research.

    This is the official Anthropic API provider.
    """

    provider_name = "Anthropic"
    api_key_setting = "llm.anthropic.api_key"
    default_model = "claude-3-sonnet-20240229"
    default_base_url = "https://api.anthropic.com/v1"

    # Metadata for auto-discovery
    provider_key = "ANTHROPIC"
    company_name = "Anthropic"
    region = "US"
    country = "United States"
    data_location = "United States"
    is_cloud = True

    @classmethod
    def create_llm(cls, model_name=None, temperature=0.7, **kwargs):
        """Factory function for Anthropic LLMs.

        Args:
            model_name: Name of the model to use
            temperature: Model temperature (0.0-1.0)
            **kwargs: Additional arguments including settings_snapshot

        Returns:
            A configured ChatAnthropic instance

        Raises:
            ValueError: If API key is not configured
        """
        settings_snapshot = kwargs.get("settings_snapshot")

        # Get API key from settings
        api_key = get_setting_from_snapshot(
            cls.api_key_setting,
            default=None,
            settings_snapshot=settings_snapshot,
        )

        if not api_key:
            logger.error(f"{cls.provider_name} API key not found in settings")
            raise ValueError(
                f"{cls.provider_name} API key not configured. "
                f"Please set {cls.api_key_setting} in settings."
            )

        # Use default model if none specified
        if not model_name:
            model_name = cls.default_model

        # Build Anthropic-specific parameters
        anthropic_params = {
            "model": model_name,
            "anthropic_api_key": api_key,
            "temperature": temperature,
        }

        # Add max_tokens if specified in settings
        try:
            max_tokens = get_setting_from_snapshot(
                "llm.max_tokens",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if max_tokens:
                anthropic_params["max_tokens"] = int(max_tokens)
        except NoSettingsContextError:
            pass  # Optional parameter

        logger.info(
            f"Creating {cls.provider_name} LLM with model: {model_name}, "
            f"temperature: {temperature}"
        )

        return ChatAnthropic(**anthropic_params)

    @classmethod
    def is_available(cls, settings_snapshot=None):
        """Check if this provider is available.

        Args:
            settings_snapshot: Optional settings snapshot to use

        Returns:
            True if API key is configured, False otherwise
        """
        try:
            # Check if API key is configured
            api_key = get_setting_from_snapshot(
                cls.api_key_setting,
                default=None,
                settings_snapshot=settings_snapshot,
            )
            return bool(api_key)
        except Exception:
            return False


# Keep the standalone functions for backward compatibility and registration
def create_anthropic_llm(model_name=None, temperature=0.7, **kwargs):
    """Factory function for Anthropic LLMs.

    Args:
        model_name: Name of the model to use (e.g., "claude-3-opus-20240229", "claude-3-sonnet-20240229", etc.)
        temperature: Model temperature (0.0-1.0)
        **kwargs: Additional arguments including settings_snapshot

    Returns:
        A configured ChatAnthropic instance

    Raises:
        ValueError: If Anthropic API key is not configured
    """
    return AnthropicProvider.create_llm(model_name, temperature, **kwargs)


def is_anthropic_available(settings_snapshot=None):
    """Check if Anthropic is available.

    Args:
        settings_snapshot: Optional settings snapshot to use

    Returns:
        True if Anthropic API key is configured, False otherwise
    """
    return AnthropicProvider.is_available(settings_snapshot)


def register_anthropic_provider():
    """Register the Anthropic provider with the LLM registry."""
    register_llm("anthropic", create_anthropic_llm)
    logger.info("Registered Anthropic LLM provider")
