import logging
from typing import List

from openai import OpenAI, Stream
from openai.types.chat import ChatCompletionChunk, ChatCompletion


class LLMBackend:
    """
    openai chat 接口封装
    """

    def __init__(self, base_url: str, api_key) -> None:
        print("base_url", base_url)
        print("api_key", api_key)
        self.base_url = base_url + "/" if base_url else None
        self.api_key = api_key
        self.client = OpenAI(base_url=self.base_url, api_key=self.api_key)

    def run(
        self,
        messages: List,
        model: str,
        tools: List = None,
        tool_choice="auto",
        stream=False,
        stream_options=None,
        extra_body=None,
        temperature=None,
        top_p=None,
        response_format=None,
        parallel_tool_calls=True,
        audio=None,
        modalities=None,
    ) -> ChatCompletion | Stream[ChatCompletionChunk]:
        if any(model.startswith(prefix) for prefix in ["o1", "o3", "gpt-5"]):
            temperature = None
            top_p = None
        chat_params = {
            "messages": messages,
            "model": model,
            "stream": stream,
            #"max_tokens": 20000,
            #"presence_penalty": 0,
            #"frequency_penalty": 0
            # "parallel_tool_calls": parallel_tool_calls,
        }
        if extra_body:
            model_params = extra_body.get("model_params")
            if model_params:
                #if "n" in model_params:
                #    raise ValueError("n is not allowed in model_params")
                chat_params.update(model_params)
            stream_options_params = extra_body.get("stream_options")
            if stream_options_params:
                chat_params["stream_options"] = {
                    "include_usage": bool(stream_options_params["include_usage"])
                }
        print("stream_optionsstream_optionsstream_optionsstream_optionsstream_options")
        print(stream_options)
        if stream_options:
            print(isinstance(stream_options, dict))
            if isinstance(stream_options, dict):
                if "include_usage" in stream_options:
                    chat_params["stream_options"] = {
                        "include_usage": bool(stream_options["include_usage"])
                    }
        if audio:
            chat_params["audio"] = audio
        if modalities:
            chat_params["modalities"] = modalities
        if top_p:
            chat_params["top_p"] = top_p
        if temperature and top_p is None:
            chat_params["temperature"] = temperature
        if tools:
            chat_params["tools"] = tools
            chat_params["parallel_tool_calls"] = parallel_tool_calls
            chat_params["tool_choice"] = tool_choice if tool_choice else "auto"
        if (
            isinstance(response_format, dict)
            and response_format.get("type") == "json_object"
        ):
            chat_params["response_format"] = {"type": "json_object"}
        for message in chat_params["messages"]:
            if "content" not in message:
                message["content"] = ""
            #elif "content" in message and "type" in message["content"] and message["content"]["type"] == "text":
            #    message["content"] = message["content"]["text"]

        chat_params["timeout"] = 300

        logging.info("chat_params: %s", chat_params)
        response = self.client.chat.completions.create(**chat_params)
        logging.info("chat_response: %s", response)
        return response
