package com.fs.app.service;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.fs.app.util.WXBizMsgCrypt;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.utils.DateUtils;
import com.fs.company.service.ICompanyConfigService;
import com.fs.qw.domain.*;
import com.fs.qw.mapper.QwCompanyMapper;
import com.fs.qw.mapper.QwExternalContactMapper;
import com.fs.qw.mapper.QwUserMapper;
import com.fs.qw.param.QwAutoRulesTagsParams;
import com.fs.qw.service.*;
import com.fs.qwApi.Result.QwGroupChatDetailsResult;
import com.fs.qwApi.Result.QwOpenidResult;
import com.fs.qwApi.domain.QwResult;
import com.fs.qwApi.param.QwEditUserTagParam;
import com.fs.qwApi.param.QwOpenidByUserParams;
import com.fs.qwApi.util.AesException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tencent.wework.Finance;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.crypto.Cipher;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class QwDataCallbackService {

    org.slf4j.Logger logger= LoggerFactory.getLogger(getClass());
    @Autowired
    ICompanyConfigService companyConfigService;
    @Autowired
    IQwExternalContactService qwExternalContactService;
    @Autowired
    IQwTagGroupService qwTagGroupService;
    @Autowired

    QwUserMapper qwUserMapper;

    @Autowired
    com.fs.qwApi.service.QwApiService qwApiService;

    @Autowired
    IQwGroupChatService qwGroupChatService;

    @Autowired
    IQwGroupChatUserService qwGroupChatUserService;

    @Autowired
    IQwAutoTagsService qwAutoTagsService;

    @Autowired
    IQwAutoTagsLogsService qwAutoTagsLogsService;

    @Autowired
    QwExternalContactMapper qwExternalContactMapper;

    @Autowired
    private IQwDeptService qwDeptService;


    @Autowired
    private RedisCache redisCache;
    @Autowired
    private QwCompanyMapper qwCompanyMapper;

    @Async
    public void dataCallback( Document document,String corpId,QwCompany qwCompany) throws Exception {


        Element root = document.getDocumentElement();
        NodeList msgTypeNode = root.getElementsByTagName("MsgType");
        String msgType = msgTypeNode.item(0).getTextContent();
        if(msgType.equals("event")){
            NodeList eventNode = root.getElementsByTagName("Event");
            String event = eventNode.item(0).getTextContent();
            String changeType ="";
            NodeList changeTypeList = root.getElementsByTagName("ChangeType");
            if(changeTypeList.getLength() > 0) {
                changeType = changeTypeList.item(0).getTextContent();
            }

            switch (event){
                //调用api接口删除员工
                case "unsubscribe" :
                    String fromUserName = root.getElementsByTagName("FromUserName").item(0).getTextContent();
                    QwUser delQwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, fromUserName);
                    if (delQwUser!=null){
                        delQwUser.setIsDel(2);
                        delQwUser.setStatus(0);
                        qwUserMapper.updateQwUser(delQwUser);
                        QwExternalContact qwExternalContact = new QwExternalContact();
                        qwExternalContact.setUserId(fromUserName);
                        qwExternalContact.setStatus(0);
                        qwExternalContact.setCorpId(corpId);
                        List<QwExternalContact> qwExternalContacts = qwExternalContactService.selectQwExternalContactList(qwExternalContact);
                        for (QwExternalContact externalContact : qwExternalContacts) {
                            QwExternalContact lz = new QwExternalContact();
                            lz.setId(externalContact.getId());
                            lz.setStatus(1);
                            qwExternalContactMapper.updateQwExternalContact(lz);
                        }

                    }
                    break;
                case "subscribe":
                    String fromUserNameUserId = root.getElementsByTagName("FromUserName").item(0).getTextContent();
                    QwUser updateOrInsertQwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, fromUserNameUserId);
                    //userid转openid
                    QwOpenidByUserParams param=new QwOpenidByUserParams();
                    param.setUserid(fromUserNameUserId);
                    QwOpenidResult qwOpenidResult = qwApiService.useridToOpenid(param, corpId);
                    if (updateOrInsertQwUser!=null&&qwOpenidResult.getErrCode()==0){
                        updateOrInsertQwUser.setOpenid(qwOpenidResult.getOpenid());
                        qwUserMapper.updateQwUser(updateOrInsertQwUser);
                    }

                    break;
                case "change_contact" :
                    if (changeType.equals("create_user")){
                        String userID = root.getElementsByTagName("UserID").item(0).getTextContent();
                        QwUser qw = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userID);
                        QwUser qwUser = new QwUser();
                        qwUser.setQwUserId(userID);
                        qwUser.setCreateTime(new Date());
                        qwUser.setCorpId(corpId);

                        if (qw==null){
                            String serverQwUserName = qwApiService.getServerQwUserName(corpId, qwCompany.getOpenSecret(), userID);
                            qwUser.setQwUserId(userID);
                            qwUser.setDepartment(root.getElementsByTagName("Department").item(0).getTextContent().toString());
                            qwUser.setQwUserName(serverQwUserName);
                            QwOpenidByUserParams param1=new QwOpenidByUserParams();
                            param1.setUserid(userID);
                            QwOpenidResult qwOpenid = qwApiService.useridToOpenid(param1, corpId);
                            qwUser.setOpenid(qwOpenid.getOpenid());
                            qwUserMapper.insertQwUser(qwUser);
                        }else {
                            qw.setIsDel(0);
                            qw.setUpdateTime(new Date());
                            qwUserMapper.updateQwUser(qw);
                        }
                    }
                    else if (changeType.equals("delete_user")){
                        String userID = root.getElementsByTagName("UserID").item(0).getTextContent();
                        QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, userID);
                        if (qwUser!=null){
                            qwUser.setIsDel(2);
                            qwUser.setStatus(0);
                            qwUserMapper.updateQwUser(qwUser);
                            QwExternalContact qwExternalContact = new QwExternalContact();
                            qwExternalContact.setUserId(userID);
                            qwExternalContact.setStatus(0);
                            qwExternalContact.setCorpId(corpId);
                            List<QwExternalContact> qwExternalContacts = qwExternalContactService.selectQwExternalContactList(qwExternalContact);
                            for (QwExternalContact externalContact : qwExternalContacts) {
                                QwExternalContact lz = new QwExternalContact();
                                lz.setId(externalContact.getId());
                                lz.setStatus(1);
                                lz.setCorpId(corpId);
                                qwExternalContactMapper.updateQwExternalContact(lz);
                            }
                        }
                    }
                    else if (changeType.equals("create_party")){

                        qwDeptService.insertOrUpdateQwDept(corpId);
                    }
                    else if (changeType.equals("update_party")){

                        qwDeptService.insertOrUpdateQwDept(corpId);

                    }else if (changeType.equals("delete_party")){
                        QwDept qwDept=new QwDept();
                        qwDept.setDeptId(Long.valueOf(root.getElementsByTagName("Id").item(0).getTextContent()));
                        qwDeptService.deleteQwDeptByDeptId(qwDept);
                    }

                    break;
                case "change_external_contact" :
                    switch (changeType){
                        case "add_external_contact":
                            String State =null;
                            NodeList StateList = root.getElementsByTagName("State");
                            if(StateList.getLength() > 0) {
                                State = StateList.item(0).getTextContent();
                            }
                            String WelcomeCode =null;
                            NodeList WelcomeCodeList = root.getElementsByTagName("WelcomeCode");
                            if(WelcomeCodeList.getLength() > 0) {
                                WelcomeCode = WelcomeCodeList.item(0).getTextContent();
                            }
                            qwExternalContactService.insertQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),null,corpId,State,WelcomeCode);
                            break;
                        case "edit_external_contact":
                            qwExternalContactService.updateQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),corpId);
                            break;
                        case "del_external_contact":
                            qwExternalContactService.deleteQwExternalContactByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),corpId);
                            break;
                        case "del_follow_user":
                            qwExternalContactService.deletefollowUserByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),corpId);
                            break;
                        case "transfer_fail":
                            qwExternalContactService.transferFailByExternalUserId(root.getElementsByTagName("ExternalUserID").item(0).getTextContent(),root.getElementsByTagName("UserID").item(0).getTextContent(),corpId,root.getElementsByTagName("FailReason").item(0).getTextContent());
                            break;
                    }
                    break;
                case "change_external_tag":

                    switch (changeType){
                        case "create":
                            qwTagGroupService.addTagByTagId(root.getElementsByTagName("TagType").item(0).getTextContent(),root.getElementsByTagName("Id").item(0).getTextContent(),corpId);
                            break;
                        case "update":
                            qwTagGroupService.updateTagByTagId(root.getElementsByTagName("TagType").item(0).getTextContent(),root.getElementsByTagName("Id").item(0).getTextContent(),corpId);
                            break;
                        case "delete":
                            qwTagGroupService.deleteTagByTagId(root.getElementsByTagName("TagType").item(0).getTextContent(),root.getElementsByTagName("Id").item(0).getTextContent(),corpId);
                            break;
                        case "shuffle":
                            qwTagGroupService.shuffleTagByTagId(root.getElementsByTagName("Id").item(0).getTextContent(),corpId);
                            break;

                    }

                    break;
                case "change_external_chat":

                    switch (changeType){
                        case "create":
                            //新建的客户群
                            qwGroupChatService.insertQwGroupChat(root.getElementsByTagName("ChatId").item(0).getTextContent(),corpId);
                            break;
                        case "update":

                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                            //群id
                            String chatId = root.getElementsByTagName("ChatId").item(0).getTextContent();
                            //变更详情
                            String updateDetail = root.getElementsByTagName("UpdateDetail").item(0).getTextContent();

                            //群信息
                            QwGroupChat qwGroupChat=new QwGroupChat();

                            //成员详细信息
                            QwGroupChatUser qwGroupChatUser=new QwGroupChatUser();
                            qwGroupChatUser.setCorpId(corpId);
                            //成员入群
                            if (updateDetail.equals("add_member")){

                                //入群方式
                                String joinScene = root.getElementsByTagName("JoinScene").item(0).getTextContent();

                                //消息创建时间
//                                    String CreateTime = root.getElementsByTagName("CreateTime").item(0).getTextContent();
//                                    Date date1 = new Date(Long.valueOf(CreateTime) * 1000); // 乘以1000是因为时间戳是以秒为单位，而Date期望毫秒
//                                    String formattedDate = sdf.format(date1);
                                String formattedDate = sdf.format(new Date());

                                //入群数量
                                String MemChangeCnt = root.getElementsByTagName("MemChangeCnt").item(0).getTextContent();

                                // 获取MemChangeList中的Item元素,当是成员入群或退群时有值。变更的成员列表
                                NodeList items = document.getElementsByTagName("Item");

                                QwAutoTags qwAutoTags = qwAutoTagsService.selectQwAutoTagsByChatIdJSON(corpId, chatId);
                                logger.info("成员入群:qwAutoTags:"+qwAutoTags);
                                //存分时段里符合条件的标签
                                Set<String> combinedTagsItem = new HashSet<>();

                                //添加标签的日志记录
                                QwAutoTagsLogs qwAutoTagsLogs=new QwAutoTagsLogs();

                                //添加的标签
                                QwEditUserTagParam qwEditUserTagParam = new QwEditUserTagParam();

                                boolean isMatch = false;

                                //查出 符合的标签
                                if (qwAutoTags != null) {
                                    List<QwAutoRulesTagsParams> qwAutoRulesTagsParams = JSON.parseArray(qwAutoTags.getRulesTags(), QwAutoRulesTagsParams.class);
                                    for (QwAutoRulesTagsParams qrtp : qwAutoRulesTagsParams) {
                                        if (qrtp.getRules().contains(chatId));{
                                            combinedTagsItem.addAll(qrtp.getTags());
                                            isMatch=true;
                                            break;
                                        }

                                    }

                                }

                                logger.info("成员入群items:"+items.getLength());
                                //成员列表
                                for (int i = 0; i < items.getLength(); i++) {

                                    String userid = items.item(i).getTextContent();
                                    qwGroupChatUser.setChatId(chatId);
                                    qwGroupChatUser.setUserId(userid);
                                    qwGroupChatUser.setJoinScene(joinScene);
                                    qwGroupChatUser.setJoinTime(formattedDate);

                                    //这个群有符合条件的标签
                                    if (isMatch){

                                        //根据客户id获取 该客户属于哪个成员
                                        List<QwExternalContact> qwExternalContacts = qwExternalContactService.selectQwExternalContactByExternalUserId(userid, corpId);
                                        qwExternalContacts.stream().forEach(item->{

                                            qwEditUserTagParam.setUserid(item.getUserId());
                                            qwEditUserTagParam.setExternal_userid(userid);
                                            //总标签 转换回列表
                                            List<String> combinedTagsList = new ArrayList<>(combinedTagsItem);
                                            // 设置标签
                                            qwEditUserTagParam.setAdd_tag(combinedTagsList);


                                            qwAutoTagsLogs.setAutoTagId(qwAutoTags.getId());
                                            qwAutoTagsLogs.setType(2L);
                                            qwAutoTagsLogs.setQwUserid(item.getQwUserId());
                                            qwAutoTagsLogs.setExternalUserId(userid);
                                            qwAutoTagsLogs.setEffectiveRules(JSON.toJSONString(combinedTagsList));
                                            qwAutoTagsLogs.setAddTime(new Date());
                                            qwAutoTagsLogs.setChatId(chatId);
                                            qwAutoTagsLogs.setJoinScene(joinScene);
                                            qwAutoTagsLogs.setCorpId(corpId);
                                            //  qwAutoTagsLogs.setCompanyId(companyId);
                                            // 企微加标签
                                            QwResult qwResult = qwApiService.editUserTag(qwEditUserTagParam, corpId);
                                            logger.info("自动添加标签-入群行为：符合条件 " + qwResult);
                                            qwAutoTagsLogsService.insertQwAutoTagsLogs(qwAutoTagsLogs);
                                        });

                                    }


                                    //查一遍有没有这个人-有的话 更新一下（退群后再入群的人）
                                    QwGroupChatUser qwGroupChatUserOld = qwGroupChatUserService.selectQwGroupChatUserByExternalUserId(qwGroupChatUser);

                                    if (qwGroupChatUserOld==null) {
                                        qwGroupChatUserService.insertQwGroupChatUser(qwGroupChatUser);
                                    }else {
                                        qwGroupChatUserOld.setIsOut(1L);
                                        qwGroupChatUserOld.setCorpId(corpId);
                                        qwGroupChatUserOld.setJoinScene(joinScene);
                                        qwGroupChatUserOld.setJoinTime(formattedDate);
                                        qwGroupChatUserOld.setQuitScene(null);
                                        qwGroupChatUserOld.setOutTime(null);
                                        qwGroupChatUserService.groupChatUserJoinAgain(qwGroupChatUserOld);
                                    }

                                }
                                //先查一遍（后期可直接改sql,不查）
                                QwGroupChat qwGroupChatOld = qwGroupChatService.selectQwGroupChatByChatId(chatId);
                                if (qwGroupChatOld != null) {
                                    qwGroupChatOld.setCorpId(corpId);
                                    //当日入群数
                                    qwGroupChatOld.setTodayJoin(qwGroupChatOld.getTodayJoin()+Integer.valueOf(MemChangeCnt));
                                    //当前群人总数
                                    qwGroupChatOld.setGroupSize(qwGroupChatOld.getGroupSize()+Integer.valueOf(MemChangeCnt));

                                    qwGroupChatService.updateQwGroupChat(qwGroupChatOld,corpId);
                                }
                            }
                            //成员退群
                            if (updateDetail.equals("del_member")){

                                //退群数量
                                String MemChangeCnt = root.getElementsByTagName("MemChangeCnt").item(0).getTextContent();
                                //退群方式
                                String QuitScene = root.getElementsByTagName("QuitScene").item(0).getTextContent();

                                String CreateTime = root.getElementsByTagName("CreateTime").item(0).getTextContent();
                                Date date1 = new Date(Long.valueOf(CreateTime) * 1000); // 乘以1000是因为时间戳是以秒为单位，而Date期望毫秒
                                String formattedDate = sdf.format(date1);

                                // 获取MemChangeList中的Item元素,当是成员入群或退群时有值。变更的成员列表
                                NodeList items = document.getElementsByTagName("Item");

                                //成员列表
                                for (int i = 0; i < items.getLength(); i++) {
                                    String userid = items.item(i).getTextContent();
                                    //是否退群
                                    qwGroupChatUser.setIsOut(2L);
                                    //退群时间
                                    qwGroupChatUser.setOutTime(formattedDate);

                                    qwGroupChatUser.setChatId(chatId);
                                    qwGroupChatUser.setUserId(userid);
                                    //退群方式
                                    qwGroupChatUser.setQuitScene(Integer.parseInt(QuitScene));
                                    qwGroupChatUser.setCorpId(corpId);
                                    //更新
                                    qwGroupChatUserService.upDateDelGroupChatUser(qwGroupChatUser);
                                }

                                //先查一遍（后期可直接改sql,不查）
                                QwGroupChat qwGroupChatOld = qwGroupChatService.selectQwGroupChatByChatId(chatId);
                                if (qwGroupChatOld != null) {
                                    int memChangeCount;

                                    if (MemChangeCnt == null || MemChangeCnt.isEmpty()) {
                                        memChangeCount = 1;
                                    } else {
                                        try {
                                            memChangeCount = Integer.parseInt(MemChangeCnt);
                                        } catch (NumberFormatException e) {
                                            memChangeCount = 1;
                                        }
                                    }

                                    // 确保qwGroupChatOld不是null
                                    if (qwGroupChatOld != null) {
                                        //当日退群数
                                        Long todayOut = qwGroupChatOld.getTodayOut();
                                        if (todayOut != null) {

                                            qwGroupChatOld.setTodayJoin(todayOut + (long) memChangeCount);
                                        } else {

                                            qwGroupChatOld.setTodayJoin((long) memChangeCount); // 或者根据实际情况决定如何处理
                                        }

                                        //总退群数
                                        qwGroupChatOld.setAllOutGroup(qwGroupChatOld.getAllOutGroup()+memChangeCount);

                                        long newGroupSize = (qwGroupChatOld.getGroupSize() - memChangeCount) < 0 ? 0 : qwGroupChatOld.getGroupSize() - memChangeCount;

                                        //当前群人总数
                                        qwGroupChatOld.setGroupSize(newGroupSize);
                                        qwGroupChatOld.setCorpId(corpId);

                                        qwGroupChatService.updateQwGroupChat(qwGroupChatOld,corpId);

                                    }
                                }

                            }
                            //群主变更/群名变更/群公告变更
                            if (updateDetail.equals("change_owner")||updateDetail.equals("change_name")||updateDetail.equals("change_notice")){


                                //获取群聊详情
                                QwGroupChatDetailsResult qwGroupChatDetailsResult = qwApiService.groupChatDetails(chatId, corpId);

                                if (qwGroupChatDetailsResult.getErrCode()==0){
                                    QwGroupChatDetailsResult.GroupChats groupChat = qwGroupChatDetailsResult.getGroupChat();

                                    //群名
                                    String name = groupChat.getName();
                                    //群公告
                                    String notice = groupChat.getNotice();
                                    //群主id
                                    String owner = groupChat.getOwner();

                                    qwGroupChat.setName(name);
                                    qwGroupChat.setNotice(notice);
                                    qwGroupChat.setOwner(owner);
                                    qwGroupChat.setMemberVersion(groupChat.getMemberVersion());
                                    qwGroupChat.setCorpId(corpId);
                                    qwGroupChat.setChatId(chatId);
                                    qwGroupChat.setUpdateTime(DateUtils.getNowDate());
                                    //更新
                                    qwGroupChatService.updateQwGroupChat(qwGroupChat,corpId);

                                }
                            }

                            break;
                        case "dismiss":
                            //解散客户群（删掉!）
                            qwGroupChatService.deleteQwGroupChatByChatIdAndCompanyId(root.getElementsByTagName("ChatId").item(0).getTextContent(),corpId);
                            break;
                    }

                    break;
                default:
                    logger.info("默认："+event);
            }
        }
    }

    @Async
    public AjaxResult msgCallBack(String corpId,String requestBody, String msg_signature, String timestamp, String nonce) {
        try {
            /*WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(customConfig.getToken(), customConfig.getEncodingAesKey(), corpId);
            // 验签+解密
            String sMsg = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, requestBody);
            System.out.println("after decrypt msg: " + sMsg);

            // 解析 XML
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document document = db.parse(new InputSource(new StringReader(sMsg)));

            // 获取 XML 的所有数据
            Map<String, String> xmlData = new HashMap<>();
            Element root = document.getDocumentElement();
            NodeList childNodes = root.getChildNodes();

            for (int i = 0; i < childNodes.getLength(); i++) {
                Node node = childNodes.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    xmlData.put(node.getNodeName(), node.getTextContent().trim());
                }
            }
            // 打印 XML 解析结果
            System.out.println("XML 解析结果：");
            for (Map.Entry<String, String> entry : xmlData.entrySet()) {
                System.out.println(entry.getKey() + " : " + entry.getValue());
            }*/
            // 判断是否是会话存档消息
           /* if (!"encrypt_chat_msg".equals(xmlData.get("MsgType"))) {
                String sdkFileId = xmlData.get("SdkFileId");
                System.out.println("收到存档消息，SdkFileId：" + sdkFileId);*/


           // }

           // System.out.println("XML 解析结果：" + xmlData);
           // return AjaxResult.success();


            // 拉取会话存档内容
            List<String> chatContents = getChatData(corpId);
            return AjaxResult.success(chatContents);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
    }

    /**
     * 拉取存档内容
     * @param
     * @return 聊天内容列表
     */
    public List<String> getChatData(String corpId) {
        QwCompany qwCompany= qwCompanyMapper.selectQwCompanyByCorpId(corpId);
        // 初始化 SDK
        long sdk = Finance.NewSdk();
        long slice = Finance.NewSlice();
        List<String> chatContents = new ArrayList<>();

        try {
            long seq = 0L;
            if (redisCache.redisTemplate.hasKey("seq:"+corpId+":")) {
                seq  = redisCache.getCacheObject("seq:"+corpId+":");
//                System.out.println("這是seq的值:" + seq);
            }
            // SDK 初始化参数
            String secret = qwCompany.getMsgSecret();
            //String secret = customConfig.getSecret();
            long limit = 1000L;  // 一次最多拉取 1000 条
            String proxy = "";
            String passwd = "";
            long timeout = 15L;

            long ret = Finance.Init(sdk, corpId, secret);
            if (ret != 0) {
                Finance.DestroySdk(sdk);
                System.out.println("初始化 SDK 失败，错误码1：" + ret);
                return chatContents;
            }

            // 拉取会话存档数据
            ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);
//            System.out.println("seq的值" + seq);
            if (ret != 0) {
                System.out.println("拉取会话存档失败，错误码：" + ret);
                return chatContents;
            }

            // 获取 JSON 内容
            String jsonContent = Finance.GetContentFromSlice(slice);
            if (jsonContent == null || jsonContent.isEmpty()) {
                System.out.println("没有获取到有效的会话存档数据");
                return chatContents;
            }

            // 解析 JSON 内容
            JSONObject json = new JSONObject(jsonContent);
            if (json.has("chatdata")) {
                for (Object item : json.getJSONArray("chatdata")) {
                    JSONObject chatItem = (JSONObject) item;
                    String encrypt_random_key = chatItem.getString("encrypt_random_key"); // 获取加密的随机密钥
                    String encrypt_chat_msg = chatItem.getString("encrypt_chat_msg"); // 获取加密消息

                    // 更新下一次拉取的 seq
                    if (chatItem.has("seq")) {
                        long nextSeq = chatItem.getLong("seq");
                        System.out.println("将 seq 存入 Redis，key: seq:, value: " + nextSeq);
                        redisCache.setCacheObject("seq:"+corpId+":", nextSeq); // 确保 `seq` 更新到缓存
                    }

                    // 使用私钥解密 encrypt_random_key 获取 encrypt_key
                    String encrypt_key = decryptRandomKey(encrypt_random_key,qwCompany.getMsgPrivateKey());
                    if (encrypt_key != null) {
                        // 解密加密消息
                        String decryptedMsg = decryptChatMessage(sdk, encrypt_key, encrypt_chat_msg);
                        // 解析 JSON 字符串
                        JsonObject jsonObject = JsonParser.parseString(decryptedMsg).getAsJsonObject();
                        /*String plaintext = Finance.GetContentFromSlice(slice);
                        // 获取 msgtype 的值
                        String msgtype = jsonObject.get("msgtype").getAsString();

                        // 处理媒体消息
                        if (msgtype.equals("voice")) {
                            getMedia(sdk,decryptedMsg);
                        }*/

                        System.out.println("解密后的消息：" + decryptedMsg);
                        chatContents.add(decryptedMsg);
                    } else {
                        System.out.println("解密随机密钥失败");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            Finance.FreeSlice(slice);
            Finance.DestroySdk(sdk);
        }
        return chatContents;
    }
    /**
     * 下载语音文件
     * @param sdk SDK实例
     * @param decryptedMsg 解密后的JSON字符串
     * @return 保存的文件路径，失败返回null
     */
    public static String getMedia(long sdk, String decryptedMsg) {
        JsonObject jsonObject = JsonParser.parseString(decryptedMsg).getAsJsonObject();

        if (!jsonObject.has("voice")) {
            log.error("JSON 数据中缺少 voice 字段");
            return null;
        }

        JsonObject voiceObj = jsonObject.getAsJsonObject("voice");
        String sdkFileId = voiceObj.get("sdkfileid").getAsString();
        String saveFilePath = "E:\\home\\" + RandomUtil.randomNumbers(5) + ".amr";

        File targetFile = new File(saveFilePath);
        if (!targetFile.getParentFile().exists() && !targetFile.getParentFile().mkdirs()) {
            log.error("无法创建目录: {}", targetFile.getParentFile());
            return null;
        }

        long mediaData = Finance.NewMediaData();
        boolean success = downloadVoice(sdk, sdkFileId, "", mediaData, saveFilePath);
        Finance.FreeMediaData(mediaData);
        return success ? saveFilePath : null;
    }

    /**
     * 递归下载语音文件
     * @param sdk SDK实例
     * @param sdkFileId 语音文件ID
     * @param indexbuf 获取分片数据时的索引
     * @param mediaData 存储语音数据的结构体
     * @param saveFilePath 保存路径
     * @return 下载是否成功
     */
    private static boolean downloadVoice(long sdk, String sdkFileId, String indexbuf, long mediaData, String saveFilePath) {

        long ret = Finance.Init(sdk, "ww51717e2b71d5e2d3", "6ODAmw-8W4t6h9mdzHh2Z4Apwj8mnsyRnjEDZOHdA7k");
        if (ret != 0) {
            Finance.DestroySdk(sdk);
            System.out.println("初始化 SDK 失败，错误码：" + ret);
            return false;
        }
        ret = Finance.GetMediaData(sdk, indexbuf, sdkFileId, "", "", 15L, mediaData);
        if (ret != 0) {
            log.error("获取语音数据失败: ret={}, sdkFileId={}", ret, sdkFileId);
            return false;
        }

        int dataLen = Finance.GetDataLen(mediaData);
        boolean isFinish = Finance.IsMediaDataFinish(mediaData) == 1;
        String nextIndexBuf = Finance.GetOutIndexBuf(mediaData);

        try (FileOutputStream outputStream = new FileOutputStream(saveFilePath, true)) {
            outputStream.write(Finance.GetData(mediaData));
        } catch (IOException e) {
            log.error("写入语音文件失败: {}", e.getMessage(), e);
            return false;
        }

        if (!isFinish) {
            return downloadVoice(sdk, sdkFileId, nextIndexBuf, mediaData, saveFilePath);
        }

        log.info("语音文件下载完成, 文件路径={}",  saveFilePath);
        return true;
    }

    public static void main(String[] args) {
        String decryptedMsg = "{\"msgid\":\"17911368467188607973_1742371674303_external\",\"action\":\"send\",\"from\":\"f\",\"tolist\":[\"wmotXidAAAbB5UE3Sr9B2frB3XIWSTyg\"],\"roomid\":\"\",\"msgtime\":1742371670126,\"msgtype\":\"voice\",\"voice\":{\"md5sum\":\"e6b6fc008f5473c73172015e0e30a019\",\"voice_size\":9218,\"play_length\":13,\"sdkfileid\":\"CtsDKjEqdTNXMmsvMis3VGlnRjNpZU0ySllXWTEyZkowbSt3ODB6Tzg0Y0lPTkg2YnZzbmtPWkhyejRCWjNlUUorc0x5L1VPOXBicEViR1dpRWtoTlB5dngrNHZ3TUIrUW1Rbkh4aEc5RlROK2xoc0xSTUszbHczZ1Jxd0dhZXdDbERSOVBQR3JEUW82NnVQS1JVS0N5WGFIMmNmSGV0MW5VN0thQkRnSWhjS3MwKy9jQitVbGNWV0J0ajN1MlZwcGhjWkl1bG9BbmpIV3pBTUxoQllqbUd2cldRNUVBL2FxVVJFMVM5VkdLMytZYURvQ0NBajV4Z0VCMFlTcHNReW11U0RVU1ZaOEZNWGdHajNYQkNMbVpGZGxZcHlxalMvWWZSZmZFdUx4L3AzVWRMLzJpaXdybm5rdjZiK2R2cVBrQ21OOUdndXpZK2cxanJMeW9RTkRqZ1grMmdxZExJcUNXOEp3WFIyczVvajI3WURVSW1ub0g0MDF1MTRZM1lXU0RCZkNwQkFSVms2MTNzOFFxRFIzOUI5SC85QU5aWHEweCt3d05aSmpoVUE4SW82NUY0UEZxRlhIRlRYRGJGdUp3SjdFalRxakpNaHJkc0t3WEwvSmZuMkQyU2c9PRI4TkRkZk1UWTRPRGcxTkRrMk16Y3hNVGt6TTE4ek1UTXlOVFF4TmpSZk1UYzBNak0zTVRZM05BPT0aIDczNjQ3NjZhNmI2NzZmNzk2ZDcyNjY3NTY3Nzg2NjY1\"}}";
        // 解析 JSON 字符串
        JsonObject jsonObject = JsonParser.parseString(decryptedMsg).getAsJsonObject();
        long sdk = Finance.NewSdk();
        long slice = Finance.NewSlice();
        getMedia(sdk,decryptedMsg);
    }





    /**
     * 解密加密的随机密钥
     * @param encryptedRandomKey 加密的随机密钥
     * @return 解密后的随机密钥
     */
    public String decryptRandomKey(String encryptedRandomKey,String msgPrivateKey) {
        try {
            // 加载私钥
            PrivateKey privateKey = loadPrivateKey(msgPrivateKey);

            // 使用 RSA 解密
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);

            // 解密数据
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedRandomKey));
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密会话消息
     * @param sdk SDK
     * @param encrypt_key 解密的密钥
     * @param encrypt_chat_msg 加密的聊天消息
     * @return 解密后的消息内容
     */
    public String decryptChatMessage(long sdk, String encrypt_key, String encrypt_chat_msg) {
        String decryptedMsg = "";
        long msg = Finance.NewSlice();
        try {
            // 解密消息
            int ret = Finance.DecryptData(sdk, encrypt_key, encrypt_chat_msg, msg);
            if (ret == 0) {
                decryptedMsg = Finance.GetContentFromSlice(msg); // 获取解密后的消息内容
                decryptedMsg = new String(decryptedMsg.getBytes(), "UTF-8");
            } else {
                System.out.println("解密失败，错误码：" + ret);
                return null;  // 返回 null，避免上游加入错误数据
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            Finance.FreeSlice(msg);
        }
        return decryptedMsg;
    }
    /**
     * 获取私钥
     * @return 私钥
     * @throws Exception 异常
     */
    public PrivateKey loadPrivateKey(String privateKey) throws Exception {
            // 解析 PEM 格式的私钥
            String privateKeyPEM = privateKey
                    .replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s", "");
            byte[] decodedKey = Base64.getDecoder().decode(privateKeyPEM);

            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);

    }




    /**
     * 回调验签，返回echoStr的明文
     * @param msgSignature
     * @param timestamp
     * @param nonce
     * @param echoStr
     * @return
     * @throws AesException
     */
    public String check(String corpId,String msgSignature,String timestamp,String nonce, String echoStr) throws com.fs.app.util.AesException {
        QwCompany qwCompany= qwCompanyMapper.selectQwCompanyByCorpId(corpId);
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qwCompany.getToken(), qwCompany.getEncodingAesKey(), corpId);
        String s = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echoStr);
        return s;
    }

}
