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

from langchain_openai import ChatOpenAI
from loguru import logger

from ....config.thread_settings import (
    get_setting_from_snapshot,
    NoSettingsContextError,
)
from ..openai_base import OpenAICompatibleProvider


class OpenAIProvider(OpenAICompatibleProvider):
    """OpenAI provider for Local Deep Research.

    This is the official OpenAI API provider.
    """

    provider_name = "OpenAI"
    api_key_setting = "llm.openai.api_key"
    default_model = ""  # User must explicitly pick a model — no silent fallback
    default_base_url = "https://api.openai.com/v1"

    # Metadata for auto-discovery
    provider_key = "OPENAI"
    company_name = "OpenAI"
    is_cloud = True

    @classmethod
    def create_llm(cls, model_name=None, temperature=0.7, **kwargs):
        """Factory function for OpenAI 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

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

        # Require an explicit model — no silent fallback to a hardcoded default.
        if not model_name or not model_name.strip():
            logger.error(f"{cls.provider_name} model name not provided")
            raise ValueError(
                f"{cls.provider_name} model not configured. "
                f"Please set llm.model in settings (e.g. 'gpt-4o-mini')."
            )

        # Build OpenAI-specific parameters
        openai_params = {
            "model": model_name,
            "api_key": api_key,
            "temperature": temperature,
        }

        # Add optional parameters if they exist in settings
        try:
            api_base = get_setting_from_snapshot(
                "llm.openai.api_base",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if api_base:
                openai_params["openai_api_base"] = api_base
        except NoSettingsContextError:
            pass  # Optional parameter

        try:
            organization = get_setting_from_snapshot(
                "llm.openai.organization",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if organization:
                openai_params["openai_organization"] = organization
        except NoSettingsContextError:
            pass  # Optional parameter

        try:
            streaming = get_setting_from_snapshot(
                "llm.streaming",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if streaming is not None:
                openai_params["streaming"] = streaming
        except NoSettingsContextError:
            pass  # Optional parameter

        try:
            max_retries = get_setting_from_snapshot(
                "llm.max_retries",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if max_retries is not None:
                openai_params["max_retries"] = max_retries
        except NoSettingsContextError:
            pass  # Optional parameter

        try:
            request_timeout = get_setting_from_snapshot(
                "llm.request_timeout",
                default=None,
                settings_snapshot=settings_snapshot,
            )
            if request_timeout is not None:
                openai_params["request_timeout"] = request_timeout
        except NoSettingsContextError:
            pass  # Optional parameter

        # 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:
                openai_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 ChatOpenAI(**openai_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 and str(api_key).strip())
        except Exception:
            return False
