"""Custom OpenAI-compatible endpoint provider for Local Deep Research."""

from loguru import logger

from ....config.thread_settings import (
    get_setting_from_snapshot as _get_setting_from_snapshot,
)
from ....utilities.url_utils import normalize_url
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 CustomOpenAIEndpointProvider(OpenAICompatibleProvider):
    """Custom OpenAI-compatible endpoint provider.

    This provider allows users to connect to any OpenAI-compatible API endpoint
    by specifying a custom URL in the settings.
    """

    provider_name = "Custom OpenAI Endpoint"
    api_key_setting = "llm.openai_endpoint.api_key"
    url_setting = "llm.openai_endpoint.url"  # Settings key for URL
    default_base_url = "https://api.openai.com/v1"
    default_model = "gpt-3.5-turbo"

    # Metadata for auto-discovery
    provider_key = "OPENAI_ENDPOINT"
    company_name = "Custom"
    region = "Custom"
    country = "User-defined"
    data_location = "User-defined"
    is_cloud = True  # Assume cloud by default

    @classmethod
    def requires_auth_for_models(cls):
        """Custom endpoints may or may not require authentication for listing models.

        Many OpenAI-compatible servers (vLLM, local LLMs, etc.) don't require
        authentication. Return False to allow model listing without an API key.
        If the endpoint requires auth, the OpenAI client will raise an error.
        """
        return False

    @classmethod
    def create_llm(cls, model_name=None, temperature=0.7, **kwargs):
        """Override to get URL from settings."""
        settings_snapshot = kwargs.get("settings_snapshot")

        # Get custom endpoint URL from settings
        custom_url = get_setting_from_snapshot(
            "llm.openai_endpoint.url",
            default=cls.default_base_url,
            settings_snapshot=settings_snapshot,
        )

        # Normalize and pass the custom URL to parent implementation
        kwargs["base_url"] = (
            normalize_url(custom_url) if custom_url else cls.default_base_url
        )

        return super().create_llm(model_name, temperature, **kwargs)


# Keep the standalone functions for backward compatibility
def create_openai_endpoint_llm(model_name=None, temperature=0.7, **kwargs):
    """Factory function for custom OpenAI-compatible endpoint 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 ChatOpenAI instance pointing to custom endpoint

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


def is_openai_endpoint_available(settings_snapshot=None):
    """Check if custom OpenAI endpoint is available.

    Args:
        settings_snapshot: Optional settings snapshot to use

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


def register_custom_openai_endpoint_provider():
    """Register the custom OpenAI endpoint provider with the LLM registry."""
    register_llm("openai_endpoint", create_openai_endpoint_llm)
    logger.info("Registered Custom OpenAI Endpoint LLM provider")
