package com.fs.fastGpt.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.fs.common.annotation.Excel;
import com.fs.common.config.FSConfig;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.company.domain.CompanyConfig;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyConfigMapper;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.config.ai.AiHostProper;
import com.fs.config.cloud.CloudHostProper;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.mapper.FsCourseWatchLogMapper;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.course.param.FsCourseLinkCreateParam;
import com.fs.course.service.IFsCourseLinkService;
import com.fs.course.vo.FsCourseWatchLogVO;
import com.fs.crm.domain.CrmMsg;
import com.fs.crm.service.ICrmMsgService;
import com.fs.fastGpt.config.ModeConfig;
import com.fs.fastGpt.domain.*;
import com.fs.fastGpt.mapper.FastGptChatReplaceWordsMapper;
import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
import com.fs.fastGpt.param.SendAIParam;
import com.fs.fastGpt.service.*;
import com.fs.fastgptApi.param.ChatParam;
import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
import com.fs.fastgptApi.result.KnowledgeBaseResult;
import com.fs.fastgptApi.service.ChatService;
import com.fs.fastgptApi.service.Impl.AudioServiceImpl;
import com.fs.fastgptApi.util.AiImgUtil;
import com.fs.fastgptApi.util.EventLogUtils;
import com.fs.fastgptApi.vo.AudioVO;
import com.fs.his.domain.FsStoreOrder;
import com.fs.his.dto.ExpressInfoDTO;
import com.fs.his.dto.TracesDTO;
import com.fs.his.enums.ShipperCodeEnum;
import com.fs.his.mapper.FsStoreMapper;
import com.fs.his.mapper.FsStoreOrderMapper;
import com.fs.his.service.IFsExpressService;
import com.fs.his.service.IFsStoreOrderService;
import com.fs.his.utils.ConfigUtil;
import com.fs.hisStore.enums.SysConfigEnum;
import com.fs.im.dto.OpenImMsgDTO;
import com.fs.im.vo.OpenImMsgCallBackVO;
import com.fs.qw.domain.*;
import com.fs.qw.mapper.*;
import com.fs.qw.param.QwAutoTagsRulesTags;
import com.fs.qw.service.*;
import com.fs.qwApi.domain.QwResult;
import com.fs.qwApi.param.QwEditUserTagParam;
import com.fs.qwApi.param.QwSendMsgParam;
import com.fs.qwApi.service.QwApiService;
import com.fs.qwHookApi.param.QwHookSendMsgParam;
import com.fs.qwHookApi.vo.QwHookMsgVO;
import com.fs.qwHookApi.vo.QwHookVO;
import com.fs.sop.domain.QwSopLogs;
import com.fs.sop.mapper.QwSopLogsMapper;
import com.fs.utils.SensitiveDataUtils;
import com.fs.voice.utils.StringUtil;
import com.fs.wxwork.dto.*;
import com.fs.wxwork.service.WxWorkService;
import com.vdurmont.emoji.EmojiParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.sql.Time;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.fs.his.utils.PhoneUtil.decryptPhone;

@Slf4j
@Service
public class AiHookServiceImpl implements AiHookService {
    @Autowired
    private FastGptChatSessionMapper fastGptChatSessionMapper;
    @Autowired
    private ChatService chatService;
    @Autowired
    private QwUserMapper qwUserMapper;
    @Autowired
    private IFastGptRoleService roleService;
    @Autowired
    private QwExternalContactInfoMapper qwExternalContactInfoMapper;
    @Autowired
    private IFastGptChatMsgService fastGptChatMsgService;
    @Autowired
    private IQwContactWayService qwContactWayService;
    @Autowired
    QwApiService qwApiService;
    @Autowired
    QwCompanyMapper qwCompanyMapper;

    @Autowired
    private IQwExternalErrRetryService errRetryService;
    @Autowired
    QwAutoTagsMapper qwAutoTagsMapper;
    @Autowired
    FsCourseWatchLogMapper fsCourseWatchLogMapper;
    @Autowired
    FsUserCourseVideoMapper fsUserCourseVideoMapper;
    @Autowired
    FsCourseWatchLogMapper   watchLogMapper;

    @Autowired
    QwAutoTagsLogsMapper qwAutoTagsLogsMapper;
    @Autowired
    IQwJsApiService qwGetJsapiTicketService;
    @Autowired
    private IFsCourseLinkService iFsCourseLinkService;
    @Autowired
    FastgptChatVoiceHomoMapper fastgptChatVoiceHomoMapper;
    @Autowired
    RedisCache redisCache;
    @Autowired
    private IQwUserService qwUserService;
    @Autowired
    IQwWorkTaskService qwWorkTaskService;
    @Autowired
    AiImgUtil aiImgUtil;
    @Autowired
    private QwExternalContactMapper qwExternalContactMapper;
    @Autowired
    private IQwMsgService qwMsgService;
    @Autowired
    private IQwTagGroupService qwTagGroupService;
    @Autowired
    private FastGptChatReplaceWordsMapper fastGptChatReplaceWordsMapper;
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    WxWorkService wxWorkService;

    @Autowired
    AiHostProper aiHostProper;

    //    @Autowired
//    private IFastGptKeywordSendService fastGptKeywordSendService;
    @Autowired
    FsStoreOrderMapper fsStoreOrderMapper;
    @Autowired
    private IFastGptKeywordSendService fastGptKeywordSendService;
    @Autowired
    private IFsStoreOrderService storeOrderService;
    @Autowired
    private IFsExpressService expressService;
    @Autowired
    private CompanyConfigMapper companyConfigMapper;
    @Autowired
    private IFastGptChatReplaceTextService fastGptChatReplaceTextService;
    @Autowired
    private ICrmMsgService crmMsgService;

    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Autowired
    private CloudHostProper cloudHostProper;

    private static final String AI_REPLY = "AI_REPLY:";
    private static final String AI_REPLY_TAG = "AI_REPLY_TAG:";

    private final String DELAY_MSG = "delayMsg";
    @Autowired
    private ConfigUtil configUtil;


