package com.sonic.cow.controller.mock;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.byteplus.ark.runtime.model.completion.chat.ChatMessage;
import com.byteplus.ark.runtime.model.completion.chat.ChatMessageRole;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sonic.common.rpc.Result;
import com.sonic.cow.client.ContextChatClient;
import com.sonic.cow.client.DeepSeekClient;
import com.sonic.cow.client.ImageGenImageClient;
import com.sonic.cow.client.ResponseChatClient;
import com.sonic.cow.client.request.ContentRequest;
import com.sonic.cow.client.request.InputRequest;
import com.sonic.cow.client.response.ResponseChatResponse;
import com.sonic.cow.domain.bo.AiGen4Bo;
import com.sonic.cow.domain.bo.TextGenImagePromptParse;
import com.sonic.cow.domain.bo.TextPromptParse;
import com.sonic.cow.domain.entity.PromptConfig;
import com.sonic.cow.domain.input.AiGenMockInput;
import com.sonic.cow.domain.input.GenAiUserContentV1Input;
import com.sonic.cow.domain.input.GenSupContentInput;
import com.sonic.cow.domain.input.MockInput;
import com.sonic.cow.enums.PromptTypeEnum;
import com.sonic.cow.event.outer.payload.AiChatPayload;
import com.sonic.cow.service.*;
import com.sonic.cow.service.impl.GenAiUserContentServiceImpl;
import com.sonic.frog.lib.client.AiClient;
import com.sonic.frog.lib.client.AiUserAlbumClient;
import com.sonic.frog.lib.output.AIUserAlbumApiOutput;
import com.sonic.frog.lib.output.AiInfoApiOutput;
import com.sonic.pigeon.lib.client.ImMessageClient;
import com.sonic.pigeon.lib.input.SendAiTextMessageInput;
import com.sonic.sdk.api.annotation.IgnoreAuth;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author code
 * @Description TODO
 * @Date 2024/1/8 11:06
 * @Version 1.0
 */
@RestController
@Slf4j
public class MockController {

    @Autowired
    private GenAiUserContentService genAiUserContentService;
    @Autowired
    private ImageGenImageClient imageGenImageClient;
    @Autowired
    private GenSupContentService genSupContentService;
    @Autowired
    private ContextSessionCacheService contextSessionCacheService;
    @Autowired
    private DeepSeekClient deepSeekClient;
    @Autowired
    private ContextChatClient contextChatClient;
    @Autowired
    private InputRequestBuildService inputRequestBuildService;
    @Autowired
    private PromptConfigService promptConfigService;
    @Autowired
    private ResponseChatClient responseChatClient;
    @Autowired
    private ChatHandlerService chatHandlerService;
    @Autowired
    private AiUserAlbumClient aiUserAlbumClient;
    @Autowired
    private ImMessageClient imMessageClient;
    @Autowired
    private AiClient aiClient;


