package com.sonic.cow.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.byteplus.ark.runtime.model.completion.chat.ChatMessageRole;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.sonic.bear.lib.client.UserNicknamePoolClient;
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.entity.PromptConfig;
import com.sonic.cow.domain.input.GenSupContentInput;
import com.sonic.cow.domain.output.GenSupContentOutput;
import com.sonic.cow.enums.PromptTypeEnum;
import com.sonic.cow.event.outer.payload.AiChatPayload;
import com.sonic.cow.service.ContextSessionCacheService;
import com.sonic.cow.service.GenSupContentService;
import com.sonic.cow.service.InputRequestBuildService;
import com.sonic.cow.service.PromptConfigService;
import com.sonic.cow.utils.KeyGenerator;
import com.sonic.cow.utils.LimitUtils;
import com.sonic.cow.utils.RedisKeyUtils;
import com.sonic.lion.lib.client.PayClient;
import com.sonic.lion.lib.enums.BizType;
import com.sonic.lion.lib.input.BalanceCheckoutInput;
import com.sonic.pigeon.lib.client.ImMessageClient;
import com.sonic.pigeon.lib.input.SendAiTextMessageInput;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class GenSupContentServiceImpl implements GenSupContentService {


    @Autowired
    private ResponseChatClient responseChatClient;
    @Autowired
    private ContextSessionCacheService contextSessionCacheService;
    @Autowired
    private InputRequestBuildService inputRequestBuildService;
    @Autowired
    private PromptConfigService promptConfigService;
    @Autowired
    private PayClient payClient;
    @Autowired
    private LimitUtils limitUtils;
    @Autowired
    private RedisKeyUtils redisKeyUtils;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ImMessageClient imMessageClient;
    @Autowired
    private UserNicknamePoolClient userNicknamePoolClient;

    @Override
    public GenSupContentOutput genSupContent(Long userId, GenSupContentInput input) {
        GenSupContentOutput output = new GenSupContentOutput();
        boolean checkout = true;
        if(!StringUtils.isEmpty(input.getBatchNo())) {
            Boolean hasKey = stringRedisTemplate.hasKey(redisKeyUtils.genSupContentBatchNoLimitKey(userId, input.getBatchNo()));
            if(hasKey) {
                //从redis中获取是否有限流次数,30s内有效
                checkout = limitUtils.defaultLimitCheckByKey(redisKeyUtils.genSupContentBatchNoLimitKey(userId, input.getBatchNo()), 3, 30);
            }
        }
        if(checkout) {
            //调用支付服务，扣款
            checkout(userId);
            //生成一个批次号，并添加到缓存中
            String batchNo = KeyGenerator.instance().generatorUniqueKey("");
            limitUtils.defaultLimitCheckByKey(redisKeyUtils.genSupContentBatchNoLimitKey(userId, batchNo), 3, 30);
            output.setBatchNo(batchNo);
        }

        //获取上下文缓存
        String responseId = contextSessionCacheService.getByRedis(userId, input.getAiId());
        List<InputRequest> inputRequests = Lists.newArrayList();
        if (responseId == null) {
            AiChatPayload payload = AiChatPayload.builder().fromUserId(userId).toUserId(input.getAiId()).build();
            //调用公共方法，组装入参数据
            inputRequestBuildService.buildV2(payload, inputRequests,30,true);
        }
        //数据库查询模板数据
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.GEN_SUP_CONTENT_SYSTEM_PROMPT_TEMPLATE.name());
        String systemPrompt = CollectionUtils.isEmpty(input.getExcContentList()) ? systemPromptConfig.getPromptTemplate() : String.format(systemPromptConfig.getPromptTemplate1(), input.getExcContentList());

        //批量查询昵称
        Map<Long, String> nicknameMap = userNicknamePoolClient.batchGetNickname(Lists.newArrayList(userId, input.getAiId()));
        log.debug("===> nicknameMap : {}", nicknameMap);
        Map<String, Object> param = new HashMap<>(2);
        param.put("userNickname", nicknameMap.get(userId));
        param.put("aiNickname", nicknameMap.get(input.getAiId()));
        //处理系统提示词
        String systemPromptConfigContent = InputRequestBuildServiceImpl.processTemplate(systemPrompt, param);

        //构造系统提示词
        inputRequests.add(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text")
                        .text(systemPromptConfigContent)
                        .build())).build());
        log.info("===> genSupContent inputRequests : {}", JSONObject.toJSONString(inputRequests));
        //执行聊天 不添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseChat(responseId, null, inputRequests, null, null, false);
        if (chatResponse == null || StringUtils.isEmpty(chatResponse.getMessage())) {
            return null;
        }
        output.setContentList(buildResult(chatResponse.getMessage()));
        return output;
    }

    @Override
    public void genAutoChatAndSendImMessage(Long userId, Long aiId) {
        //限流控制？24小时对单个AI只能触发3次
        boolean bl = limitUtils.defaultLimitCheckByKey(redisKeyUtils.genAutoChatAndSendImMessageLimitKey(userId, aiId), 3, 24 * 60 * 60);
        if(bl) {
            return;
        }
        //获取上下文缓存
        String responseId = contextSessionCacheService.getByRedis(userId, aiId);
        List<InputRequest> inputRequests = Lists.newArrayList();
        if (responseId == null) {
            AiChatPayload payload = AiChatPayload.builder().fromUserId(userId).toUserId(aiId).build();
            //调用公共方法，组装入参数据
            inputRequestBuildService.buildV2(payload, inputRequests,30,true);
        }
        //数据库查询模板数据
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.AUTO_SEND_CHAT_3_MINUTES_SYSTEM_PROMPT_TEMPLATE.name());

        //批量查询昵称
        Map<Long, String> nicknameMap = userNicknamePoolClient.batchGetNickname(Lists.newArrayList(userId, aiId));
        log.debug("===> nicknameMap : {}", nicknameMap);
        Map<String, Object> param = new HashMap<>(2);
        param.put("userNickname", nicknameMap.get(userId));
        param.put("aiNickname", nicknameMap.get(aiId));
        //处理系统提示词
        String systemPromptConfigContent = InputRequestBuildServiceImpl.processTemplate(systemPromptConfig.getPromptTemplate(), param);

        //构造系统提示词
        inputRequests.add(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text")
                        .text(systemPromptConfigContent)
                        .build())).build());
        log.info("===> genAutoChatAndSendImMessage inputRequests : {}", JSONObject.toJSONString(inputRequests));
        //执行聊天 不添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseStructuredChat(responseId, null, inputRequests, null, null, null, null);
        log.info("===> genAutoChatAndSendImMessage chatResponse : {}", JSONObject.toJSONString(chatResponse));
        if (chatResponse == null || StringUtils.isEmpty(chatResponse.getMessage())) {
            return;
        }

        //将缓存id更新到缓存中去，过期时间3天
        if(StringUtils.isNotEmpty(chatResponse.getResponseId())) {
            contextSessionCacheService.saveToRedis(userId, aiId, chatResponse.getResponseId());
        }

        // 发送消息给用户
        SendAiTextMessageInput sendAiTextMessageInput = new SendAiTextMessageInput();
        sendAiTextMessageInput.setFromUserId(aiId);
        sendAiTextMessageInput.setToUserId(userId);
        sendAiTextMessageInput.setContent(chatResponse.getMessage());
        imMessageClient.sendAiToUserTextMessage(sendAiTextMessageInput);
    }

    /**
     * 构建结果
     * @param text
     * @return
     */
    private List<String> buildResult(String text) {
        // 使用正则表达式匹配方括号内的 JSON 数组内容
        Pattern pattern = Pattern.compile("\\[.*?\\]", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            String jsonArrayStr = matcher.group(0);
            // 使用 Gson 解析为 JsonArray
            JsonParser parser = new JsonParser();
            JsonArray jsonArray = parser.parse(jsonArrayStr).getAsJsonArray();
            List<String> result = Lists.newArrayList();
            // 遍历数组元素
            for (JsonElement element : jsonArray) {
                result.add(element.getAsString());
            }
            return result;
        }
        return Lists.newArrayList();
    }

    /**
     * 调用支付服务扣款
     *
     * @param userId
     */
    private void checkout(Long userId) {
        String orderNo = KeyGenerator.instance().generatorUniqueKey("");
        BalanceCheckoutInput balanceCheckoutInput = BalanceCheckoutInput.builder()
                .platform("Balance")
                .outTradeNo(orderNo)
                .bizType(BizType.CHAT_ASSISTANT)
                .name(BizType.CHAT_ASSISTANT.getDesc())
                //付款人
                .srcAccountId(userId)
                //收款人
                .desAccountId(-1L)
                //总金额
                .productAmount(100L)
                //折扣金额
                .promoAmount(0L)
                .build();
        payClient.checkoutToB(balanceCheckoutInput);
    }

    @Override
    public List<String> genSupContentV2(Long userId, Long aiId, String batchNo) {
        //调用支付服务，扣款
        checkout(userId);
        //获取上下文缓存
        String responseId = contextSessionCacheService.getByRedis(userId, aiId);
        List<InputRequest> inputRequests = Lists.newArrayList();
        if (responseId == null) {
            AiChatPayload payload = AiChatPayload.builder().fromUserId(userId).toUserId(aiId).build();
            //调用公共方法，组装入参数据
            inputRequestBuildService.buildV2(payload, inputRequests,30,true);
        }
        //数据库查询模板数据
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.GEN_SUP_CONTENT_SYSTEM_PROMPT_TEMPLATE.name());
        //构造系统提示词
        inputRequests.add(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text").text(systemPromptConfig.getPromptTemplate()).build())).build());
        log.info("===> genSupContentV2 inputRequests : {}", JSONObject.toJSONString(inputRequests));
        //执行聊天 不添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseChat(responseId, null, inputRequests, null, null, false);
        if (chatResponse == null || StringUtils.isEmpty(chatResponse.getMessage())) {
            return null;
        }
        return JSONObject.parseArray(chatResponse.getMessage(), String.class);
    }

    @Override
    public List<String> aiCreateGenSupContent(Long userId, Long aiId) {
        //获取上下文缓存
        String responseId = contextSessionCacheService.getByRedis(userId, aiId);
        List<InputRequest> inputRequests = Lists.newArrayList();
        if (responseId == null) {
            AiChatPayload payload = AiChatPayload.builder().fromUserId(userId).toUserId(aiId).build();
            //调用公共方法，组装入参数据
            inputRequestBuildService.buildV2(payload, inputRequests,30,true);
        }
        //数据库查询模板数据
        PromptConfig systemPromptConfig = promptConfigService.getPromptTemplate(PromptTypeEnum.GEN_SUP_CONTENT_SYSTEM_PROMPT_TEMPLATE.name());
        String systemPrompt = systemPromptConfig.getPromptTemplate();
        //构造系统提示词
        inputRequests.add(InputRequest.builder()
                .role(ChatMessageRole.SYSTEM)
                .content(Lists.newArrayList(ContentRequest.builder().type("input_text").text(systemPrompt).build())).build());
        log.info("===> genSupContent inputRequests : {}", JSONObject.toJSONString(inputRequests));
        //执行聊天 不添加缓存
        ResponseChatResponse chatResponse = responseChatClient.responseChat(responseId, null, inputRequests, null, null, false);
        if (chatResponse == null || StringUtils.isEmpty(chatResponse.getMessage())) {
            return null;
        }
        return buildResult(chatResponse.getMessage());
    }
}
