package com.fs.fastgptApi.util;

import com.fs.common.core.domain.entity.SysDictData;
import com.fs.fastGpt.domain.FastGptEventLog;
import com.fs.fastGpt.domain.FastGptEventTokenLog;
import com.fs.fastGpt.service.IFastGptChatMsgService;
import com.fs.fastgptApi.result.AiImgResult;
import com.fs.fastgptApi.result.ChatDetailFStreamFResult;
import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
import com.fs.qw.domain.QwUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static com.fs.common.utils.DictUtils.getDictCache;

@Component
@Slf4j
public class EventLogUtils {

    private static IFastGptChatMsgService fastGptChatMsgService;

    @Autowired
    public void setFastGptChatMsgService(IFastGptChatMsgService service) {
        EventLogUtils.fastGptChatMsgService = service;
    }

    @Scheduled(fixedDelay = 200)
    public void consumeLogs() {
        FastGptEventLog eventLog;
        while ((eventLog = EventLogQueue.pollEventLog()) != null) {
            try {
                fastGptChatMsgService.insertFastGptEventLog(eventLog);
            } catch (Exception e) {
                // 记录失败日志，可加入重试机制
                log.error("Ai事件日志写入失败：" + eventLog, e);
            }
        }

        FastGptEventTokenLog tokenLog;
        while ((tokenLog = EventLogQueue.pollEventTokenLog()) != null) {
            try {
                fastGptChatMsgService.insertFastGptEventTokenLog(tokenLog);
            } catch (Exception e) {
                log.error("Ai的token事件日志写入失败：" + eventLog, e);
            }
        }
    }

    /**
     *  记录ai事件日志
     * @param count     触发数量
     * @param type      事件类型(1互动 1总对话 3转人工 4AI无法回复转人工 5AI回复不合适转人工 6完课回复 7物流事件 8图片回复 9自定义事件回复 10用户未回复AI再次提醒)
     * @param user      企微用户
     */
    public static void recordEventLog(Long senderId, Long count, Integer type, QwUser user) {
        List<SysDictData> dictCache = getDictCache("sys_fastgpt_event_log_type");
        String content = "未知事件";
        if(dictCache != null){
            for (SysDictData sysDictData : dictCache) {
                if (type.toString().equals(sysDictData.getDictValue())){
                    content = sysDictData.getDictLabel();
                }
            }
        }
        FastGptEventLog fastGptEventLog = new FastGptEventLog();
        fastGptEventLog.setEventName(content);
        fastGptEventLog.setSenderId(senderId);
        fastGptEventLog.setRoleId(user.getFastGptRoleId());
        fastGptEventLog.setCount(count);
        fastGptEventLog.setType(type);
        fastGptEventLog.setCompanyId(user.getCompanyId());
        fastGptEventLog.setCompanyUserId(user.getCompanyUserId());
        fastGptEventLog.setQwUserId(user.getId());
        fastGptEventLog.setCreateTime(new Date());


        EventLogQueue.addEventLog(fastGptEventLog); // 入队
        //fastGptChatMsgService.insertFastGptEventLog(fastGptEventLog);
    }

    /**
     * 记录ai事件token消耗日志
     * @param content       事件名称
     * @param eventType     事件类型(1文字 2图片 3...)
     * @param tokenCount    token数量
     * @param tokenType     token类型(1输入 2输出)
     * @param user
     */
    public static void recordEventTokenLog(String content,Long senderId,Integer eventType, Long tokenCount, Integer tokenType, QwUser user) {
        FastGptEventTokenLog fastGptEventTokenLog = new FastGptEventTokenLog();
        fastGptEventTokenLog.setEventName(content);
        fastGptEventTokenLog.setSenderId(senderId);
        fastGptEventTokenLog.setRoleId(user.getFastGptRoleId());
        fastGptEventTokenLog.setEventType(eventType);
        fastGptEventTokenLog.setTokenCount(tokenCount);
        fastGptEventTokenLog.setTokenType(tokenType);
        fastGptEventTokenLog.setCompanyId(user.getCompanyId());
        fastGptEventTokenLog.setCompanyUserId(user.getCompanyUserId());
        fastGptEventTokenLog.setQwUserId(user.getId());
        fastGptEventTokenLog.setCreateTime(new Date());

        EventLogQueue.addEventTokenLog(fastGptEventTokenLog); // 入队
        //fastGptChatMsgService.insertFastGptEventTokenLog(fastGptEventTokenLog);
    }

    public static void createEventTokenLog(String content,QwUser user,Long senderId,ChatDetailTStreamFResult result) {

        //计算token
        List<ChatDetailTStreamFResult.ResponseNode> responseData = result.getResponseData();
        Long totalTokens = 0L;
        for (ChatDetailTStreamFResult.ResponseNode responseDatum : responseData) {
            int tokens = responseDatum.getTokens();
            totalTokens+=tokens;
        }
        recordEventTokenLog(content + "消耗token",senderId,2,totalTokens,0, user);

        Long promptTokens = (long) result.getUsage().getPrompt_tokens();
        recordEventTokenLog(content + "输入token",senderId,2,promptTokens,1, user);

        Long completionTokens = (long) result.getUsage().getCompletion_tokens();
        recordEventTokenLog(content + "输出token",senderId,2,completionTokens,2, user);
    }


    public static void createEventTokenLog(String content,QwUser user,Long senderId,ChatDetailFStreamFResult result) {

        Long totalTokens = (long) result.getUsage().getTotalTokens();
        recordEventTokenLog(content + "消耗token",senderId,2,totalTokens,0, user);

        Long promptTokens = (long) result.getUsage().getPromptTokens();
        recordEventTokenLog(content + "输入token",senderId,2,promptTokens,1, user);

        Long completionTokens = (long) result.getUsage().getCompletionTokens();
        recordEventTokenLog(content + "输出token",senderId,2,completionTokens,2, user);
    }

    public static void createEventTokenLog(String content,QwUser user,Long senderId,AiImgResult result) {

        Long totalTokens = (long) result.getUsage().getTotal_tokens();
        recordEventTokenLog(content + "消耗token",senderId,2,totalTokens,0, user);

        Long promptTokens = (long) result.getUsage().getPrompt_tokens();
        recordEventTokenLog(content + "输入token",senderId,2,promptTokens,1, user);

        Long completionTokens = (long) result.getUsage().getCompletion_tokens();
        recordEventTokenLog(content + "输出token",senderId,2,completionTokens,2, user);
    }

}