    /** Ai半小时未回复提醒 **/
    /**
     *
     * sender    像是fastgpt_chat_msg中的user_id字段
     * receiver     qw_user表中的vid字段
     * uuid         qw_user表中的uid字段
     * type  fasgpt_chat_msg中的msg_type字段
     * @return
     */
    @Override
    public R AiRemind() {
        List<FastGptChatSession> fastGptChatSessions = fastGptChatSessionMapper.selectFastGptChatSessionByRemind();
        if(fastGptChatSessions != null && !fastGptChatSessions.isEmpty()){
            for (FastGptChatSession fastGptChatSession : fastGptChatSessions) {
                String qwContent = "用户未回复";

                if(fastGptChatSession.getUserId() != null && fastGptChatSession.getQwUserId() != null){
                    Long sender = Long.valueOf(fastGptChatSession.getUserId());
                    Long qwUserId = fastGptChatSession.getQwUserId();
                    QwUser user = qwUserMapper.selectQwUserById(qwUserId);
                    //查询接收人
                    if(user==null){
                        System.out.println("查询接收人为空");
                        continue;
                    }
                    String uid = user.getUid();
                    if(user.getFastGptRoleId()==null){
                        System.out.println("未绑定角色");
                        continue;
                    }
                    Long serverId = user.getServerId();
                    System.out.println("服务器id"+serverId);
                    if (serverId == null) {
                        System.out.println("服务id为空");
                        continue;
                    }
                    FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(user.getFastGptRoleId());
                    //没用ai角色跳过
                    if(role==null){
                        System.out.println("没用ai角色跳过");
                        continue;
                    }
                    String modeConfig=role.getModeConfigJson();
                    //key不为空
                    if(StringUtils.isEmpty(modeConfig)){
                        System.out.println("没有aiKey");
                        continue;
                    }
                    ModeConfig config=JSONUtil.toBean(modeConfig,ModeConfig.class);
                    if(StringUtils.isEmpty(config.getAPPKey())){
                        System.out.println("没有aiKey");
                        continue;
                    }

                    QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactById(fastGptChatSession.getQwExtId());
                    if (qwExternalContacts==null){
                        System.out.println("没有外部联系人");
                        continue;
                    }
                    if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){

                        //判断是否转人工
                        if (fastGptChatSession.getIsArtificial()==1){
                            System.out.println("转人工了");
                            continue;
                        }
                        Long externalContactId = qwExternalContacts.getId();
                        QwExternalContactInfo contactInfo = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(externalContactId);
                        if(contactInfo != null && "非首次交流".equals(contactInfo.getTalk())){
                            System.out.println("该用户非首次交流extId:" + externalContactId);
                            continue;
                        }


                        //用户首次发送消息
                        redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),1,5,TimeUnit.MINUTES);
                        redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),qwContent,5,TimeUnit.MINUTES);
                        System.out.println("等待");
                        R r= sendAiMsg(1,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
                        System.out.println(r);
                        //完成对话 删除消息记录
                        redisCache.deleteObject("reply:" + fastGptChatSession.getSessionId());
                        redisCache.deleteObject("msg:" + fastGptChatSession.getSessionId());
                        if(!r.get("code").equals(200)){
                            //log.info("ai报错转人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
                            continue;
                        }

                        ChatDetailTStreamFResult result=(ChatDetailTStreamFResult)r.get("data");
                        EventLogUtils.createEventTokenLog("用户未回复AI再次提醒",user,sender,result);
                        EventLogUtils.recordEventLog(sender,1L,10,user);
                        //是否转人工
                        if(result.getChoices().isEmpty()){
                            continue;
                        }
                        String contentKh = result.getChoices().get(0).getMessage().getContent();
                        String content = replace(result.getChoices().get(0).getMessage().getContent()).trim();
                        //计算token
                        List<ChatDetailTStreamFResult.ResponseNode> responseData = result.getResponseData();
                        int token=0;
                        for (ChatDetailTStreamFResult.ResponseNode responseDatum : responseData) {
                            int tokens = responseDatum.getTokens();
                            token+=tokens;
                        }
                        //存聊天记录
                        addSaveAiMsg(2,2,contentKh,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),result.getUsage().prompt_tokens,result.getUsage().completion_tokens,token);
                        if (!content.isEmpty()){
                            getFastGptSession(qwExternalContacts,user);
                            //从fastgpt_chat_artificial_words表中查询所有转人工文本
                            List<FastgptChatArtificialWords> chatArtificialWords = qwExternalContactMapper.selectChatGptChatArtificialWords();
                            List<String> collect = chatArtificialWords.stream().map(m -> m.getContent()).collect(Collectors.toList());
                            if (collect.stream().anyMatch(contentKh::contains)){
                                notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 触发关键词",qwExternalContacts.getId(),sender);
                                continue;
                            }
                            if (result.isLongText()){
                                //新增用户信息
                                addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
                                sendAiMsg(content,sender,uid,serverId);

                            }else {
                                String sa = contentKh.replaceAll("】\n", "】").replaceAll("\n【", "【");
                                String nr = replace(sa);
                                String[] split = nr.split("\n");
                                if (split.length>6){
                                    notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName(),"回复长度异常",qwExternalContacts.getId(),sender);
                                    continue;
                                }
                                List<String> countList = countString(content);
                                //新增用户信息
                                addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
                                for (String msg : countList) {
                                    sendAiMsg(msg,sender,uid,serverId);
                                    try {
                                        Thread.sleep(10000);
                                    } catch (InterruptedException e) {

                                    }
                                    Integer replyH = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
                                    //用户正在发送消息 后面的消息不发了
                                    if (replyH!=null&&replyH!=0){
                                        return R.ok();
                                    }
                                }
                            }
                        }
                        if (result.isArtificial()){
                            notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai请求人工协助",qwExternalContacts.getId(),sender);
                        }
                    }
                }
            }
        }
        return R.ok();
    }

    @Override
    public R AiReply(OpenImMsgCallBackVO openImMsgDTO, Long companyId) {
        String content = openImMsgDTO.getContent();
        if (content == null || content.isEmpty() || content.trim().isEmpty()) {
            return R.error();
        }

        CompanyConfig companyConfig = companyConfigMapper.selectCompanyConfigByKey(companyId, "sys:AiIM:config");
        Map<String,String> modeConfig = JSONUtil.toBean(companyConfig.getConfigValue(), HashMap.class);
        if (StringUtils.isEmpty(modeConfig.get("key")) || StringUtils.isEmpty(modeConfig.get("url"))) {
            return R.error();
        }

        ChatParam param=new ChatParam();
        param.setStream(false);
        param.setDetail(true);
        ChatParam.Variables variables=new ChatParam.Variables();
        variables.setUid(openImMsgDTO.getRecvID());
        variables.setName("test");
        List<ChatParam.Message> messageList=new ArrayList<ChatParam.Message>();
        param.setMessages(messageList);
        ChatParam.Message message=new ChatParam.Message();
        message.setRole("user");
        message.setContent(content);
        messageList.add(message);
        // apkey 需要换一下  ① 是否需要做一下 前置的用户角色设定
        R r = chatService.initiatingTakeChat(param,modeConfig.get("url"),modeConfig.get("key"));
        if (r.get("code").equals(200)) {
            List<ChatDetailTStreamFResult.Choice> data = ((ChatDetailTStreamFResult) r.get("data")).getChoices();
            if (data.size() > 0) {
                return R.ok().put("code",200).put("content",data.get(0).getMessage().getContent());
            }
        }
        return R.error();
    }


    /** Ai回复 **/
    @Async
    @Override
    public R qwHookNotifyAiReply(Long qwUserId, Long sender,String qwContent,String uid,Integer type) {
        if (qwContent==null||qwContent.isEmpty()){
            return R.ok();
        }
        if (qwContent.trim().isEmpty()){
            return R.ok();
        }
        if (qwContent.contains("我已经添加了你")){
            return R.ok();
        }
        log.info("数据：{}", qwUserId);
        QwUser user = qwUserMapper.selectQwUserById(qwUserId);
        //查询接收人
        if(user==null){
            log.error("查询接收人为空");
            return R.ok();
        }
        if(user.getFastGptRoleId()==null){
            log.error("未绑定角色");
            return R.ok();
//            return userIsReply(sender, uid, user);
        }

        if(user.getAiStatus() == 1){
            log.error("ai已下线:{}",user);
            return R.ok();
        }

        Long serverId = user.getServerId();
        log.info("服务器id"+serverId);
        if (serverId == null) {
            log.error("服务id为空");
            return R.ok();
        }
        FastGptRole role=roleService.selectFastGptRoleTypeByRoleId(user.getFastGptRoleId());
        //没用ai角色跳过
        if(role==null){
            log.error("没用ai角色跳过");
            return userIsReply(sender, uid, user);
        }
        String modeConfig=role.getModeConfigJson();
        //key不为空
        if(StringUtils.isEmpty(modeConfig)){
            log.error("没有aiKey");
            return R.ok();
        }
        ModeConfig config=JSONUtil.toBean(modeConfig,ModeConfig.class);
        if(StringUtils.isEmpty(config.getAPPKey())){
            log.error("没有aiKey");
            return R.ok();
        }
        WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
        wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(sender));
        wxWorkVid2UserIdDTO.setUuid(uid);
        WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO,serverId);
        List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
        if (data==null|| data.isEmpty()){

            log.error("未获取到extId"+wxWorkVid2UserIdDTO);
            return R.ok();
        }
        com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);

        QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(),user.getQwUserId());
        if (qwExternalContacts==null){
            log.error("没有外部联系人" + "user:" + user);
            return R.ok();
        }
        if(qwExternalContacts.getType()==2){

            return R.ok();
        }
        // 添加脱敏逻辑
        if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){
            FastGptChatSession fastGptChatSession= getFastGptSession(qwExternalContacts,user,dto);
            if(type == 104||type == 101){
                String imageParse = aiImgUtil.getImageParse(qwContent,user,sender);
                if (imageParse==null){
                    return R.ok();
                }
                if(!imageParse.contains("表情包") && type == 104){
                    qwContent="用户发送图片内容:"+"\"未被识别的表情包\"";
                }else{
                    String img = imgEmoticon(imageParse);
                    if (img==null|| img.isEmpty()){
                        qwContent="用户发送图片内容:"+"\""+imageParse+"\"";
                    }else {
                        qwContent=img;
                    }
                }
            }else {
                log.info("不是图片"+type);
            }

            if("==语音转换失败==".equals(qwContent)){
                log.error("语音转换失败转人工:"+role.getRoleId()+":"+qwExternalContacts.getName() + "，uid" + uid);
                notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 语音转换失败转人工",qwExternalContacts.getId(),sender);
                return R.ok();
            }

            //对用户处理的内容做处理，去除手机号替换
            String maskedContent = processContent(qwContent);
            String contentEmj = replaceWxEmo(maskedContent);
            if(!contentEmj.contains("表情包")){
                if(!contentEmj.isEmpty()){
                    addSaveAiMsg(1,1,contentEmj,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
                    //通过用户发送的对话去查询用户是否为新客，是就删除sop，否就不做处理
                    cleanNewUserDialogue(user, qwExternalContacts);
                    //用户是未回复状态
                    if(qwExternalContacts.getIsReply() == 0){
                        qwExternalContactMapper.updateQwExternalContactIsRePlyById(qwExternalContacts.getId());
                    }
                }else {
                    contentEmj ="用户发送表情："+qwContent;
                    if (type==16){
                        return R.ok();
                    }
                }
            }

            //规定时间不发送内容
            if(role.getForbidStatus() == null){
                role.setForbidStatus(1);
            }

            if(role.getForbidStatus() == 1){
                Time forbidSendStart = role.getForbidSendStart()==null? Time.valueOf("00:00:00") :role.getForbidSendStart();
                Time forbidSendEnd = role.getForbidSendEnd()==null? Time.valueOf("04:59:59") :role.getForbidSendEnd();
                //设置规定时间不发送消息
                Time now = Time.valueOf(LocalDateTime.now().toLocalTime());
                // 判断当前时间是否在禁止发送时间段内
                if (now.after(forbidSendStart) && now.before(forbidSendEnd)) {
                    String sessionId = String.valueOf(fastGptChatSession.getSessionId());
                    log.info("当前时间 {} 在禁止发送时间段内 ({} - {})，会话id:{},跳过回复", now, forbidSendStart, forbidSendEnd,fastGptChatSession.getSessionId());

                    // HSET命令是原子的，多个线程同时写不同field不会互相覆盖；同field会覆盖（符合需求）
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("content",contentEmj);
                    jsonObject.put("sender",sender);
                    jsonObject.put("type",type);
                    String objectString = jsonObject.toString();

                    redisCache.hPut(DELAY_MSG, sessionId, objectString);

                    // 4. 确保主Key有8小时过期时间（只在首次设置时生效，避免重复刷新）
                    if (!redisCache.hasKey(DELAY_MSG)) {
                        redisCache.expire(DELAY_MSG, 8, TimeUnit.HOURS);
                    }

                    return R.ok();
                }
            }

            //规定时间不发送内容
            if(role.getForbidStatus() == null){
                role.setForbidStatus(1);
            }

            if(role.getForbidStatus() == 1){
                Time forbidSendStart = role.getForbidSendStart()==null? Time.valueOf("00:00:00") :role.getForbidSendStart();
                Time forbidSendEnd = role.getForbidSendEnd()==null? Time.valueOf("04:59:59") :role.getForbidSendEnd();
                //设置规定时间不发送消息
                Time now = Time.valueOf(LocalDateTime.now().toLocalTime());
                // 判断当前时间是否在禁止发送时间段内
                if (now.after(forbidSendStart) && now.before(forbidSendEnd)) {
                    String sessionId = String.valueOf(fastGptChatSession.getSessionId());
                    log.info("当前时间 {} 在禁止发送时间段内 ({} - {})，会话id:{},跳过回复", now, forbidSendStart, forbidSendEnd,fastGptChatSession.getSessionId());

                    // HSET命令是原子的，多个线程同时写不同field不会互相覆盖；同field会覆盖（符合需求）
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("content",contentEmj);
                    jsonObject.put("sender",sender);
                    jsonObject.put("type",type);
                    String objectString = jsonObject.toString();

                    redisCache.hPut(DELAY_MSG, sessionId, objectString);

                    // 4. 确保主Key有8小时过期时间（只在首次设置时生效，避免重复刷新）
                    if (!redisCache.hasKey(DELAY_MSG)) {
                        redisCache.expire(DELAY_MSG, 8, TimeUnit.HOURS);
                    }

                    return R.ok();
                }
            }


            //判断是否转人工
            if (fastGptChatSession.getIsArtificial()==1){
                log.error("转人工了，sessionId:" + fastGptChatSession.getSessionId());
                return R.ok();
            }
            //获取是用户是否发送消息
            Integer reply = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
            Integer replyI=1;
            //用户正在发送消息 不发
            if (reply!=null&&reply!=0){
                //更新用户发送消息次数
                redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),reply+1,5, TimeUnit.MINUTES);
                //获取用户之前发送的消息
                String msg = redisCache.getCacheObject("msg:" + fastGptChatSession.getSessionId());
                if (!msg.isEmpty()){
                    //更新用户发送消息内容
                    redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),msg+","+contentEmj,5,TimeUnit.MINUTES);
                }
                //本次跳过
                log.info("正在对话");
                return R.ok();
            }
            //用户首次发送消息
            redisCache.setCacheObject("reply:" + fastGptChatSession.getSessionId(),1,5,TimeUnit.MINUTES);
            redisCache.setCacheObject("msg:" + fastGptChatSession.getSessionId(),contentEmj,5,TimeUnit.MINUTES);
            log.info("等待");
            R r= sendAiMsg(replyI,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
            EventLogUtils.recordEventLog(sender,1L,1,user);
            EventLogUtils.recordEventLog(sender,1L,2,user);
            log.info("数据：{}", r);
            //完成对话 删除消息记录
            redisCache.deleteObject("reply:" + fastGptChatSession.getSessionId());
            redisCache.deleteObject("msg:" + fastGptChatSession.getSessionId());
            if(!r.get("code").equals(200)){
                //判断消息是否需要重发的依据
               /*redisCache.setCacheObject("retry:" + fastGptChatSession.getSessionId(),1,2,TimeUnit.MINUTES);
                redisCache.setCacheObject("retryMsg:" + fastGptChatSession.getSessionId(),contentEmj,2,TimeUnit.MINUTES);
                Integer retryCount = redisCache.getCacheObject("retry:" + fastGptChatSession.getSessionId());
                if(retryCount < 3){
                    r= retrySendAiMsg(retryCount,fastGptChatSession,role,user,qwExternalContacts.getId(),config.getAPPKey(),qwExternalContacts,sender);
                }
                redisCache.deleteObject("retry:" + fastGptChatSession.getSessionId());
                redisCache.deleteObject("retryMsg:" + fastGptChatSession.getSessionId());*/

                log.error("ai报错转人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
                notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai报错转人工",qwExternalContacts.getId(),sender);
                return R.ok();
            }
            ChatDetailTStreamFResult result=(ChatDetailTStreamFResult)r.get("data");
            //是否转人工
            if(result.getChoices().isEmpty()){
                return R.ok();
            }
            String contentKh = result.getChoices().get(0).getMessage().getContent();
            String content = replace(result.getChoices().get(0).getMessage().getContent()).trim();
            //计算token
            List<ChatDetailTStreamFResult.ResponseNode> responseData = result.getResponseData();
            int token=0;
            for (ChatDetailTStreamFResult.ResponseNode responseDatum : responseData) {
                int tokens = responseDatum.getTokens();
                token+=tokens;
            }
            //存聊天记录
            addSaveAiMsg(2,2,contentKh,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),result.getUsage().prompt_tokens,result.getUsage().completion_tokens,token);
            if (!content.isEmpty()){
                addSaveAiMsg(1,2,content,user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
                //从fastgpt_chat_artificial_words表中查询所有转人工文本
                List<FastgptChatArtificialWords> chatArtificialWords = qwExternalContactMapper.selectChatGptChatArtificialWords();
                List<String> collect = chatArtificialWords.stream().map(m -> m.getContent()).collect(Collectors.toList());
                if (collect.stream().anyMatch(content::contains)){
                    log.info("触发关键词:"+role.getRoleId()+":"+qwExternalContacts.getName());
                    notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 触发关键词",qwExternalContacts.getId(),sender);
                    return R.ok();
                }
                //ai回复文字长度大于500就转人工
                if(content.length() > 500){
                    log.error("回复长度异常:"+role.getRoleId()+":"+qwExternalContacts.getName());
                    notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," 回复长度异常",qwExternalContacts.getId(),sender);
                    return R.ok();
                }
                if (result.isLongText()){
                    //新增用户信息
                    addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
                    if (type==16){
                        sendAiVoiceMsg(content,sender,uid,serverId,user);
                    }else {
                        sendAiMsg(content,sender,uid,serverId);
                    }

                }else {
                    String sa = contentKh.replaceAll("】\n", "】").replaceAll("\n【", "【");
                    String nr = replace(sa);
                    String[] split = nr.split("\n");
                    if (split.length>6){
                        log.info("回复长度异常:"+role.getRoleId()+":"+qwExternalContacts.getName());
                        notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName(),"回复长度异常",qwExternalContacts.getId(),sender);
                        return R.ok();
                    }
                    List<String> countList = countString(content);
                    //新增用户信息
                    addUserInfo(contentKh, qwExternalContacts.getId(),fastGptChatSession);
                    for (String msg : countList) {
                        if (type==16){
                            sendAiVoiceMsg(msg,sender,uid,serverId,user);
                        }else {
                            sendAiMsg(msg,sender,uid,serverId);
                        }
                        try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {

                        }
                        Integer replyH = redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
                        //用户正在发送消息 后面的消息不发了
                        if (replyH!=null&&replyH!=0){
                            return R.ok();
                        }
                    }
                }
            }

            aiEventProcess(sender, uid, role, contentKh, user, fastGptChatSession, serverId,qwExternalContacts);


            if (result.isArtificial()){
                log.error("ai请求人工:"+role.getRoleId()+":"+qwExternalContacts.getName());
                notifyArtificial(fastGptChatSession.getSessionId(),user,qwExternalContacts.getName()," ai请求人工协助",qwExternalContacts.getId(),sender);
            }
        }

        return R.ok();
    }

    /**
     * 根据发送者id设置用户是否为首次回复
     * @param sender 发送者id
     * @param uid   企微用户的uuid
     * @param user  企微用户信息
     * @return
     */
    private @Nullable R userIsReply(Long sender, String uid, QwUser user) {
        Long qwExternalContactId = redisCache.getCacheObject(AI_REPLY + sender);
        if(qwExternalContactId == null){
            WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
            wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(sender));
            wxWorkVid2UserIdDTO.setUuid(uid);
            WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO, user.getServerId());
            List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
            if (data==null|| data.isEmpty()){
                log.error("未获取到extId"+wxWorkVid2UserIdDTO);
                return R.ok();
            }
            com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);

            QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(dto.getOpenid(), user.getCorpId(), user.getQwUserId());
            if (qwExternalContacts==null){
                log.error("没有外部联系人" + "user:" + user);
                return R.ok();
            }
            List<String> oldCache = redisCache.getCacheObject(AI_REPLY_TAG + user.getCorpId());
            if(oldCache != null && !oldCache.isEmpty()){
                QwExternalContact qwExternalContact = new QwExternalContact();
                if(qwExternalContacts.getTagIds() != null && !qwExternalContacts.getTagIds().isEmpty() && !"[]".equals(qwExternalContacts.getTagIds())){
                    List<String> parsedTags = JSON.parseArray(qwExternalContacts.getTagIds(), String.class);
                    if (parsedTags != null && !parsedTags.isEmpty()) {
                        for (String parsedTag : oldCache) {
                            if (!oldCache.contains(parsedTag)) {
                                oldCache.add(parsedTag);
                            }
                        }
                    }
                    qwExternalContact.setTagIds(JSON.toJSONString(oldCache));
                }else if("[]".equals(qwExternalContacts.getTagIds()) || qwExternalContacts.getTagIds() == null){
                    qwExternalContact.setTagIds(JSON.toJSONString(oldCache));
                }
                qwExternalContact.setId(qwExternalContacts.getId());
                qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
            }
            qwExternalContactMapper.updateQwExternalContactIsRePlyById(qwExternalContacts.getId());
            redisCache.setCacheObject(AI_REPLY + sender,qwExternalContacts.getId());
        }
        return R.ok();
    }

    /**
     * 通过用户发送的对话去查询用户是否为新客，是就删除sop，否就不做处理
     * @param user
     * @param qwExternalContacts
     */
    private void cleanNewUserDialogue(QwUser user, QwExternalContact qwExternalContacts) {
        String redisKey = "qwNewChat:" + user.getQwUserId() + ":" + user.getCorpId() + ":" + qwExternalContacts.getExternalUserId();
        String key  = (String) redisCache.getCacheObject(redisKey);
        if(!StringUtil.strIsNullOrEmpty(key)){
            try {
                QwSopLogs qwSopLogs = new QwSopLogs();
                qwSopLogs.setQwUserid(user.getQwUserId());
                qwSopLogs.setCorpId(user.getCorpId());
                qwSopLogs.setExternalUserId(qwExternalContacts.getExternalUserId());
                qwSopLogs.setSendStatus(3L);
                qwSopLogs.setSendType(4);
                List<QwSopLogs> qwSopLogsList = qwSopLogsMapper.selectQwSopLogsList(qwSopLogs);
                if(qwSopLogsList != null && !qwSopLogsList.isEmpty()){
                    qwSopLogsMapper.batchUpdateQwSopLogsNewUserById(qwSopLogsList);
                }
            } catch (Exception e) {
                log.error("停用新客对话sop失败：" + redisKey + "原因：" + e);
            }finally {
                redisCache.deleteObject(redisKey);
            }
        }
    }



    /**
     * 处理ai事件发送
     * @param sender    用户的ai对话id
     * @param uid
     * @param role      规则
     * @param contentKh ai回复
     * @param user      企微用户
     * @param fastGptChatSession
     * @param serverId
     */
    private void aiEventProcess(Long sender, String uid, FastGptRole role, String contentKh, QwUser user, FastGptChatSession fastGptChatSession, Long serverId,QwExternalContact qwExternalContacts) {
        Long roleId = role.getRoleId();
        List<FastGptKeywordSend> fastGptKeywordSends = fastGptKeywordSendService.selectFastGptKeywordSendByRoleId(roleId);
        if(fastGptKeywordSends != null && !fastGptKeywordSends.isEmpty()) {
            //将该role名下的keywordSend全部查出
            List<FastGptKeywordSend> keywordSendList = fastGptKeywordSends.stream().filter(m -> {
                String keyword = "【事件：" + m.getKeyword() + "】";
                return contentKh.contains(keyword);
            }).collect(Collectors.toList());

            if(!keywordSendList.isEmpty()){
                String keyword = keywordSendList.get(0).getKeyword();
                FastGptKeywordArtificial keywordArtificial = new FastGptKeywordArtificial();
                keywordArtificial.setUserId(String.valueOf(sender));
                keywordArtificial.setCompanyId(user.getCompanyId());
                keywordArtificial.setCompanyUserId(user.getCompanyUserId());
                keywordArtificial.setKeywordSendContent(keyword);
                keywordArtificial.setCreateTime(new Date());

                //查询已经插入关键词人工表的关键词
                List<FastGptKeywordArtificial> artificialList =  fastGptKeywordSendService.selectFastGptKeywordArtificial(keywordArtificial);
                //将全部的keywordSendId取出来
                List<Long> collect = keywordSendList.stream().map(FastGptKeywordSend::getId).collect(Collectors.toList());

                //如果已经插入关键词人工表的关键词，则从keywordSendList中删除
                if (artificialList != null && !artificialList.isEmpty()){
                    artificialList.stream().map(FastGptKeywordArtificial::getKeywordSendId).filter(collect::contains).forEach(collect::remove);
                    keywordSendList = keywordSendList.stream().filter(m -> collect.contains(m.getId())).collect(Collectors.toList());
                    if(keywordSendList.isEmpty()){
                        EventLogUtils.recordEventLog(sender,1L,3,user);
                        EventLogUtils.recordEventLog(sender,1L,4,user);
                        fastGptChatSession.setIsArtificial(1);
                        fastGptChatSessionMapper.updateFastGptChatSession(fastGptChatSession);
                    }else{
                        sendAiMsg(sender, uid, role, user, fastGptChatSession, serverId, qwExternalContacts, keywordSendList);
                    }
                }else{//关键词人工表中不含当前的关键词
                    sendAiMsg(sender, uid, role, user, fastGptChatSession, serverId, qwExternalContacts, keywordSendList);
                }
            }
        }
    }

    private void sendAiMsg(Long sendId, String uuid, FastGptRole role, QwUser user, FastGptChatSession fastGptChatSession, Long serverId, QwExternalContact qwExternalContacts, List<FastGptKeywordSend> keywordSendList) {
        Random random = new Random();
        FastGptKeywordSend fastGptKeywordSend = keywordSendList.get(random.nextInt(keywordSendList.size()));
        if (fastGptKeywordSend == null){
            log.info("输出为空格");
            return;
        }
        if(fastGptKeywordSend.getKeywordType() == 1L && "物流".equals(fastGptKeywordSend.getKeyword())){
            Long fsUserId = qwExternalContacts.getFsUserId();
            if(fsUserId != null){
                StringBuilder sBuilder = new StringBuilder();
                List<FsStoreOrder> fsStoreOrderList = storeOrderService.selectFsStoreOrderByFsUserId(fsUserId);
                if(fsStoreOrderList != null && !fsStoreOrderList.isEmpty()){
                    for (FsStoreOrder fsStoreOrder : fsStoreOrderList) {
                        if(sBuilder.length() > 0 && fsStoreOrder.getStatus() > 1){
                            sBuilder.append("\n\n同时，");
                        }else if(fsStoreOrder.getStatus() > 1){
                            sBuilder.append("您好，");
                        }
                        switch (fsStoreOrder.getStatus())
                        {
                            case -1:
                            case -2:
                            case 1:
                                EventLogUtils.recordEventLog(sendId,1L,3,user);
                                EventLogUtils.recordEventLog(sendId,1L,4,user);
                                fastGptChatSession.setIsArtificial(1);
                                fastGptChatSessionMapper.updateFastGptChatSession(fastGptChatSession);
                                break;
                            case 2:
                                sBuilder.append("您好，您有一个包裹正在准备发货，请耐心等待;\n")
                                        .append("\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
                            case 3:
                                ExpressInfoDTO expressInfo = getExpress(fsStoreOrder.getOrderId());
                                sBuilder.append("您有一个包裹 ");
                                sBuilder.append(" 已经查询到了，正在配送中了。\n");
                                if(expressInfo != null && expressInfo.getTraces() != null && !expressInfo.getTraces().isEmpty()){
                                    List<TracesDTO> traces = expressInfo.getTraces();
                                    TracesDTO tracesDTO = traces.get(traces.size() - 1);
                                    sBuilder.append("快递单号为：").append(fsStoreOrder.getDeliverySn()).append("\n");
                                    sBuilder.append(tracesDTO.getAcceptStation()).append("，上次更新时间在").append(tracesDTO.getAcceptTime()).append(";\n");
                                }
                                break;
                            case 4:
                            case 5:
                                ExpressInfoDTO express = getExpress(fsStoreOrder.getOrderId());
                                //你好，这边查询到您购买的XXX（购买套餐）在XXX（时间）已经送到了，送货员电话为XXX（送货员信息）
                                sBuilder.append("这边查询到您有一个包裹");
                                if(express != null && express.getTraces() != null && !express.getTraces().isEmpty()){
                                    List<TracesDTO> traces = express.getTraces();
                                    TracesDTO tracesDTO = traces.get(traces.size() - 1);
                                    sBuilder.append(" 在").append(tracesDTO.getAcceptTime()).append("已经送到了\n");
                                    sBuilder.append("物流信息：").append(tracesDTO.getAcceptStation()).append("\n");
                                }else{
                                    sBuilder.append(" 已经送到了\n");
                                }
                                break;
                        }
                    }
                    if(sBuilder.length() > 0){
                        sBuilder.append("\n\uD83C\uDF39\uD83C\uDF39\uD83C\uDF39");
                    }
                }else{
                    EventLogUtils.recordEventLog(sendId,1L,3,user);
                    EventLogUtils.recordEventLog(sendId,1L,4,user);
                    //触发物流但是没有订单，就转人工
                    fastGptChatSession.setIsArtificial(1);
                    fastGptChatSessionMapper.updateFastGptChatSession(fastGptChatSession);
                }
                //2.发送模板中的文字内容
                if(!"".contentEquals(sBuilder)){
                    String content = sBuilder.toString();
                    WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
                    wxWorkSendTextMsgDTO.setSend_userid(sendId);
                    wxWorkSendTextMsgDTO.setUuid(uuid);
                    wxWorkSendTextMsgDTO.setContent(content);
                    wxWorkSendTextMsgDTO.setIsRoom(false);
                    wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO,serverId);
                }
                EventLogUtils.recordEventLog(sendId,1L,7,user);
            }
        }else{

            WxWorkResponseDTO<WxwUploadCdnLinkImgRespDTO> dto = new WxWorkResponseDTO<>();
            //1.上传cdn网络图片
            if(fastGptKeywordSend.getImgUrl() != null){
                WxwUploadCdnLinkImgDTO wxwUploadCdnLinkImgDTO = new WxwUploadCdnLinkImgDTO();
                wxwUploadCdnLinkImgDTO.setUuid(uuid);
                wxwUploadCdnLinkImgDTO.setUrl(fastGptKeywordSend.getImgUrl());
                dto  = wxWorkService.uploadCdnLinkImg(wxwUploadCdnLinkImgDTO,serverId);
            }

            //2.发送模板中的文字内容
            String content = fastGptKeywordSend.getContent();
            if(content != null){
                WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
                wxWorkSendTextMsgDTO.setSend_userid(sendId);
                wxWorkSendTextMsgDTO.setUuid(uuid);
                wxWorkSendTextMsgDTO.setContent(content);
                wxWorkSendTextMsgDTO.setIsRoom(false);
                wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO,serverId);
            }


            //图片上传成功后再发送图片
            if("成功".equals(dto.getErrmsg()) && fastGptKeywordSend.getImgUrl() != null){
                WxwUploadCdnLinkImgRespDTO imgRespDTO = dto.getData();
                WxwSendCDNImgMsgDTO wxwSendCDNImgMsgDTO = new WxwSendCDNImgMsgDTO();
                wxwSendCDNImgMsgDTO.setSend_userid(sendId);
                wxwSendCDNImgMsgDTO.setUuid(uuid);
                wxwSendCDNImgMsgDTO.setIsRoom(false);
                wxwSendCDNImgMsgDTO.setCdnkey(imgRespDTO.getCdn_key());
                wxwSendCDNImgMsgDTO.setAeskey(imgRespDTO.getAes_key());
                wxwSendCDNImgMsgDTO.setMd5(imgRespDTO.getMd5());
                wxwSendCDNImgMsgDTO.setFileSize(imgRespDTO.getSize());
                wxWorkService.SendCDNImgMsg(wxwSendCDNImgMsgDTO, serverId);
            }
            if("用户完课".equals(fastGptKeywordSend.getKeyword())){
                EventLogUtils.recordEventLog(sendId,1L,6,user);
            }
            if(fastGptKeywordSend.getKeywordType() == 0L){
                EventLogUtils.recordEventLog(sendId,1L,9,user);
            }
        }
        FastGptKeywordArtificial keywordArtificial = new FastGptKeywordArtificial();
        keywordArtificial.setKeywordSendId(fastGptKeywordSend.getId());
        keywordArtificial.setUserId(String.valueOf(sendId));
        keywordArtificial.setCompanyId(user.getCompanyId());
        keywordArtificial.setCompanyUserId(user.getCompanyUserId());
        keywordArtificial.setKeywordSendContent(fastGptKeywordSend.getKeyword());
        keywordArtificial.setCreateTime(new Date());
        fastGptKeywordSendService.insertFastGptKeywordArtificial(keywordArtificial);
        addSaveAiMsg(1,2,fastGptKeywordSend.getContent(), user, fastGptChatSession.getSessionId(), role.getRoleId(), qwExternalContacts, fastGptChatSession.getUserId(),null,null,null);
    }

    public ExpressInfoDTO getExpress(Long id){
        FsStoreOrder order=storeOrderService.selectFsStoreOrderByOrderId(id);

        ExpressInfoDTO expressInfoDTO=null;
        if(com.fs.common.utils.StringUtils.isNotEmpty(order.getDeliverySn())){
            String lastFourNumber = "";
            if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {

                lastFourNumber = order.getUserPhone();
                if (lastFourNumber.length() == 11) {
                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                }else if (lastFourNumber.length()>11){
                    String jm = decryptPhone(lastFourNumber);
                    lastFourNumber = StrUtil.sub(jm, jm.length(), -4);
                }
            }
            expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);

            if((expressInfoDTO.getStateEx()!=null&&expressInfoDTO.getStateEx().equals("0"))&&(expressInfoDTO.getState()!=null&&expressInfoDTO.getState().equals("0"))){
                lastFourNumber = "19923690275";
                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
                    if (lastFourNumber.length() == 11) {
                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                    }
                }

                expressInfoDTO=expressService.getExpressInfo(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);

            }
        }
        return expressInfoDTO;
    }

    private String imgEmoticon(String imageParse) {
        Pattern img = Pattern.compile("【表情包：(.*?)】", Pattern.DOTALL);
        Matcher imgMatcher = img.matcher(imageParse);
        while  (imgMatcher.find()) {
            String imgTag = imgMatcher.group(1).trim();
            if(imgTag!=null&&!imgTag.equals("")){
                return imgTag;
            }

        }
        return null;
    }

    /**
     * 处理用户的输入问题
     * @param qwContent
     * @return
     */
    private @Nullable String processContent(String qwContent) {
        //String maskedContent = SensitiveDataUtils.maskMobileNumbers(qwContent);
        String maskedContent = qwContent;
        if(maskedContent != null && !maskedContent.isEmpty()){
            FastGptChatReplaceText fastGptChatReplaceText = new FastGptChatReplaceText();
            fastGptChatReplaceText.setStatus(1);
            List<FastGptChatReplaceText> chatReplaceTextList = fastGptChatReplaceTextService.selectFastGptChatReplaceTextList(fastGptChatReplaceText);
            if(chatReplaceTextList != null && !chatReplaceTextList.isEmpty()){
                for (FastGptChatReplaceText replaceText : chatReplaceTextList) {
                    if(maskedContent.contains(replaceText.getContent())){
                        maskedContent = maskedContent.replace(replaceText.getContent(), replaceText.getChangeCount());
                    }
                }
            }
        }
        return maskedContent;
    }

    private void sendAiVoiceMsg(String content, Long sendId , String uuid,Long serverId,QwUser user) {
        if (content == null || content.trim().isEmpty()){
            System.out.println("输出为空格");
            return;
        }
        content = voiceHomo(replaceWords(content));
        System.out.println("过滤后的文字："+content);
        if (content.isEmpty()){
            return;
        }
        WxwSilkVoceDTO silkVoice;
        /*判断是否走豆包语音*/
        com.alibaba.fastjson.JSONObject vcConfig = configUtil.generateConfigByKey(SysConfigEnum.VS_CONFIG.getKey());
        if (vcConfig != null && !vcConfig.isEmpty() &&
//                !vcConfig.equals(new com.alibaba.fastjson.JSONObject()) &&
                "2".equals(vcConfig.getString("type"))){
            silkVoice = wxWorkService.getSilkVoiceDoubao(content, user.getCompanyUserId());
        }else {
            silkVoice= wxWorkService.getSilkVoice(content, user.getCompanyUserId());
        }

        if (silkVoice == null){
            return;
        }
        if (silkVoice.getCode()!=200){
            return;
        }
        WxwSilkVoceDTO.Data data = silkVoice.getData();
        WxwUploadCdnLinkFileDTO wxwUploadCdnLinkFileDTO = new WxwUploadCdnLinkFileDTO();
        wxwUploadCdnLinkFileDTO.setUrl(data.getUrl());
        wxwUploadCdnLinkFileDTO.setFilename(data.getUrl());
        wxwUploadCdnLinkFileDTO.setUuid(uuid);
        WxWorkResponseDTO<WxwUploadCdnLinkFileRespDTO> dto = wxWorkService.uploadCdnLinkFile(wxwUploadCdnLinkFileDTO, serverId);
        log.info("语音数据:{}", JSON.toJSONString(dto));
        WxwUploadCdnLinkFileRespDTO voice = dto.getData();
        WxwSendCDNVoiceMsgDTO wxwSendCDNVoiceMsgDTO = new WxwSendCDNVoiceMsgDTO();
        wxwSendCDNVoiceMsgDTO.setSend_userid(sendId);
        System.out.println("语音size"+voice.getSize());
        wxwSendCDNVoiceMsgDTO.setVoice_time(data.getDuration());
        wxwSendCDNVoiceMsgDTO.setIsRoom(false);
        wxwSendCDNVoiceMsgDTO.setCdnkey(voice.getCdn_key());
        wxwSendCDNVoiceMsgDTO.setAeskey(voice.getAes_key());
        wxwSendCDNVoiceMsgDTO.setMd5(voice.getMd5());
        wxwSendCDNVoiceMsgDTO.setFileSize(voice.getSize());
        wxwSendCDNVoiceMsgDTO.setUuid(uuid);
        WxWorkResponseDTO<WxwSendCDNVoiceMsgRespDTO> wxwSendCDNVoiceMsgRespDTOWxWorkResponseDTO = wxWorkService.SendCDNVoiceMsg(wxwSendCDNVoiceMsgDTO, serverId);
        System.out.println(wxwSendCDNVoiceMsgRespDTOWxWorkResponseDTO);

    }

    @Autowired
    QwSopLogsMapper qwSopLogsMapper;
    private void sendAiMsg(String content, Long sendId , String uuid,Long serverId) {
        if (content == null || content.trim().isEmpty()){
            System.out.println("输出为空格");
            return;
        }
        WxWorkSendTextMsgDTO wxWorkSendTextMsgDTO = new WxWorkSendTextMsgDTO();
        wxWorkSendTextMsgDTO.setSend_userid(sendId);
        wxWorkSendTextMsgDTO.setUuid(uuid);
        wxWorkSendTextMsgDTO.setContent(replaceWords(content));
        wxWorkSendTextMsgDTO.setIsRoom(false);
        WxWorkResponseDTO<WxWorkSendTextMsgRespDTO> wxWorkSendTextMsgRespDTOWxWorkResponseDTO = wxWorkService.SendTextMsg(wxWorkSendTextMsgDTO,serverId);
        WxWorkSendTextMsgRespDTO data = wxWorkSendTextMsgRespDTOWxWorkResponseDTO.getData();


    }
    /**
     * 增加标签
     *
     * @param qwUser
     * @param userID
     * @param externalUserID
     */
    private void addQwAutoTags(QwUser qwUser, String userID, String externalUserID) {
        QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalByExternalIdAndCompanyIdToIdAndFs(
                externalUserID, userID, qwUser.getCorpId());

        QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();
        qwEditUserTagParam.setUserid(userID);
        qwEditUserTagParam.setExternal_userid(externalUserID);

        QwAutoTags qwAutoTags = qwAutoTagsMapper.selectQwAutoReplyTagsByIdJSON(qwUser.getCorpId(), qwUser.getId());
        if (qwAutoTags == null) {
            return;
        }

        Set<String> combinedTagsSet = new HashSet<>();
        Set<String> timeSlotMatchedTags = new HashSet<>();
        String tagRemark = null;
        boolean isMatch = false;

        QwAutoTagsLogs qwAutoTagsLogs = new QwAutoTagsLogs();
        qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
        qwAutoTagsLogs.setType(3L);
        qwAutoTagsLogs.setQwUserid(qwUser.getId());
        qwAutoTagsLogs.setExternalUserId(externalUserID);

        List<QwAutoTagsRulesTags> rulesList = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoTagsRulesTags.class);

        LocalDate todayDate = LocalDate.now();
        DayOfWeek today = todayDate.getDayOfWeek();
        int todayIndex = today.getValue();
        LocalTime now = LocalTime.now();

        for (QwAutoTagsRulesTags rule : rulesList) {
            if (!rule.getWeek().contains(todayIndex)) {
                continue;
            }
            LocalTime start = LocalTime.parse(rule.getStartTime());
            LocalTime end = LocalTime.parse("24:00".equals(rule.getEndTime()) ? "23:59:59" : rule.getEndTime());

            if (now.isBefore(start) || now.isAfter(end)) {
                continue;
            }

            combinedTagsSet.addAll(rule.getTags());
            timeSlotMatchedTags.addAll(rule.getTags());
            isMatch = true;

            if (rule.getIsDay() != null && rule.getIsDay() == 1) {
                tagRemark = todayDate.format(DateTimeFormatter.ofPattern("yyMMdd")).substring(1);
            }

            if (!StringUtil.strIsNullOrEmpty(rule.getRemarks())) {
                tagRemark = (tagRemark == null ? "" : tagRemark + "-") + rule.getRemarks();
            }
        }

        if (!isMatch) {
            return;
        }

        List<String> tagsToAdd = new ArrayList<>(combinedTagsSet);
        qwEditUserTagParam.setAdd_tag(tagsToAdd);

        qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(new ArrayList<>(timeSlotMatchedTags)));
        qwAutoTagsLogs.setAddTime(new Date());
        qwAutoTagsLogs.setCompanyId(qwUser.getCompanyId());
        qwAutoTagsLogs.setCorpId(qwUser.getCorpId());

        QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, qwUser.getCorpId());
        log.info("自动添加标签的状态: {}|{}|qwEditUserTagParam--{}",
                qwResult.getErrcode(), qwResult.getErrmsg(), qwEditUserTagParam);

        if (qwResult.getErrcode() == 0) {
            qwExternalContact.setTagIds(JSON.toJSONString(tagsToAdd));
            qwAutoTagsLogsMapper.insertOrUpdateQwAutoTagsLogs(qwAutoTagsLogs);
        } else if (qwResult.getErrcode() == 45035) {
            insertQwExternalErrRetryTool(
                    qwUser.getCorpId(),
                    JSON.toJSONString(qwEditUserTagParam),
                    1,
                    qwResult.getErrmsg());
            log.info("自动添加标签添加失败-已加入补偿机制中: {}", qwEditUserTagParam);
        }
    }
    public void  insertQwExternalErrRetryTool(String corpId,String params,Integer retryState,String msg) {

        QwExternalErrRetry errRetry=new QwExternalErrRetry();
        errRetry.setTakeState(1);
        errRetry.setCorpId(corpId);
        errRetry.setRetryState(retryState);
        errRetry.setRetryType(2);
        errRetry.setRetryParams(JSON.toJSONString(params));
        errRetry.setRetryNum(0);
        errRetry.setCreateTime(new Date());
        errRetry.setMark(msg);

        errRetryService.insertQwExternalErrRetry(errRetry);

    }

    /** 回调转人工  **/
    private void notifyArtificial(Long sessionId, QwUser user, String name,String reason,Long extId,Long sender) {
        EventLogUtils.recordEventLog(sender,1L,3,user);
        if(reason.contains("人工") || reason.contains("异常")){
            EventLogUtils.recordEventLog(sender,1L,4,user);
        }else if(reason.contains("关键词")){
            EventLogUtils.recordEventLog(sender,1L,5,user);
        }
        FastGptChatSession s = new FastGptChatSession();
        s.setIsArtificial(1);
        s.setRemindStatus(0);
        s.setIsReply(0);
        s.setSessionId(sessionId);
        s.setLastTime(new Date());
        fastGptChatSessionMapper.updateFastGptChatSession(s);
        log.info("转人工:"+name);
        QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(user.getCorpId());
        sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),"您的客户:"+name+"因"+reason+"  需要转人工,请及时回复");
        sendQwAppMsg(user.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),name);
        qwWorkTaskService.addQwWorkByAiNotifyArtificial(user,extId,"Ai转人工");
        FastGptChatSession chatSession = fastGptChatSessionMapper.selectFastGptChatSessionBySessionId(sessionId);
        CrmMsg crmMsg = new CrmMsg();
        crmMsg.setMsgType(3);
        crmMsg.setTitle("Ai转人工");
        crmMsg.setContent("你的客户：" + chatSession.getNickName() + "， 因  \"" + reason + "\"  需要转人工,请及时回复");
        crmMsg.setCompanyId(user.getCompanyId());
        crmMsg.setCompanyUserId(user.getCompanyUserId());
        crmMsgService.insertCrmMsg(crmMsg);

    }

    void sendQwAppMsg(String corpId, Integer agentId,String qwUserId,String content){
        QwSendMsgParam qwSendMsgParam = new QwSendMsgParam();
        qwSendMsgParam.setAgentid(agentId);
        qwSendMsgParam.setTouser(qwUserId);
        QwSendMsgParam.Text text = new QwSendMsgParam.Text();
        text.setContent(content);
        qwSendMsgParam.setText(text);
        qwSendMsgParam.setMsgtype("text");
        qwApiService.sendMsg(qwSendMsgParam, corpId);
    }


    private void saveQwUserMsg(FastGptChatSession fastGptChatSession,Integer sendType,String content,QwUser sendUser) {
        content = replaceWxEmo(content);
        if(content.isEmpty()){
            return;
        }
        FastGptChatMsg fastGptChatMsgAi = new FastGptChatMsg();
        fastGptChatMsgAi.setContent(content);
        fastGptChatMsgAi.setSessionId(fastGptChatSession.getSessionId());
        fastGptChatMsgAi.setRoleId(Long.parseLong(fastGptChatSession.getKfId()));
        fastGptChatMsgAi.setSendType(sendType);
        fastGptChatMsgAi.setCompanyId(fastGptChatSession.getCompanyId());
        fastGptChatMsgAi.setCompanyUserId(sendUser.getCompanyUserId());
        fastGptChatMsgAi.setUserId(fastGptChatSession.getUserId());
        fastGptChatMsgAi.setUserType(1);
        fastGptChatMsgAi.setMsgType(1);
        fastGptChatMsgAi.setStatus(0);
        fastGptChatMsgAi.setAvatar(fastGptChatSession.getAvatar());
        fastGptChatMsgAi.setNickName(fastGptChatSession.getNickName());
        fastGptChatMsgAi.setCreateTime(new Date());
        fastGptChatMsgAi.setExtId(fastGptChatSession.getQwExtId()+"");
        fastGptChatMsgService.insertFastGptChatMsg(fastGptChatMsgAi);
        log.info("新增消息："+fastGptChatMsgAi);
    }
    /** 存聊天记录  **/
    private void addSaveAiMsg(Integer msgType,Integer sendType,String content, QwUser user, Long sessionId, Long roleId, QwExternalContact qwExternalContacts, String userId, Integer promptTokens, Integer completionTokens, Integer token) {

        FastGptChatMsg fastGptChatMsgAi = new FastGptChatMsg();
        fastGptChatMsgAi.setContent(content);
        fastGptChatMsgAi.setSessionId(sessionId);
        fastGptChatMsgAi.setRoleId(roleId);
        fastGptChatMsgAi.setSendType(sendType);
        fastGptChatMsgAi.setCompanyId(user.getCompanyId());
        fastGptChatMsgAi.setUserId(userId);
        fastGptChatMsgAi.setCompanyUserId(user.getCompanyUserId());
        fastGptChatMsgAi.setUserType(1);
        fastGptChatMsgAi.setMsgType(msgType);
        fastGptChatMsgAi.setStatus(0);
        fastGptChatMsgAi.setAvatar(qwExternalContacts.getAvatar());
        fastGptChatMsgAi.setNickName(qwExternalContacts.getName());
        fastGptChatMsgAi.setCreateTime(new Date());
        fastGptChatMsgAi.setExtId(qwExternalContacts.getId()+"");
        fastGptChatMsgAi.setPromptTokens(promptTokens);
        fastGptChatMsgAi.setCompletionTokens(completionTokens);
        fastGptChatMsgAi.setTotalTokens(token);
        fastGptChatMsgService.insertFastGptChatMsg(fastGptChatMsgAi);
    }
    /** 获取会话  **/
    private FastGptChatSession getFastGptSession(QwExternalContact qwExternalContacts, QwUser user) {
        FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), user.getId());
        if (fastGptChatSession==null){
            fastGptChatSession = new FastGptChatSession();
            String chatId = UUID.randomUUID().toString();
            fastGptChatSession.setChatId(chatId);
            fastGptChatSession.setKfId(user.getFastGptRoleId().toString());
            fastGptChatSession.setStatus(1);
            fastGptChatSession.setRemindCount(0);
            fastGptChatSession.setRemindStatus(0);
            fastGptChatSession.setCreateTime(new Date());
            fastGptChatSession.setQwExtId(qwExternalContacts.getId());
            fastGptChatSession.setQwUserId(user.getId());
            fastGptChatSession.setIsArtificial(0);
            fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
            fastGptChatSession.setNickName(qwExternalContacts.getName());
            fastGptChatSession.setCompanyId(user.getCompanyId());
            fastGptChatSession.setLastTime(new Date());
            fastGptChatSession.setIsReply(0);
            fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
            addUserSex(qwExternalContacts);
        }else {
            if (fastGptChatSession.getRemindStatus()==1){
                FastGptChatSession ss = new FastGptChatSession();
                ss.setSessionId(fastGptChatSession.getSessionId());
                ss.setRemindStatus(0);
                ss.setIsReply(0);
                fastGptChatSessionMapper.updateFastGptChatSession(ss);
            }
        }
        return fastGptChatSession;
    }
    private FastGptChatSession getFastGptSession(QwExternalContact qwExternalContacts, QwUser user,WxWorkVid2UserIdRespDTO dto) {
        FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), user.getId());
        if (fastGptChatSession==null){
            fastGptChatSession = new FastGptChatSession();
            String chatId = UUID.randomUUID().toString();
            fastGptChatSession.setChatId(chatId);
            fastGptChatSession.setKfId(user.getFastGptRoleId().toString());
            fastGptChatSession.setStatus(1);
            fastGptChatSession.setRemindCount(0);
            fastGptChatSession.setRemindStatus(0);
            fastGptChatSession.setCreateTime(new Date());
            fastGptChatSession.setQwExtId(qwExternalContacts.getId());
            fastGptChatSession.setQwUserId(user.getId());
            fastGptChatSession.setIsArtificial(0);
            fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
            fastGptChatSession.setNickName(qwExternalContacts.getName());
            fastGptChatSession.setCompanyId(user.getCompanyId());
            fastGptChatSession.setLastTime(new Date());
            fastGptChatSession.setIsReply(0);
            fastGptChatSession.setUserId(String.valueOf(dto.getUser_id()));
            fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
            addUserSex(qwExternalContacts);
        }else {
            if (fastGptChatSession.getRemindStatus()==1){
                FastGptChatSession ss = new FastGptChatSession();
                ss.setSessionId(fastGptChatSession.getSessionId());
                ss.setRemindStatus(0);
                ss.setIsReply(0);
                ss.setUserId(String.valueOf(dto.getUser_id()));
                fastGptChatSessionMapper.updateFastGptChatSession(ss);
            }
        }
        return fastGptChatSession;
    }
    /** 特殊转人工 **/
    @Override
    public void artificial(QwHookVO vo) {
        QwHookMsgVO msgVo= JSONUtil.toBean(vo.getData(),QwHookMsgVO.class);
        if (msgVo.getIs_room()!=null&&msgVo.getIs_room()==0){
            QwUser user=qwUserService.selectQwUserByAppKey(msgVo.getKey());
            if(user!=null&&user.getFastGptRoleId()!=null) {
                FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByUserIdAndKfId(msgVo.getSender(), user.getId());
                if (fastGptChatSession!=null&&fastGptChatSession.getIsArtificial()!=1){
                    QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(msgVo.getSender_openid(), user.getCorpId(),user.getQwUserId());
                    if (qwExternalContacts!=null){
                        EventLogUtils.recordEventLog(Long.valueOf(msgVo.getSender()),1L,9, user);
                        FastGptChatSession s = new FastGptChatSession();
                        s.setIsArtificial(1);
                        s.setSessionId(fastGptChatSession.getSessionId());
                        fastGptChatSessionMapper.updateFastGptChatSession(s);
                        QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(user.getCorpId());
                        qwSendAppMsg(qwCompany.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),"您的客户:"+qwExternalContacts.getName()+" 因发送图片或视频,需要转人工,请及时回复");
                        qwSendAppMsg(qwCompany.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),user.getQwUserId(),qwExternalContacts.getName());
                        if (fastGptChatSession.getRemindStatus()==1){
                            FastGptChatSession ss = new FastGptChatSession();
                            ss.setSessionId(fastGptChatSession.getSessionId());
                            ss.setRemindStatus(0);
                            ss.setIsReply(0);
                            fastGptChatSessionMapper.updateFastGptChatSession(ss);
                        }
                    }
                }
            }
        }
    }

    void qwSendAppMsg(String corpId,Integer agentId, String qwUserId,String content){
        QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(corpId);
        QwSendMsgParam qwSendMsgParam2 = new QwSendMsgParam();
        qwSendMsgParam2.setAgentid(agentId);
        qwSendMsgParam2.setTouser(qwUserId);
        QwSendMsgParam.Text text2 = new QwSendMsgParam.Text();
        text2.setContent(content);
        qwSendMsgParam2.setText(text2);
        qwSendMsgParam2.setMsgtype("text");
        qwApiService.sendMsg(qwSendMsgParam2, qwCompany.getCorpId());
    }
    /** 添加企微性别 **/
    private void addUserSex(QwExternalContact qwExternalContacts) {

        QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(qwExternalContacts.getId());
        if (qwExternalContacts.getGender()!=0){
            if (info!=null){
                info.setSex(qwExternalContacts.getGender()==1?"男":"女");
                qwExternalContactInfoMapper.updateQwExternalContactInfo(info);

            }else {
                QwExternalContactInfo qwExternalContactInfo = new QwExternalContactInfo();
                qwExternalContactInfo.setExternalContactId(qwExternalContacts.getId());
                qwExternalContactInfo.setSex(qwExternalContacts.getGender()==1?"男":"女");
                qwExternalContactInfo.setCreateTime(new Date());
                qwExternalContactInfoMapper.insertQwExternalContactInfo(qwExternalContactInfo);

            }
        }



    }
    /** Ai发送课程链接 **/
    private void sendUrlLink(String content, QwHookMsgVO msgVo, QwUser user, QwSession session) {
        if (content.contains("【发送课程：当天课程】")){
            FsCourseWatchLogVO fsCourseWatchLogVO = watchLogMapper.selectFsCourseWatchLogByExtIdAndQwUserId(session.getQwExtId(), user.getId());
            if (fsCourseWatchLogVO!=null){
                FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                param.setVideoId(fsCourseWatchLogVO.getVideoId());
                param.setQwUserId(user.getId());
                param.setDays(1);
                param.setCorpId(user.getCorpId());
                param.setCourseId(fsCourseWatchLogVO.getCourseId());
                param.setCompanyUserId(user.getCompanyUserId());
                param.setCompanyId(user.getCompanyId());
                param.setQwExternalId(Long.parseLong(session.getQwExtId()));
                param.setSendTime(new Date());
                R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
                qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsCourseWatchLogVO.getVideoId()+""),
                        Integer.valueOf(fsCourseWatchLogVO.getCourseId()+""),
                        String.valueOf(user.getId()),
                        String.valueOf(user.getCompanyUserId()),
                        String.valueOf(user.getCompanyId()),
                        String.valueOf(session.getQwExtId()),2);
                if (linkUrl != null && linkUrl.get("url") != null) {
                    String s = (String)linkUrl.get("url");
                    // sendWebSocketMsg(s,msgVo,user,session);
                }
            }
        }
        else if (content.contains("【发送课程")){
            Pattern c = Pattern.compile("【发送课程：(.*?)】", Pattern.DOTALL);
            Matcher cMatcher = c.matcher(content);
            while  (cMatcher.find()) {
                String trim = cMatcher.group(1).trim();
                if(trim!=null&&!trim.equals("")){
                    FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoStringId(trim);
                    if (fsUserCourseVideo==null){
                        FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                        param.setVideoId(fsUserCourseVideo.getVideoId());
                        param.setQwUserId(user.getId());
                        param.setDays(1);
                        param.setCorpId(user.getCorpId());
                        param.setCourseId(fsUserCourseVideo.getCourseId());
                        param.setCompanyUserId(user.getCompanyUserId());
                        param.setCompanyId(user.getCompanyId());
                        param.setQwExternalId(Long.parseLong(session.getQwExtId()));
                        param.setSendTime(new Date());
                        R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
                        qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsUserCourseVideo.getVideoId()+""),
                                Integer.valueOf(fsUserCourseVideo.getCourseId()+""),
                                String.valueOf(user.getId()),
                                String.valueOf(user.getCompanyUserId()),
                                String.valueOf(user.getCompanyId()),
                                String.valueOf(session.getQwExtId()),2);
                        if (linkUrl != null && linkUrl.get("url") != null) {
                            String s = (String)linkUrl.get("url");
                            // sendWebSocketMsg(s,msgVo,user,session);
                        }
                    }

                }else {
                    log.error("发送课程不存在:"+trim);
                }

            }
        }
    }
    /** 发送Ai消息 **/
    private R  sendAiMsg(Integer i,FastGptChatSession fastGptChatSession, FastGptRole role,QwUser user,Long qwExternalContactsId,String appKey,QwExternalContact qwExternalContacts,Long sender){
        //等待5秒
        try {
            Thread.sleep(10000); // 5000 毫秒 = 5 秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //获取现在的次数
        Integer reply = (Integer)redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
        if (reply!=i){
            //次数变动 重新等待5秒
            R r = sendAiMsg(reply, fastGptChatSession, role, user, qwExternalContactsId, appKey, qwExternalContacts,sender);
            return r;
        }else {
            System.out.println("开始ai回答");
            ChatParam param=new ChatParam();
            param.setChatId(fastGptChatSession.getChatId());
            param.setStream(false);
            param.setDetail(true);
            ChatParam.Variables variables=new ChatParam.Variables();
            variables.setUid(user.getFastGptRoleId().toString());
            variables.setName("test");
            param.setVariables(variables);
            List<ChatParam.Message> messageList=new ArrayList<ChatParam.Message>();
            param.setMessages(messageList);
            //添加看客记录
            addCourseWatchLog(qwExternalContactsId);
            String msgC = (String)redisCache.getCacheObject("msg:" + fastGptChatSession.getSessionId());

            if (("今正科技".equals(cloudHostProper.getCompanyName()))) {
                //处理名称替换
                if (role.getReminderWords() != null && !role.getReminderWords().isEmpty() && role.getReminderWords().contains("#销售名称#")) {
                    CompanyUser companyUser = companyUserMapper.selectCompanyUserByQwUserId(user.getId());
                    if (companyUser != null) {
                        role.setReminderWords(role.getReminderWords().replace("#销售名称#", companyUser.getNickName()));
                    }
                }
            }

            //添加关键词
            addPromptWord(messageList,msgC,qwExternalContactsId,role.getReminderWords(), role.getContactInfo(),fastGptChatSession.getSessionId());
            R r = chatService.initiatingTakeChat(param, aiHostProper.getAiApi(), appKey);
            Object data1 = r.get("data");
            if(!(data1 instanceof KnowledgeBaseResult)){
                ChatDetailTStreamFResult data = (ChatDetailTStreamFResult) r.get("data");
                EventLogUtils.createEventTokenLog("发起对话",user,sender,data);
            }

            Integer reply2 = (Integer)redisCache.getCacheObject("reply:" + fastGptChatSession.getSessionId());
            //次数变动 重新等待5秒
            if (reply2!=i){
                System.out.println("等待");
                R r1 = sendAiMsg(reply, fastGptChatSession, role, user, qwExternalContactsId, appKey, qwExternalContacts,sender);
                return r1;
            }
            addSaveAiMsg(2,1,messageList.get(0).getContent(),user,fastGptChatSession.getSessionId(),role.getRoleId(),qwExternalContacts,fastGptChatSession.getUserId(),null,null,null);
            return r;
        }

    }
    /** 增加课程信息 **/
    private void addCourseWatchLog(Long id) {
        FsCourseWatchLogVO log = fsCourseWatchLogMapper.selectFsCourseWatchLogByExtId(id);
        if (log!=null){
            QwExternalContactInfo qwExternalContactInfo = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(id);
            QwExternalContactInfo info = new QwExternalContactInfo();
//            Date dateToCheck = log.getCreateTime(); // 假设这是你要检查的日期
//            Date today = new Date(); // 获取当前日期
            // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 格式化日期
            String name = log.getCourseName() + log.getTitle();
            name = name.replaceAll("[【】]", "");
//            if (sdf.format(dateToCheck).equals(sdf.format(today))) {
            info.setStudy(name);
            info.setCourseStatus(log.getLogType()==3?"待看课":log.getLogType()==1?"已完课":log.getLogType()==2?"已完课":"看课中断");

//            }else {
//                info.setStudy(name);
//                info.setCourseStatus("待看课");
//
//
//            }
            if(qwExternalContactInfo!=null){
                info.setId(qwExternalContactInfo.getId());
                qwExternalContactInfoMapper.updateQwExternalContactInfo(info);
            }else {
                info.setExternalContactId(id);
                info.setCreateTime(new Date());
                qwExternalContactInfoMapper.insertQwExternalContactInfo(info);

            }
        }
    }
    /** 组装发送AI内容 **/
    private void addPromptWord(List<ChatParam.Message> messageList,String count,Long extId,String words,String countInfo,Long sessionId){

        String  str="";

        // 这里获取后台的提示词进行匹配
        QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(extId);
        if(info==null){
            info=new QwExternalContactInfo();
        }

        if (info.getCreateTime()!=null){
            Calendar today = Calendar.getInstance();
            today.set(Calendar.HOUR_OF_DAY, 0);
            today.set(Calendar.MINUTE, 0);
            today.set(Calendar.SECOND, 0);
            today.set(Calendar.MILLISECOND, 0);
            Calendar createDate = Calendar.getInstance();
            createDate.setTime(info.getCreateTime());
            createDate.set(Calendar.HOUR_OF_DAY, 0);
            createDate.set(Calendar.MINUTE, 0);
            createDate.set(Calendar.SECOND, 0);
            createDate.set(Calendar.MILLISECOND, 0);
            if(createDate.before(today)){
                if (info.getTalk()==null||info.getTalk().isEmpty()){
                    info.setTalk("非首次交流");
                }
            }
        }

        if (info!=null){
            str="【用户状态信息\n";
            Field[] fields = info.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Excel annotation = field.getAnnotation(Excel.class);
                if (annotation != null) {
                    String name = field.getName();
                    String fieldName = annotation.name();
                    String[] split = countInfo.split(",");
                    for (String zName : split) {
                        if (zName.equals(name)) {
                            Object value = null;
                            try {
                                value = field.get(info);
                            } catch (IllegalAccessException e) {
                            }
                            if (value != null) {
                                str += fieldName + ": " + value.toString() + "\n";
                            }else if("交流状态".equals(fieldName) || "学习到的章节".equals(fieldName)){
                                str += fieldName + ":  \n";
                            }
                        }
                    }
                }
            }
        }
        str+="】\n";
        if (words!=null&&!"".equals(words)){
            str+="【你的角色信息：以下内容为你的信息状态的补充而非用户信息，相当于放在角色任务里面，问到了需要知晓，但是如果无关的时候请无视此段内容 "+"\""+words+"\""+"】\n";
        }

        List<FastGptChatMsg> msgs=fastGptChatMsgService.selectFastGptChatMsgByMsgSessionIdAndExtId(sessionId,extId);
        if (!msgs.isEmpty()){
            Collections.reverse(msgs);
            msgs.remove(msgs.size() - 1);
            str+="【历史聊天内容：\n";
            for (FastGptChatMsg msg : msgs) {
                Integer sendType = msg.getSendType();
                String content = msg.getContent();
                if(sendType!=1){
                    if (content!=null&&content.length()>150){
                        continue;
                    }
                }

                str +=(sendType==1?"用户:":"AI:")+content+"\n";
            }
            str+="】\n";
        }

        if (count!=null&&!"".equals(count)){
            str+="【用户说的话内容（之前的内容仅仅为背景，你知道即可，以下才是用户真实说的话的内容）\n" +
                    "\""+count+"\""+"\n" +
                    "】";
        }


        ChatParam.Message message1=new ChatParam.Message();
        message1.setRole("user");
        message1.setContent(str);
        messageList.add(message1);
    }
    /** 组装表情 **/
    public static List<String> countString(String input) {

        List<String> stringList = new ArrayList<>();
        // 所有的回车都分段发送
        String[] split = input.split("\n");
        for (String s : split) {
            List<String> sList = subCount(s);
            stringList.addAll(sList);
        }
//        if (isEmoji){
//            Random random = new Random();
//            String[] emojiMorning = new String[] {
//                    "😊",  // 微笑
//                    "☀️",  // 太阳
//                    "🌹",  // 玫瑰
//                    "☕️",  // 茶杯
//                    "💪",  // 强壮
//                    "❤️"   // 爱心
//            };
//            String[] emojiEvening = new String[] {
//                    "😊",  // 微笑
//                    "🌟",  // 星星
//                    "🌹",  // 玫瑰
//                    "☕️",  // 茶杯
//                    "💪",  // 强壮
//                    "❤️"   // 爱心
//            };
//            List<String> sebdList = new ArrayList<>();
//            for (String segment : stringList) {
//                if(!segment.trim().equals("")){
//                    LocalTime currentTime = LocalTime.now();
//                    LocalTime startTime = LocalTime.of(5, 0);
//                    LocalTime endTime   = LocalTime.of(18, 0);
//                    int sj = random.nextInt(2);
//                    // 判断当前时间是否在5点到18点之间
//                    String emj="";
//                    if (sj==0){
//                        if (currentTime.isAfter(startTime) && currentTime.isBefore(endTime)) {
//                            int i = random.nextInt(1);
//                            emj=emojiMorning[random.nextInt(emojiMorning.length-1)];
//                        } else {
//                            emj=emojiEvening[random.nextInt(emojiEvening.length-1)];
//                        }
//                    }
//                    sebdList.add(segment+emj) ;
//                }
//
//            }
//            return sebdList;
//        }


        return stringList;
    }
    /** 内容分段 **/
    static List<String> subCount(String s){
        ArrayList<String> a = new ArrayList<>();
        if (s.length()>30){
            String substring = s.substring(30);
            Pattern pattern = Pattern.compile("([~。!?]+)");
            String[] segments = pattern.split(substring);
            Matcher matcher = pattern.matcher(substring);
            if (matcher.find()&&segments.length>1) {
                int dh=0;
                String group = matcher.group();
                if (group.equals("。")){
                    group="";
                    dh=1;
                }
                String s1 = s.substring(0, 30) + segments[0] + group;
                a.addAll(Arrays.asList(s1));
                if (s.substring(s1.length())!=null&&!s.substring(s1.length()+dh).equals("")){
                    List<String> add = subCount(s.substring(s1.length()+dh));
                    a.addAll(add);
                }
            }else {
                a.add(s);
                return  a;
            }
        }else {
            a.add(s);
        }
        return  a;
    }
    /** 增加用户信息以及打标签 **/
    private void addUserInfo(String word,Long extId,FastGptChatSession fastGptChatSession)  {
        Pattern pattern = Pattern.compile("【用户状态信息(.*?)】", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(word);

        while  (matcher.find()) {
            QwExternalContactInfo info = qwExternalContactInfoMapper.selectQwExternalContactInfoByExternalContactId(extId);
            String trim = matcher.group(1).trim();
            String[] zd = trim.split("\n");
            boolean b=false;

            if (info==null){
                info=new QwExternalContactInfo();
                b=true;
            }
            Field[] fields = info.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Excel annotation = field.getAnnotation(Excel.class);
                if (annotation != null) {
                    //中文名称
                    String fieldName = annotation.name();
                    String valueName ="";
                    Object value = null;
                    try {
                        value = field.get(info);
                    } catch (IllegalAccessException e) {
                    }
                    if (value != null) {
                        valueName= value.toString();
                    }
                    for (String s : zd) {
                        String[] zdName=null;
                        if (s.contains(":")){
                            zdName = s.split(":");
                        }
                        if (s.contains("：")){
                            zdName = s.split("：");
                        }
                        if (zdName!=null&&zdName.length==2){
                            String name1 = zdName[0];
                            String name2 = zdName[1];
                            if (name1.trim().equals(fieldName)){
                                String name2Trim = name2.trim();
                                if (!name2Trim.isEmpty()){
                                    if(name1.equals("交流状态")){
                                        if (name2Trim.equals("非首次交流")){
                                            if (fastGptChatSession.getRemindStatus()!=null&&fastGptChatSession.getRemindStatus()==1){
                                                FastGptChatSession s1 = new FastGptChatSession();
                                                s1.setSessionId(fastGptChatSession.getSessionId());
                                                s1.setRemindStatus(0);
                                                s1.setRemindCount(0);
                                                fastGptChatSessionMapper.updateFastGptChatSession(s1);
                                            }
                                        }
                                    }
                                    if (!valueName.trim().equals(name2Trim)){
                                        if(name1.equals("学习到的章节")||name1.equals("今日课程完成情况")){
                                            continue;
                                        }

                                        if (name2Trim.contains("delete")&&name2Trim.contains("；")){
                                            name2Trim = name2Trim.replaceAll("delete.*?；", "");
                                        }else if (name2Trim.contains("delete")){
                                            name2Trim=" ";
                                        }
                                        try {
                                            // 允许修改私有属性
                                            field.setAccessible(true);
                                            // 修改 name 属性的值
                                            field.set(info, name2Trim);
                                            b=true;
                                        } catch (Exception e) {
                                            System.out.println("修改错误");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (b){
                if (info.getId()!=null){
                    qwExternalContactInfoMapper.updateQwExternalContactInfo(info);
                }else {
                    info.setExternalContactId(extId);
                    info.setCreateTime(new Date());
                    qwExternalContactInfoMapper.insertQwExternalContactInfo(info);
                }
            }
        }
        Pattern tag = Pattern.compile("【标签：(.*?)】", Pattern.DOTALL);
        Matcher TagMatcher = tag.matcher(word);
        while  (TagMatcher.find()) {
            String trimTag = TagMatcher.group(1).trim();
            if(trimTag!=null&&!trimTag.equals("")){
                qwTagGroupService.addQwTagByAi(trimTag,extId);
            }

        }

        Pattern delTag = Pattern.compile("【移除标签：(.*?)】", Pattern.DOTALL);
        Matcher delTagMatcher = delTag.matcher(word);
        while  (delTagMatcher.find()) {
            String deTag = delTagMatcher.group(1).trim();
            if(deTag!=null&&!deTag.equals("")){
                qwTagGroupService.delQwTagByAi(deTag,extId);
            }

        }

        Pattern addTime = Pattern.compile("【开始计时：(.*?)】", Pattern.DOTALL);
        Matcher addTimeMather = addTime.matcher(word);
        while  (addTimeMather.find()) {
            try {
                String time = addTimeMather.group(1).trim();
                int t = Integer.parseInt(time);
                FastGptChatSession s1 = new FastGptChatSession();
                s1.setSessionId(fastGptChatSession.getSessionId());
                Calendar calendar = Calendar.getInstance(); // 获取当前时间
                calendar.add(Calendar.MINUTE, t); // 增加t分钟
                s1.setRemindTime(calendar.getTime());
                s1.setRemindStatus(1);
                s1.setRemindCount(0);
                fastGptChatSessionMapper.updateFastGptChatSession(s1);

            }catch (Exception e){
                log.info("ai计时错误"+word);
            }

        }
    }
    /** 过滤[] **/
    private static String replace(String s){

        if(org.springframework.util.StringUtils.isEmpty(s)) return "";

        String regex1 = "<llnnerThoughtBeginl>[\\s\\S]*?<lnnerThoughtEnd|>";
        // 创建 Pattern 对象
        Pattern pattern1 = Pattern.compile(regex1);
        // 创建 Matcher 对象
        Matcher matcher1 = pattern1.matcher(s);
        s = matcher1.replaceAll("");

        String regex = "【[\\s\\S]*?】";
        // 创建 Pattern 对象
        Pattern pattern = Pattern.compile(regex);
        // 创建 Matcher 对象
        Matcher matcher = pattern.matcher(s);
        // 替换匹配到的内容
        return matcher.replaceAll("");
    }
    /** 过滤[] **/
    private static String replaceWxEmo(String s){

        if(org.springframework.util.StringUtils.isEmpty(s)) return "";
        // 替换匹配到的内容
        String text = s.replaceAll("\\[.*?]", "").trim();
        return EmojiParser.removeAllEmojis(text);
    }
    /** 发送语音过滤 */
    private  String voiceHomo(String content){
        List<FastgptChatVoiceHomo> homos = fastgptChatVoiceHomoMapper.selectFastgptChatVoiceHomoList(new FastgptChatVoiceHomo());
        for (FastgptChatVoiceHomo homo : homos) {
            if (content.contains(homo.getContent())) {
                // 如果包含目标字段，则替换
                content= content.replace(homo.getContent(), homo.getChangeCount());
            } else {
            }
        }
        content = content.replaceAll("[a-zA-Z]", "")
                .replaceAll("\\s", "");
        return content;
    }
    /** 替换违禁词 **/
    private  String replaceWords(String content){
        List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
        for (FastGptChatReplaceWords word : words) {
            if (content.contains(word.getContent())) {
                // 如果包含目标字段，则替换
                content= content.replace(word.getContent(), word.getChangeCount());
            } else {
            }
        }
        return content;
    }
    /** 发送语音回复 */
    private static AudioVO getSilk(String count,Long userId) {
        AudioServiceImpl audioService = new AudioServiceImpl();
        AudioVO Silk = audioService.TextToVoice(count,userId);
        return Silk;
    }
    /** 发送普通消息 */
//    private void sendWebSocketMsg(String count, QwHookMsgVO msgVo, QwUser user,QwSession session) {
//        //发送socket
//        if (count!=null&& !count.trim().isEmpty()){
//            qwMsgService.addAiMsg(session,count,1,user);
//            QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
//            QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
//            sendMsgParam.setType(101003);
//            sendMsgData.setMsg(replaceWords(count));
//            sendMsgData.setSendId(msgVo.getSender());
//            sendMsgData.setSyncKey("1");
//            sendMsgParam.setData(sendMsgData);
//            SendAIParam sendAIParam = new SendAIParam();
//            sendAIParam.setCmd("aiReplyMsg");
//            sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
//            sendAIParam.setKey(user.getAppKey());
//            redisTemplate.opsForList().leftPush("AiMsg:"+user.getAppKey(), JSON.toJSONString(sendAIParam));
//        }
//
//
//    }

    /** 发送定时任务课程链接 */
    private void sendTaskUrlLink(String content, String sendId, QwUser user, FastGptChatSession session) {
        if (content.contains("【发送课程：当天课程】")){
            FsCourseWatchLogVO fsCourseWatchLogVO = watchLogMapper.selectFsCourseWatchLogByExtIdAndQwUserId(session.getQwExtId().toString(), user.getId());
            if (fsCourseWatchLogVO!=null){
                FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                param.setVideoId(fsCourseWatchLogVO.getVideoId());
                param.setQwUserId(user.getId());
                param.setDays(1);
                param.setCorpId(user.getCorpId());
                param.setCourseId(fsCourseWatchLogVO.getCourseId());
                param.setCompanyUserId(user.getCompanyUserId());
                param.setCompanyId(user.getCompanyId());
                param.setQwExternalId(session.getQwExtId());
                param.setSendTime(new Date());
                R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
                qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsCourseWatchLogVO.getVideoId()+""),
                        Integer.valueOf(fsCourseWatchLogVO.getCourseId()+""),
                        String.valueOf(user.getId()),
                        String.valueOf(user.getCompanyUserId()),
                        String.valueOf(user.getCompanyId()),
                        String.valueOf(session.getQwExtId()),2);
                if (linkUrl != null && linkUrl.get("url") != null) {
                    String s = (String)linkUrl.get("url");
                    sendWebTaskSocketMsg(s,sendId,user);
                }
            }
        }
        else if (content.contains("【发送课程")){
            Pattern c = Pattern.compile("【发送课程：(.*?)】", Pattern.DOTALL);
            Matcher cMatcher = c.matcher(content);
            while  (cMatcher.find()) {
                String trim = cMatcher.group(1).trim();
                if(trim!=null&&!trim.equals("")){
                    FsUserCourseVideo fsUserCourseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoStringId(trim);
                    System.out.println("课程："+fsUserCourseVideo);
                    FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
                    param.setVideoId(fsUserCourseVideo.getVideoId());
                    param.setQwUserId(user.getId());
                    param.setDays(1);
                    param.setCorpId(user.getCorpId());
                    param.setCourseId(fsUserCourseVideo.getCourseId());
                    param.setCompanyUserId(user.getCompanyUserId());
                    param.setCompanyId(user.getCompanyId());
                    param.setQwExternalId(session.getQwExtId());
                    param.setSendTime(new Date());
                    R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
                    qwContactWayService.addWatchLogIfNeeded(Integer.valueOf(fsUserCourseVideo.getVideoId()+""),
                            Integer.valueOf(fsUserCourseVideo.getCourseId()+""),
                            String.valueOf(user.getId()),
                            String.valueOf(user.getCompanyUserId()),
                            String.valueOf(user.getCompanyId()),
                            String.valueOf(session.getQwExtId()),2);
                    if (linkUrl != null && linkUrl.get("url") != null) {
                        String s = (String)linkUrl.get("url");
                        sendWebTaskSocketMsg(s,sendId,user);
                    }
                }

            }
        }



    }
    /** 发送定时任务消息 */
    private void sendWebTaskSocketMsg(String count, String sendId, QwUser user) {
        //发送socket
        //文本消息
        QwHookSendMsgParam sendMsgParam=new QwHookSendMsgParam();
        QwHookSendMsgParam.QwHookSendMsgData sendMsgData=new QwHookSendMsgParam.QwHookSendMsgData();
        sendMsgParam.setType(101003);
        sendMsgData.setMsg(count);
        sendMsgData.setSendId(sendId);
        sendMsgData.setSyncKey("1");
        sendMsgParam.setData(sendMsgData);
        SendAIParam sendAIParam = new SendAIParam();
        sendAIParam.setCmd("aiReplyMsg");
        sendAIParam.setData(JSONUtil.toJsonStr(sendMsgParam));
        sendAIParam.setKey(user.getAppKey());
        redisTemplate.opsForList().leftPush("AiMsg:"+user.getAppKey(), JSON.toJSONString(sendAIParam));
    }

    @Override
    public R qwHookNotifyAddMsgNew(Long qwUserID, Long sender,String count,String uid,Integer type) {
        QwUser sendUser = qwUserMapper.selectQwUserById(qwUserID);


        if (sendUser!=null){

            String extId = getExtId(sender, uid, sendUser.getServerId());
            QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(extId, sendUser.getCorpId(),sendUser.getQwUserId());
            if (qwExternalContacts==null){
                return R.ok();
            }
            FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), sendUser.getId());
            if (fastGptChatSession!=null){
                saveQwUserMsg(fastGptChatSession,2,count,sendUser);
                // 客服进行回复后就转人工10分钟
                if(type == 1){
                    Calendar calendar = Calendar.getInstance();
                    calendar.add(Calendar.MINUTE, -5);
                    Date lastTime = calendar.getTime();
                    if(lastTime.after(fastGptChatSession.getCreateTime())){
                        Calendar calendar1 = Calendar.getInstance();
                        //定时任务会处理10分钟以内的，所以设置20分钟
                        calendar1.add(Calendar.MINUTE, 10);
                        Date expireTime = calendar1.getTime();

                        FastGptChatSession chatSession = new FastGptChatSession();
                        chatSession.setLastTime(expireTime);
                        chatSession.setIsArtificial(1);
                        chatSession.setSessionId(fastGptChatSession.getSessionId());

                        fastGptChatSessionMapper.updateFastGptChatSession(chatSession);
                    }
                }
            }else {

                if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){
                    if(sendUser.getFastGptRoleId()!=null){
                        fastGptChatSession = new FastGptChatSession();
                        String chatId = UUID.randomUUID().toString();
                        fastGptChatSession.setChatId(chatId);
                        fastGptChatSession.setKfId(sendUser.getFastGptRoleId().toString());
                        fastGptChatSession.setStatus(1);
                        fastGptChatSession.setRemindCount(0);
                        fastGptChatSession.setRemindStatus(0);
                        fastGptChatSession.setCreateTime(new Date());
                        fastGptChatSession.setQwExtId(qwExternalContacts.getId());
                        fastGptChatSession.setQwUserId(sendUser.getId());
                        fastGptChatSession.setIsArtificial(0);
                        fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
                        fastGptChatSession.setNickName(qwExternalContacts.getName());
                        fastGptChatSession.setCompanyId(sendUser.getCompanyId());
                        fastGptChatSession.setLastTime(new Date());
                        fastGptChatSession.setIsReply(0);
                        fastGptChatSession.setUserId(String.valueOf(sender));
                        fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
                        addUserSex(qwExternalContacts);
                        saveQwUserMsg(fastGptChatSession,2,count,sendUser);
                    }
                }
            }
        }
        return R.ok();
    }

    @Override
    public R qwHookNotifyAddMsg(Long qwUserID, Long sender,String count,String uid) {
        QwUser sendUser = qwUserMapper.selectQwUserById(qwUserID);


        if (sendUser!=null){

            String extId = getExtId(sender, uid, sendUser.getServerId());
            QwExternalContact qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByExternalUserIdAndQwUserId(extId, sendUser.getCorpId(),sendUser.getQwUserId());
            if (qwExternalContacts==null){
                return R.ok();
            }
            FastGptChatSession fastGptChatSession = fastGptChatSessionMapper.selectFastGptChatSessionByQwExternalContactsAndUserId(qwExternalContacts.getId(), sendUser.getId());
            if (fastGptChatSession!=null){
                saveQwUserMsg(fastGptChatSession,2,count,sendUser);
            }else {

                if(qwExternalContacts.getType()!=null&&qwExternalContacts.getType()==1){
                    if(sendUser.getFastGptRoleId()!=null){
                        fastGptChatSession = new FastGptChatSession();
                        String chatId = UUID.randomUUID().toString();
                        fastGptChatSession.setChatId(chatId);
                        fastGptChatSession.setKfId(sendUser.getFastGptRoleId().toString());
                        fastGptChatSession.setStatus(1);
                        fastGptChatSession.setRemindCount(0);
                        fastGptChatSession.setRemindStatus(0);
                        fastGptChatSession.setCreateTime(new Date());
                        fastGptChatSession.setQwExtId(qwExternalContacts.getId());
                        fastGptChatSession.setQwUserId(sendUser.getId());
                        fastGptChatSession.setIsArtificial(0);
                        fastGptChatSession.setAvatar(qwExternalContacts.getAvatar());
                        fastGptChatSession.setNickName(qwExternalContacts.getName());
                        fastGptChatSession.setCompanyId(sendUser.getCompanyId());
                        fastGptChatSession.setLastTime(new Date());
                        fastGptChatSession.setIsReply(0);
                        fastGptChatSessionMapper.insertFastGptChatSession(fastGptChatSession);
                        addUserSex(qwExternalContacts);
                        saveQwUserMsg(fastGptChatSession,2,count,sendUser);
                    }
                }
            }
        }
        return R.ok();
    }

    @Override
    public void expireAiMsg() {
        List<QwSopLogs> qwSopLogs = qwSopLogsMapper.selectExpireAiMsg();
        if (qwSopLogs==null|| qwSopLogs.isEmpty()){
            System.out.println("无");
            return;
        }
        qwSopLogsMapper.batchUpdateQwSopLogsById(qwSopLogs);
        List<QwSopLogs> distinctList = new ArrayList<>(qwSopLogs.stream()
                .collect(Collectors.toMap(
                        QwSopLogs::getExternalId,  // 以 extId 作为 Key
                        log -> log,            // Value 是对象本身
                        (existing, replacement) -> existing  // 遇到重复时保留已有值（第一个）
                ))
                .values());
        for (QwSopLogs logs : distinctList) {
            log.info("转人工:"+logs.getCorpId());
            QwCompany qwCompany = qwCompanyMapper.selectQwCompanyByCorpId(logs.getCorpId());
            sendQwAppMsg(logs.getCorpId(),Integer.parseInt(qwCompany.getServerAgentId().trim()),logs.getQwUserid(),"您的客户:"+logs.getExternalUserName()+"因  AI回复内容过期转人工，请及时登录插件确定定位配置准确");
        }

    }


    String getExtId(Long id,String uid,Long serverId){
        WxWorkVid2UserIdDTO wxWorkVid2UserIdDTO = new WxWorkVid2UserIdDTO();
        wxWorkVid2UserIdDTO.setUser_id(Arrays.asList(id));
        wxWorkVid2UserIdDTO.setUuid(uid);
        WxWorkResponseDTO<List<WxWorkVid2UserIdRespDTO>> WxWorkVid2UserIdRespDTO = wxWorkService.Vid2UserId(wxWorkVid2UserIdDTO,serverId);
        List<WxWorkVid2UserIdRespDTO> data = WxWorkVid2UserIdRespDTO.getData();
        if (data==null || data.isEmpty()){
            System.out.println("未获取到extId");
            return "";
        }
        com.fs.wxwork.dto.WxWorkVid2UserIdRespDTO dto = data.get(0);
        return dto.getOpenid();
    }

    @Override
    public WxWorkResponseDTO<String> getFileUrl(String uuid, String fileId, String aesKey, String authKey, String fileName, Integer fileSize, Long serverId) {
        WxwDownloadWeChatFileDTO weChatFileDTO = new WxwDownloadWeChatFileDTO();
        weChatFileDTO.setUuid(uuid);
        weChatFileDTO.setUrl(fileId);
        weChatFileDTO.setAes_key(aesKey);
        weChatFileDTO.setAuth_key(authKey);
        weChatFileDTO.setFile_name(fileName);
        weChatFileDTO.setSize(fileSize);
        return wxWorkService.downloadWeChatFile(weChatFileDTO, serverId);
    }

}
