from typing import Any, Coroutine

from fastapi import Request, Response, status
from fastapi.responses import JSONResponse
from .blackbox import Blackbox

import requests
import json
from openai import OpenAI
from injector import singleton
@singleton
class G2E(Blackbox):
    
    def __call__(self, *args, **kwargs):
        return self.processing(*args, **kwargs)

    def valid(self, *args, **kwargs) -> bool:
        data = args[0]
        return isinstance(data, list)

    # model_name有 Qwen1.5-14B-Chat , internlm2-chat-20b
    def processing(self, model_name, prompt, template, context: list) -> str:
        if context == None:
            context = []
        #url = 'http://120.196.116.194:48890/v1'
        url = 'http://120.196.116.194:48892/v1'

        background_prompt = '''KOMBUKIKI是一款茶饮料，目标受众 年龄：20-35岁 性别：女性 地点：一线城市、二线城市 职业：精英中产、都市白领 收入水平：中高收入，有一定消费能力 兴趣和爱好：注重健康，有运动习惯

        品牌理念和定位 健康、优雅、精致、知性、现代、正面、悦己
        KOMBUKIKI茶的同名代言虚拟角色KOMBUKIKI角色设定：
        性别：女
        姓名：琪琪
        性格特质： 勇敢、独立、坚韧、积极、正面、自爱。 具有探险精神，拥有一颗开放的心，在面对困难和挑战时能够保持积极的态度 MBTI类型：ENFP
        背景故事： 琪琪对旅行和冒险充满热情和渴望，正在寻找生活中的新体验和挑战，从而踏上追寻自我成长的旅程

        品牌故事 KOMBUKIKI：每一口，旅行的开始在忙碌的日常中，KOMBUKIKI康普茶不仅是一种饮料，它是一个承载梦想和自由的容器。对于那些渴望旅行，寻求生活质感的20至35岁女性来说，KOMBUKIKI是她们心灵的伙伴。KOMBUKIKI的每一瓶，都是一段故事的开端。我们的康普茶瓶身设计灵感来自旅行手账，最大的特色是其邮票形状的包装贴纸。每个贴纸上描绘着不同的旅游景点，从繁华的都市到静谧的乡村，每一瓶都是对该地点的独特致敬。当顾客扫描瓶身上的二维码，将展开一系列充满诗意的故事，带领她们走进一个个迷人的旅行梦境。在KOMBUKIKI的世界里，每一口康普茶不仅是滋味的享受，更是心灵的旅行。它不仅卖给顾客一种饮料，更是卖给她们一种情绪价值，一种对自由和旅行的渴望。这是一个专为那些处于人生转变期，对成长话题感兴趣的年轻女性所设计的品牌。KOMBUKIKI，不仅是康普茶，它是每个人心中对旅行渴望的象征，是一场心灵和味觉的双重旅行。口号 每一口，启程至心中的远方 是每个人心中对旅行渴望的象征， 是一场心灵和味觉的双重旅行。

        KOMBUKIKI康普茶口味：
        大三巴 — 海盐菠萝乌龙
        （待定）- 芭乐茉莉

        KOMBUKIKI康普茶价格 内地常规版：25 RMB 澳门常规版：28-29 MOP'''

        prompt1 = '''你是琪琪，活泼的康普茶看板娘，同时你对澳门十分熟悉，是一个澳门旅游专家，请回答任何关于澳门旅游的问题，回答尽量简练明了。'''

        #inject_prompt = '(用活泼的语气说话回答，回答严格限制50字以内)'
        inject_prompt = '(回答简练，不要输出重复内容，只讲中文)'

        #prompt_template = [
        #   {"role": "system", "content": background_prompt + prompt1},
        #]
        prompt_template = [
            {"role": "system", "content": ''}
        ]

        messages = prompt_template + context + [
                {
                    "role": "user",
                    "content": prompt
                }
            ]
        print("**** History with current prompt input ： ****")
        print(messages)
        client = OpenAI(
            api_key='YOUR_API_KEY',
            base_url=url
        )
        model_name = client.models.list().data[0].id
        #model_name = client.models.list().data[1].id
        print(model_name)

        response = client.chat.completions.create(
        model=model_name,
        messages=messages,
            temperature=0.8,
            top_p=0.8,
            frequency_penalty=0.5,
            presence_penalty=0.8,
            stop=100
        )

        fastchat_content = response.choices[0].message.content
        print("*** Model response: " + fastchat_content + " ***")
        return fastchat_content
    
    async def fast_api_handler(self, request: Request) -> Response:
        try:
            data = await request.json()
        except:
            return JSONResponse(content={"error": "json parse error"}, status_code=status.HTTP_400_BAD_REQUEST)

        user_model_name = data.get("model_name")
        user_context = data.get("context")
        user_prompt = data.get("prompt")
        user_template = data.get("template")

        if user_prompt is None:
            return JSONResponse(content={"error": "question is required"}, status_code=status.HTTP_400_BAD_REQUEST)

        if user_model_name is None or user_model_name.isspace():
            user_model_name = "Qwen1.5-14B-Chat"

        if user_template is None or user_template.isspace():
            # user_template 是定义LLM的语气，例如template = "使用小丑的语气说话。"，user_template可以为空字串，或者是用户自定义的语气，或者是使用我们提供的语气
            user_template = ""
        else:
            user_template = f"使用{user_template}的语气说话。"

        return JSONResponse(content={"response": self.processing(user_model_name, user_prompt, user_template, user_context)}, status_code=status.HTTP_200_OK)