"""OpenAI 兼容接口通用实现，适用于所有兼容 OpenAI Chat API 的提供商。"""

from __future__ import annotations

from typing import Generator

from openai import OpenAI

from acm.llm.base import LLMBase


class OpenAICompatProvider(LLMBase):
    """通用 OpenAI 兼容 API 提供商。"""

    def __init__(self, api_key: str, model: str, base_url: str = ""):
        self._model = model
        kwargs: dict = {"api_key": api_key}
        if base_url:
            kwargs["base_url"] = base_url
        self._client = OpenAI(**kwargs)

    def chat(self, system_prompt: str, user_prompt: str) -> str:
        response = self._client.chat.completions.create(
            model=self._model,
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt},
            ],
            temperature=0.3,
        )
        return response.choices[0].message.content or ""

    def chat_with_history(
        self,
        system_prompt: str,
        messages: list[dict[str, str]],
    ) -> str:
        full_messages = [{"role": "system", "content": system_prompt}] + messages
        response = self._client.chat.completions.create(
            model=self._model,
            messages=full_messages,  # type: ignore[arg-type]
            temperature=0.3,
        )
        return response.choices[0].message.content or ""

    def stream_chat(
        self, system_prompt: str, user_prompt: str
    ) -> Generator[str, None, None]:
        stream = self._client.chat.completions.create(
            model=self._model,
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt},
            ],
            temperature=0.3,
            stream=True,
        )
        for chunk in stream:
            delta = chunk.choices[0].delta.content
            if delta:
                yield delta

    def stream_chat_with_history(
        self,
        system_prompt: str,
        messages: list[dict[str, str]],
    ) -> Generator[str, None, None]:
        full_messages = [{"role": "system", "content": system_prompt}] + messages
        stream = self._client.chat.completions.create(
            model=self._model,
            messages=full_messages,  # type: ignore[arg-type]
            temperature=0.3,
            stream=True,
        )
        for chunk in stream:
            delta = chunk.choices[0].delta.content
            if delta:
                yield delta
