from typing import Optional

from openai import OpenAI
from wcferry import WxMsg

from common.log import logger
from config import conf
from openai import OpenAI, AuthenticationError, APIConnectionError, APIError


class Plugin:
    def __init__(self):
        self.config = conf()
        self.LOG = logger
        self.openAiClient = OpenAI(api_key=self.config.get("openai_key"),
                                   base_url=self.config.get("openai_base"))

    def answer(self, msg: WxMsg, wx_wxid: Optional[str] = None) -> str:
        rsp = ""
        try:
            messages = [
                {"role": "user", "content": msg.content}
            ]
            rsp = self._client_reply(self.openAiClient, messages)
            self.LOG.info(rsp)
        except AuthenticationError:
            self.LOG.error("OpenAI API 认证失败，请检查 API 密钥是否正确")
        except APIConnectionError:
            self.LOG.error("无法连接到 OpenAI API，请检查网络连接")
        except APIError as e1:
            self.LOG.error(f"OpenAI API 返回了错误：{str(e1)}")
        except Exception as e0:
            self.LOG.error(f"发生未知错误：{str(e0)}")
        return rsp

    def _client_reply(self, client: OpenAI, messages: list, sender: Optional[str] = None, roomid: Optional[str] = None):
        if sender is None and roomid is None:
            extra_body = {}
        else:
            chat_id = "chatId"
            if sender is not None:
                chat_id += "_" + sender
            if roomid is not None:
                chat_id += "_" + roomid
            extra_body = {
                "chatId": chat_id
            }
        extra_body = {}
        ret = client.chat.completions.create(
            model=self.config.get("open_ai_model", "gpt-4o"),
            max_tokens=self.config.get("open_ai_max_tokens", 8192),
            temperature=self.config.get("open_ai_temperature", 0.7),
            top_p=self.config.get("open_ai_top_p", 1),
            extra_body=extra_body,
            messages=messages
        )
        rsp = ret.choices[0].message.content
        rsp = rsp[2:] if rsp.startswith("\n\n") else rsp
        rsp = rsp.replace("\n\n", "\n")
        return rsp