    @IgnoreAuth
    @PostMapping(value = "/mock/textGenImage6Prompt")
    @ApiOperation(value = "文生图-生成6组不同promp测试", tags = {"mock"})
    public Result textGenImage6Prompt() {
        String promptType = PromptTypeEnum.TEXT_TO_IMAGE_PROMPT.name();
        HashMap<String, Object> map = Maps.newHashMap();
        map.put("content", "花园中漫步的漂亮女孩");
        map.put("imageStylePrompt", "manga style, clean black outlines, expressive face, large eyes, halftone shading, cell shading,black and white,");
        map.put("commonImagePrompt", "caucasian features, western facial structure, proportional anatomy, highly detailed, ultra high resolution, 8k, masterpiece, professional studio lighting, cinematic lighting, volumetric shadows, master piece");
        TextGenImagePromptParse textGenImagePromptParse = null;
        try {
            textGenImagePromptParse = genAiUserContentService.genContent(promptType, map, TextGenImagePromptParse.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return Result.success(textGenImagePromptParse);
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/imageGenImage")
    @ApiOperation(value = "图生图-测试", tags = {"mock"})
    public Result imageGenImageMock() {
        String imageUrl = "https://b0.bdstatic.com/ugc/aBlDFCWKxpvg5MW1yQHnAA1bb451086e5ebe96d8bc3c1e63c91211.jpg";
        String imageBase64 = null;
        try {
            imageBase64 = imageGenImageClient.imageGenImage(imageUrl, "大学生模样，走在校园里");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        log.info("imageGenImageMock imageBase64:{}", imageBase64);
        return Result.success(imageBase64);
    }

    @IgnoreAuth
    @ApiOperation(value = "生成辅助对话内容", tags = {"WEB-AI一键生成"})
    @RequestMapping(value = "/mock/gen/sup-content", produces = {"application/json"}, method = RequestMethod.POST)
    public Result<List<String>> genSupContent(@Validated @RequestBody GenSupContentInput input) {
        return Result.success(genSupContentService.genSupContent(438933526413313L, input));
    }

    @IgnoreAuth
    @ApiOperation(value = "生成辅助对话内容", tags = {"WEB-AI一键生成"})
    @RequestMapping(value = "/mock/gen/sup-content-v2", produces = {"application/json"}, method = RequestMethod.POST)
    public Result<List<String>> aiGenSupContentV2(@Validated @RequestBody GenSupContentInput input) {
        return Result.success(genSupContentService.genSupContentV2(438933526413313L, input.getAiId(), null));
    }

    @IgnoreAuth
    @ApiOperation(value = "删除redis缓存", tags = {"WEB-AI一键生成"})
    @RequestMapping(value = "/mock/response/redis-del", produces = {"application/json"}, method = RequestMethod.POST)
    public Result<Void> redisDelResponse(@Validated @RequestBody MockInput input) {
        contextSessionCacheService.deleteRedis(input.getUserId(), input.getAiId());
        return Result.success();
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/chat-score")
    @ApiOperation(value = "根据聊天记录进行情绪价值打分", tags = {"mock"})
    public Result chatScoreMock() {
        String promptType = PromptTypeEnum.CHAT_SCORE_SYSTEM_PROMPT_TEMPLATE.name();
        List<ChatMessage> messages = Lists.newArrayList();
        messages.add(ChatMessage.builder()
                .role(ChatMessageRole.ASSISTANT)
                .content("我喜欢你")
                .build());
        messages.add(ChatMessage.builder()
                .role(ChatMessageRole.ASSISTANT)
                .content("嘻嘻，我也喜欢你")
                .build());
        HashMap<String, Object> map = Maps.newHashMap();
        map.put("content", JSON.toJSONString(messages));
        TextPromptParse textPromptParse = null;
        try {
            textPromptParse = genAiUserContentService.genContent(promptType, map, TextPromptParse.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return Result.success(textPromptParse);
    }


    @IgnoreAuth
    @PostMapping(value = "/mock/doubao/aiGen")
    @ApiOperation(value = "使用doubao模型来测试一键生成", tags = {"mock"})
    public Result<String> doubaoAiGen(@RequestBody AiGenMockInput input) {
        return Result.success(contextChatClient.aiGen(input.getSystemPrompt(), input.getTemperatur()));
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/deepSeek/aiGen")
    @ApiOperation(value = "使用deepSeek模型来测试一键生成", tags = {"mock"})
    public Result<String> deepSeekAiGen(@RequestBody AiGenMockInput input) {
        return Result.success(deepSeekClient.aiGen(input.getSystemPrompt(), input.getTemperatur()));
    }


    @IgnoreAuth
    @PostMapping(value = "/mock/buildSystemPromptContent")
    @ApiOperation(value = "构造系统提示词", tags = {"mock"})
    public Result<String> buildSystemPromptContent(@RequestBody AiGenMockInput input) {
        AiInfoApiOutput aiUserInfo = aiClient.getAiInfo(input.getAiId());
        return Result.success(inputRequestBuildService.buildSystemPromptContent(input.getFromUserId(), input.getAiId(), aiUserInfo));
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/buildVoiceChatSystemPromptContent")
    @ApiOperation(value = "构造语音系统提示词", tags = {"mock"})
    public Result<String> buildVoiceChatSystemPromptContent(@RequestBody AiGenMockInput input) {
        AiInfoApiOutput aiUserInfo = aiClient.getAiInfo(input.getAiId());
        return Result.success(inputRequestBuildService.buildVoiceChatSystemPromptContent(input.getFromUserId(), input.getAiId(), aiUserInfo));
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/autoChat")
    @ApiOperation(value = "24小时自动发起聊天内容", tags = {"mock"})
    public Result<ResponseChatResponse> autoChat(@RequestBody AiGenMockInput input) {
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.AUTO_SEND_CHAT_SYSTEM_PROMPT_TEMPLATE.name());
        Long fromUserId = input.getFromUserId();
        Long toUserId = input.getAiId();
        //获取上下文缓存 这个缓存一定是存在的
        String responseId = contextSessionCacheService.getByRedis(fromUserId, toUserId);
        log.info("===> autoChat responseId : {}", responseId);
        //构造系统提示词
        List<InputRequest> inputRequests = Lists.newArrayList(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text").text(systemPromptConfig.getPromptTemplate()).build())).build());
        //执行聊天 不将添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseStructuredChat(responseId, null, inputRequests, null, false);
        // 发送消息给用户
        SendAiTextMessageInput sendAiTextMessageInput = new SendAiTextMessageInput();
        sendAiTextMessageInput.setFromUserId(toUserId);
        sendAiTextMessageInput.setToUserId(fromUserId);
        sendAiTextMessageInput.setContent(chatResponse.getMessage());
        imMessageClient.sendAiToUserTextMessage(sendAiTextMessageInput);
        //发送IM消息
        log.info("===> chatResponse : {}", chatResponse);
        return Result.success(chatResponse);
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/genStartVoiceChatDialoguePrologue")
    @ApiOperation(value = "生成语音通话开场白", tags = {"mock"})
    public Result<ResponseChatResponse> genStartVoiceChatDialoguePrologue(@RequestBody AiGenMockInput input) {
        Long fromUserId = input.getFromUserId();
        Long toUserId = input.getAiId();
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.START_VOICE_CHAT_DIALOGUE_PROLOGUE.name());
        //获取上下文缓存 这个缓存一定是存在的
        String responseId = contextSessionCacheService.getByRedis(fromUserId, toUserId);
        List<InputRequest> inputRequests = Lists.newArrayList();
        if (StringUtils.isEmpty(responseId)) {
            AiChatPayload payload = AiChatPayload.builder().fromUserId(fromUserId).toUserId(toUserId).build();
            //调用公共方法，组装入参数据
            inputRequestBuildService.buildV2(payload, inputRequests, 50,true);
        }
        //构造系统提示词
        inputRequests.add(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text").text(systemPromptConfig.getPromptTemplate()).build())).build());
        //执行聊天 不将添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseStructuredChat(responseId, null, inputRequests, null, false);
        log.info("===> genStartVoiceChatDialoguePrologue chatResponse : {}", chatResponse);
        return Result.success(chatResponse);
    }


    @IgnoreAuth
    @PostMapping(value = "/mock/chat-send-album")
    @ApiOperation(value = "生成语音通话开场白", tags = {"mock"})
    public Result<Void> sendAlbum(@RequestBody AiGenMockInput input) {
        AIUserAlbumApiOutput album = aiUserAlbumClient.getRandomLockImage(input.getUserId(), input.getAiId());
        AiChatPayload payload = AiChatPayload.builder().fromUserId(input.getFromUserId()).toUserId(input.getAiId()).build();
        ResponseChatResponse chatResponse = ResponseChatResponse.builder().message("自定义图片消息").score(new BigDecimal(0.1)).build();
        chatHandlerService.sendImCustomMessage(payload, "自定义图片消息", album, chatResponse);
        return Result.success();
    }

    @IgnoreAuth
    @PostMapping(value = "/mock/set6PromptTemplate")
    @ApiOperation(value = "配置生成6组不同的prompt的模板", tags = {"mock"})
    public Result<Void> set6PromptTemplate(@RequestBody AiGenMockInput input) {
        PromptConfig promptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.TEXT_TO_IMAGE_PROMPT.name());
        promptConfig.setPromptTemplate(input.getSystemPrompt());
        promptConfig.setTemperature(input.getTemperatur());
        promptConfigService.updateById(promptConfig);
        return Result.success();
    }

    @IgnoreAuth
    @ApiOperation(value = "提取json内容", tags = {"WEB-AI一键生成"})
    @RequestMapping(value = "/mock/ext/json", produces = {"application/json"}, method = RequestMethod.POST)
    public Result<Object> extJson(@Validated @RequestBody GenAiUserContentV1Input input) throws Exception {
        PromptConfig promptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.EXTRACT_JSON_CONTENT.name());
        //系统提示词替换(根据参数名替换)
        Map<String, Object> data = JSONObject.parseObject(JSONObject.toJSONString(input), Map.class);
        String formatted = GenAiUserContentServiceImpl.processTemplate(promptConfig.getPromptTemplate(), data);
        AiGen4Bo bo = contextChatClient.aiGen4(formatted, promptConfig.getModel(), promptConfig.getTemperature(), promptConfig.getTopp());
        return Result.success(bo);
    }


    @IgnoreAuth
    @ApiOperation(value = "聊天提示词", tags = {"WEB-聊天"})
    @RequestMapping(value = "/mock/chat/prompt", produces = {"application/json"}, method = RequestMethod.POST)
    public Result<Object> chatPrompt(@Validated @RequestBody AiChatPayload input) throws Exception {
        List<InputRequest> inputRequests = Lists.newArrayList();
        inputRequestBuildService.buildV2(input, inputRequests,100,true);
        return Result.success(inputRequests);
    }

    @IgnoreAuth
    @ApiOperation(value = "一键生成", tags = {"API-接口"})
    @PostMapping("/mock/gen/user-content")
    public Result<String> genUserContent(@RequestBody GenAiUserContentV1Input input) throws Exception {
        return Result.success(genAiUserContentService.genAiUserContentV1(-1L, input).getContent());
    }

}
