package com.fs.qw.service.impl;

import com.fs.common.utils.PubFun;
import com.fs.qw.domain.QwUser;
import com.fs.qw.mapper.QwExternalContactMapper;
import com.fs.qw.result.QwFilterSopCustomersResult;
import com.fs.qw.vo.QwSopRuleTimeVO;
import com.fs.sop.domain.*;
import com.fs.sop.mapper.QwSopLogsMapper;
import com.fs.sop.mapper.QwSopMapper;
import com.fs.sop.mapper.QwSopTempMapper;
import com.fs.sop.mapper.SopUserLogsInfoMapper;
import com.fs.sop.params.DeleteQwSopParam;
import com.fs.sop.params.QwSopTagsParam;
import com.fs.sop.params.SopUserLogsArray;
import com.fs.sop.params.SopUserLogsList;
import com.fs.sop.service.IQwSopTempVoiceService;
import com.fs.sop.service.ISopUserLogsService;
import com.fs.voice.utils.StringUtil;
import com.fs.wxUser.domain.CompanyWxUser;
import com.fs.wxUser.mapper.CompanyWxUserMapper;
import com.fs.wxUser.param.CompanyWxUserSopParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class AsyncSopService {


    private final QwSopLogsMapper qwSopLogsMapper;
    private final QwSopMapper qwSopMapper;
    private final SopUserLogsInfoMapper sopUserLogsInfoMapper;
    private final CompanyWxUserMapper companyWxUserMapper;
    private final ISopUserLogsService sopUserLogsService;
    private final QwExternalContactMapper qwExternalContactMapper;
    private final QwSopTempMapper qwSopTempMapper;
    private final IQwSopTempVoiceService qwSopTempVoiceService;

    /**
     * 立即执行SOP任务
     */
    @Async("scheduledExecutorService")
    public void executeSopByIds(String[] ids) {

        List<QwSopRuleTimeVO> ruleTimeVOList = qwSopMapper.executeSopByIds(ids);
        List<QwSopTemp> tempList = qwSopTempMapper.selectListByIds(PubFun.listToNewList(ruleTimeVOList, QwSopRuleTimeVO::getTempId));
        Map<String, QwSopTemp> tempMap = PubFun.listToMapByGroupObject(tempList, QwSopTemp::getId);
        CompanyWxUserSopParam wxUserSopParam=new CompanyWxUserSopParam();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {
            ruleTimeVOList.forEach(ruleTimeVO->{
                QwSopTemp qwSopTemp = tempMap.get(ruleTimeVO.getTempId());
                //如果当前模板停用了，则不运行了
                if (qwSopTemp.getStatus().equals("0")){
                    QwSop qwSop=new QwSop();
                    qwSop.setId(ruleTimeVO.getId());
                    qwSop.setStatus(0L);

                    qwSopMapper.updateQwSop(qwSop);

                }
                else {

                    //筛选的参数
                    QwSopTagsParam qwSopTagsParam = new QwSopTagsParam();

                    //录入SOP日志
                    QwSopLogs qwSopLogs = new QwSopLogs();

                    qwSopLogs.setLogType(ruleTimeVO.getType());
                    qwSopLogs.setCompanyId(ruleTimeVO.getCompanyId());
                    qwSopLogs.setReceivingStatus(0L);
                    qwSopLogs.setSendType(ruleTimeVO.getSendType());
                    qwSopLogs.setSopId(ruleTimeVO.getId());
                    qwSopLogs.setCorpId(ruleTimeVO.getCorpId());
                    qwSopLogs.setSendStatus(3L);



                    //规则已经执行
                    QwSop qwSop=new QwSop();
                    qwSop.setId(ruleTimeVO.getId());
                    qwSop.setStatus(2L);
                    //标签
                    String tags = ruleTimeVO.getTags();


                    switch (ruleTimeVO.getType()){
                        //个微
                        case 1:
                            //客户筛选
                            wxUserSopParam.setCompanyId(ruleTimeVO.getCompanyId());
                            wxUserSopParam.setUserIdsSelectList(Arrays.asList( ruleTimeVO.getQwUserIds().split(",")));

                            //标过滤类型
                            wxUserSopParam.setFilterType(ruleTimeVO.getFilterType());

                            if (!StringUtil.strIsNullOrEmpty(tags)){

                                wxUserSopParam.setTagsIdsSelectList(Arrays.asList(tags.split(",")));
                            }


                            List<CompanyWxUser> companyWxUserList = companyWxUserMapper.selectCompanyWxUserByCompanyUserId(wxUserSopParam);

                            //如果查询结果为空，则直接返回
                            if (companyWxUserList == null || companyWxUserList.isEmpty()) {
                                return;
                            }
                            else {

                                Map<String, List<String>> userWeixinMap = companyWxUserList.stream()
                                        .collect(Collectors.groupingBy(
                                                res -> String.valueOf(res.getCompanyUserId()), // 按 CompanyUserId 分组
                                                Collectors.mapping(companyWxUser -> companyWxUser.getWeixinId().trim(),Collectors.toList()) // 收集 WeixinId 到列表中
                                        ));

                                // 遍历 userWeixinMap
                                userWeixinMap.forEach((companyUserId, weixinIdList) -> {

                                    SopUserLogs sopUserLogs1 = new SopUserLogs();

                                    SopUserLogsArray userLogsArray1=new SopUserLogsArray();

                                    SopUserLogsList userLogsList = new SopUserLogsList();

                                    userLogsList.setSopId(ruleTimeVO.getId());
                                    userLogsList.setSopTempId(ruleTimeVO.getTempId());
                                    userLogsList.setQwUserId(companyUserId);
                                    userLogsList.setCorpId(ruleTimeVO.getCorpId());
                                    userLogsList.setStartTime(sdf.format(ruleTimeVO.getStartTime()));
                                    userLogsList.setStatus(1);

                                    sopUserLogs1.setSopId(ruleTimeVO.getId());
                                    sopUserLogs1.setSopTempId(ruleTimeVO.getTempId());
                                    sopUserLogs1.setQwUserId(companyUserId);
                                    sopUserLogs1.setCorpId(ruleTimeVO.getCorpId());
                                    sopUserLogs1.setStartTime(sdf.format(ruleTimeVO.getStartTime()));
                                    sopUserLogs1.setStatus(1);

                                    //客户列表放新表(先不弄)
//                                    userLogsList.setExternalContactId(weixinIdList);

//                                    String unionSopId = sopUserLogsService.selectSopUserLogsByUnionSopId(sopUserLogs1);
//                                    if (!StringUtil.strIsNullOrEmpty(unionSopId)) {
//                                        userLogsArray1.setId(unionSopId);
////                                        userLogsArray1.setExternalContactId(weixinIdList.toArray(new String[0]));
//                                        sopUserLogsService.updateSopUserLogsDistinctByList(userLogsArray1);
//                                    }else {
//                                        sopUserLogsService.insertSopUserLogsByList(userLogsList);
//                                    }

                                });

                            }

                            qwSopMapper.updateQwSop(qwSop);
                            break;
                        //企微
                        case 2:

                            //成员筛选
                            if (!StringUtil.strIsNullOrEmpty(ruleTimeVO.getQwUserIds())){
                                qwSopTagsParam.setUserIdsSelectList(Arrays.asList( ruleTimeVO.getQwUserIds().split(",")));
                            }

                            //标过滤类型
                            qwSopTagsParam.setFilterType(ruleTimeVO.getFilterType());


                            //标签
                            if (!StringUtil.strIsNullOrEmpty(tags)){
                                qwSopTagsParam.setTagsIdsSelectList(Arrays.asList(tags.split(",")));
                            }

                            //排除标签
                            String excludeTags = ruleTimeVO.getExcludeTags();
                            if (!StringUtil.strIsNullOrEmpty(excludeTags)){
                                qwSopTagsParam.setOutTagsIdsSelectList(Arrays.asList(excludeTags.split(",")));
                            }
                            qwSopTagsParam.setCropId(ruleTimeVO.getCorpId());

                            // 查询符合条件的客户
//                            List<QwFilterSopCustomersResult> qwFilterSopCustomersResults = qwSopMapper.selectFilterQwSopCustomersTest(qwSopTagsParam);
                            List<QwFilterSopCustomersResult> qwFilterSopCustomersResults = qwSopMapper.selectFilterQwSopCustomers(qwSopTagsParam);


                            List<List<Long>> companyUserIds = PubFun.listToNewList(qwFilterSopCustomersResults.stream().filter(e -> e.getCuCompanyId() != null && e.getCompanyId() != null).collect(Collectors.toList()), e -> Arrays.asList(e.getCuCompanyUserId(), e.getCuCompanyId()));
                            try {
                                qwSopTempVoiceService.synchronous(ruleTimeVO.getId(), companyUserIds);
                            }catch (Exception e){
                                log.error("异步同步临时语音失败:",e);
                            }

                            //如果查询结果为空，则直接返回
                            if (qwFilterSopCustomersResults == null || qwFilterSopCustomersResults.isEmpty()) {
                                qwSop.setStatus(3L);
                                qwSopMapper.updateQwSop(qwSop);
                                return;
                            }
                            else {

//                                Map<String, Set<String>> groupedResults = qwFilterSopCustomersResults.stream()
//                                        .collect(Collectors.groupingBy(
//                                                res -> res.getUserId().trim()+"|"+res.getQwUserId()+"|"+res.getCuCompanyUserId()+"|"+res.getCuCompanyId(),
//                                                Collectors.mapping(res -> res.getExternalUserId().trim()+"|"+res.getId()+"|"+res.getFsUserId()+"|"+res.getName(),Collectors.toSet() // 收集为列表
//                                                )
//                                        ));

                                Map<String, Set<String>> groupedResults = qwFilterSopCustomersResults.stream()
                                        .collect(Collectors.groupingBy(
                                                res -> res.getUserId().trim() + "|" + res.getQwUserId() + "|" + res.getCuCompanyUserId() + "|" + res.getCuCompanyId(),
                                                Collectors.mapping(
                                                        res -> {
                                                            String name = Optional.ofNullable(res.getName()).orElse("无昵称");
                                                            return res.getExternalUserId().trim() + "|" + res.getId() + "|" + res.getFsUserId() + "|" + name;
                                                        },
                                                        Collectors.toSet() // 收集为 Set
                                                )
                                        ));


                                groupedResults.forEach((userIdAndQwUserId, externalUserIds) -> {

                                    // 将 key 按 "|" 分割，得到 userId 和 qwUserId
                                    String[] keys = userIdAndQwUserId.split("\\|"); // 使用 \\| 来转义 | 字符，因为 | 是正则表达式中的特殊字符

                                    String userId = keys[0].trim();
                                    String qwUserId = keys[1].trim();
                                    String companyUserId = keys[2].trim();
                                    String companyId = keys[3].trim();

                                    SopUserLogs sopUserLogs = new SopUserLogs();

                                    SopUserLogsList userLogsList = new SopUserLogsList();
                                    userLogsList.setSopId(ruleTimeVO.getId());
                                    userLogsList.setSopTempId(ruleTimeVO.getTempId());
                                    userLogsList.setQwUserId(userId);
                                    userLogsList.setUserId(qwUserId+"|"+companyUserId+"|"+companyId);
                                    userLogsList.setCorpId(ruleTimeVO.getCorpId());
                                    userLogsList.setStartTime(sdf.format(ruleTimeVO.getStartTime()));
                                    userLogsList.setStatus(1);

                                    sopUserLogs.setSopId(ruleTimeVO.getId());
                                    sopUserLogs.setSopTempId(ruleTimeVO.getTempId());
                                    sopUserLogs.setQwUserId(userId);
                                    sopUserLogs.setUserId(qwUserId+"|"+companyUserId+"|"+companyId);
                                    sopUserLogs.setCorpId(ruleTimeVO.getCorpId());
                                    sopUserLogs.setStartTime(sdf.format(ruleTimeVO.getStartTime()));
                                    sopUserLogs.setStatus(1);

                                    // 主逻辑
                                    String unionSopId = sopUserLogsService.selectSopUserLogsByUnionSopId(sopUserLogs);
                                    if (!StringUtil.strIsNullOrEmpty(unionSopId)) {
                                        // 如果 unionSopId 存在，直接插入
                                        processAndInsertExternalUserIds(externalUserIds, ruleTimeVO.getId(), unionSopId,userId,ruleTimeVO.getCorpId());
                                    } else {
                                        // 否则，先插入 userLogsList
                                        sopUserLogsService.insertSopUserLogsByList(userLogsList);

                                        // 获取新的 unionSopId
                                        String unionSopIdNew = sopUserLogsService.selectSopUserLogsByUnionSopId(sopUserLogs);

                                        // 插入数据
                                        processAndInsertExternalUserIds(externalUserIds, ruleTimeVO.getId(), unionSopIdNew,userId,ruleTimeVO.getCorpId());
                                    }

                                });


                            }

                            qwSopMapper.updateQwSop(qwSop);

                            System.out.println("执行成功");
                            break;
                        default:
                            break;
                    }

                }
            });
        }catch (Exception e){
            log.error("立即执行执行失败",e);
        }

    }

    // 定义一个方法来批量处理插入逻辑，支持每 500 条数据一次的批量插入
    private void processAndInsertExternalUserIds(Set<String> externalUserIds, String sopId, String unionSopId, String userId,String corpId) {
        // 定义批量插入的大小
        int batchSize = 500;

        // 将外部用户 ID 转为 List 进行处理
        List<String> externalUserIdsList = new ArrayList<>(externalUserIds);

        // 循环处理外部用户 ID，每次处理批量大小的子集
        for (int i = 0; i < externalUserIdsList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, externalUserIdsList.size());
            List<String> batchList = externalUserIdsList.subList(i, endIndex);  // 获取当前批次的子集

            // 处理当前批次的记录
            List<SopUserLogsInfo> sopUserLogsInfoList = new ArrayList<>();

            batchList.forEach(externalUserId -> {
                // 将 key 按 "|" 分割，得到 userId 和 qwUserId
                String[] externalKeys = externalUserId.split("\\|");

                // 解析 fsUserId
                String fsUserIdStr = (externalKeys[2] != null && !externalKeys[2].trim().equals("null")) ? externalKeys[2].trim() : "";
                Long fsUserId = (!fsUserIdStr.isEmpty()) ? Long.parseLong(fsUserIdStr) : 0L;

                // 解析 externalUserName
                String externalUserName = "无昵称";
                if (externalKeys.length > 3 && externalKeys[3] != null && !externalKeys[3].trim().equals("null") && !externalKeys[3].trim().isEmpty()) {
                    externalUserName = externalKeys[3].trim();
                }
                // 创建 SopUserLogsInfo 对象
                SopUserLogsInfo info = new SopUserLogsInfo();
                info.setSopId(sopId);
                info.setUserLogsId(unionSopId);
                info.setExternalContactId(externalKeys[0].trim());
                info.setQwUserId(userId);
                info.setCorpId(corpId);
                info.setExternalId(Long.valueOf(externalKeys[1].trim()));
                info.setFsUserId(fsUserId);
                info.setExternalUserName(externalUserName);

                // 加入当前批次的列表
                sopUserLogsInfoList.add(info);
            });

            if (!sopUserLogsInfoList.isEmpty()){
                // 批量插入当前批次的数据
                sopUserLogsInfoMapper.batchInsertSopUserLogsInfo(sopUserLogsInfoList);
            }

        }
    }


    /**
     * 异步处理销售删除客户
     */
    @Async("scheduledExecutorService")
    public void deleteSop(QwUser qwUser) {

        try {
            //查询这个销售所有的删除的客户
            List<String> deleteList = qwExternalContactMapper.selectQwExternalContactListAllByStatus(qwUser.getQwUserId(), qwUser.getCorpId());

            // 2. 设定每个批次大小
            final int batchSize = 500;

            // 3. 分批调用，避免一次塞太多
            for (int start = 0; start < deleteList.size(); start += batchSize) {
                // 计算此批次的结束位置
                int end = Math.min(start + batchSize, deleteList.size());

                // 获取当前批次需要删除的 externalUserId 子列表
                List<String> subList = deleteList.subList(start, end);

                //删除待发送记录
                DeleteQwSopParam apiParam = new DeleteQwSopParam();
                apiParam.setQwUserId(qwUser.getQwUserId());
                apiParam.setCorpId(qwUser.getCorpId());
                apiParam.setExternalUserIds(subList);

                // 批量删除 qw_external_contact 表中已经删除的客户的营期以及发送记录
                sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdList(apiParam);
                sopUserLogsInfoMapper.deleteByQwUserIdAndCorpIdToContactIdByChatList(apiParam);


                //批量删除发送记录
                qwSopLogsMapper.deleteQwSopLogsByExternalUserIdList(apiParam);
            }

        }catch (Exception e){
            log.error("异步处理销售删除客户:"+e);
        }



    }
}
