"""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"
    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 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)

    @classmethod
    def list_models_for_api(cls, api_key=None, settings_snapshot=None):
        """List available models using the custom endpoint.

        Args:
            api_key: Optional API key
            settings_snapshot: Optional settings snapshot for getting custom URL

        Returns:
            List of model dictionaries with 'value' and 'label' keys
        """
        try:
            # Get custom endpoint URL from settings if available
            if settings_snapshot:
                custom_url = get_setting_from_snapshot(
                    "llm.openai_endpoint.url",
                    default=cls.default_base_url,
                    settings_snapshot=settings_snapshot,
                )
                base_url = (
                    normalize_url(custom_url)
                    if custom_url
                    else cls.default_base_url
                )
            else:
                # Fall back to default if no settings available
                base_url = cls.default_base_url

            # Check if auth is required
            if cls.requires_auth_for_models():
                if not api_key:
                    logger.debug(
                        f"{cls.provider_name} requires API key for model listing"
                    )
                    return []
            else:
                api_key = api_key or "dummy-key-for-models-list"

            from openai import OpenAI

            # Create OpenAI client with custom URL
            client = OpenAI(api_key=api_key, base_url=base_url)

            # Fetch models
            logger.debug(
                f"Fetching models from {cls.provider_name} at {base_url}"
            )
            models_response = client.models.list()

            models = []
            for model in models_response.data:
                if model.id:
                    models.append(
                        {
                            "value": model.id,
                            "label": model.id,
                        }
                    )

            logger.debug(f"Found {len(models)} models from {cls.provider_name}")
            return models

        except Exception:
            logger.exception(f"Error listing models from {cls.provider_name}")
            return []


# 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")
