package com.tzld.piaoquan.api.job.wecom.thirdpart;

import com.alibaba.fastjson.JSONObject;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.tzld.piaoquan.api.common.enums.wecom.ConfigTaskContentTypeEnum;
import com.tzld.piaoquan.api.common.enums.wecom.MsgSendStatusEnum;
import com.tzld.piaoquan.api.common.enums.wecom.ThirdPartWeComStaffStatusEnum;
import com.tzld.piaoquan.api.component.VideoApiService;
import com.tzld.piaoquan.api.dao.mapper.contentplatform.ext.ContentPlatformPlanMapperExt;
import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComMsgMapper;
import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ThirdPartWeComRoomMapper;
import com.tzld.piaoquan.api.dao.mapper.wecom.thirdpart.ext.ThirdPartWeComVideoMapperExt;
import com.tzld.piaoquan.api.model.param.wecom.thirdpart.*;
import com.tzld.piaoquan.api.model.po.contentplatform.ContentPlatformVideo;
import com.tzld.piaoquan.api.model.po.wecom.thirdpart.*;
import com.tzld.piaoquan.api.model.vo.contentplatform.WxVideoV2VO;
import com.tzld.piaoquan.api.service.VideoMultiService;
import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyAccountService;
import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyRoomService;
import com.tzld.piaoquan.api.service.wecom.thirdparty.WeComThirdPartyService;
import com.tzld.piaoquan.api.util.CdnUtil;
import com.tzld.piaoquan.growth.common.model.po.CgiReplyBucketData;
import com.tzld.piaoquan.growth.common.model.po.Staff;
import com.tzld.piaoquan.growth.common.service.MessageAttachmentService;
import com.tzld.piaoquan.growth.common.utils.DateUtil;
import com.tzld.piaoquan.growth.common.utils.LarkRobotUtil;
import com.tzld.piaoquan.growth.common.utils.MessageUtil;
import com.tzld.piaoquan.growth.common.utils.RedisUtils;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Component
public class WeComSendMsgJob {

    @Autowired
    WeComThirdPartyService weComThirdPartyService;
    @Autowired
    WeComThirdPartyAccountService weComThirdPartyAccountService;
    @Autowired
    WeComThirdPartyRoomService weComThirdPartyRoomService;
    @Autowired
    MessageAttachmentService messageAttachmentService;
    @Autowired
    VideoApiService videoApiService;
    @Autowired
    ContentPlatformPlanMapperExt planMapperExt;
    @Autowired
    ThirdPartWeComVideoMapperExt videoMapperExt;
    @Autowired
    ThirdPartWeComRoomMapper roomMapper;
    @Autowired
    ThirdPartWeComMsgMapper msgMapper;
    @Autowired
    private VideoMultiService videoMultiService;

    @Autowired
    RedisUtils redisUtils;

    @Value("${send.room.msg.video.min.score:1}")
    private Double videoMinScore;
    @Value("${send.room.msg.duplicate.days:30}")
    private Integer duplicateDays;

    private final static ExecutorService pool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(),
            new ThreadFactoryBuilder().setNameFormat("WeComSendMsgJob-%d").build(),
            new ThreadPoolExecutor.AbortPolicy());

    @XxlJob("autoSendAppMsg")
    public ReturnT<String> autoSendAppMsg(String param) {
        List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
        String time = DateUtil.getCurrentDateStr("HH:mm");
        List<Long> staffIdList = activeStaffList.stream().map(ThirdPartWeComStaff::getId).collect(Collectors.toList());
        List<ThirdPartWeComStaffConfig> staffConfigList = weComThirdPartyAccountService.getStaffConfigListByStaffIds(staffIdList);
        Map<Long, ThirdPartWeComStaffConfig> staffConfigMap = staffConfigList.stream().collect(Collectors.toMap(ThirdPartWeComStaffConfig::getStaffId, a -> a));
        for (ThirdPartWeComStaff staff : activeStaffList) {
            ThirdPartWeComStaffConfig staffConfig = staffConfigMap.get(staff.getId());
            if (Objects.isNull(staffConfig) || staffConfig.getSwitchFlag() != 1) {
                continue;
            }
            List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
            if (CollectionUtils.isEmpty(roomList)) {
                continue;
            }
            List<Long> roomIds = roomList.stream().map(ThirdPartWeComRoom::getId).collect(Collectors.toList());
            List<ThirdPartWeComRoomConfig> roomConfigList = weComThirdPartyRoomService.getRoomConfigListByRoomIds(roomIds);
            if (CollectionUtils.isEmpty(roomConfigList)) {
                continue;
            }
            Map<Long, ThirdPartWeComRoomConfig> roomConfigMap = roomConfigList.stream().collect(Collectors.toMap(ThirdPartWeComRoomConfig::getRoomId, a -> a));
            List<String> configIds = roomConfigList.stream().map(ThirdPartWeComRoomConfig::getId).map(String::valueOf).collect(Collectors.toList());
            List<ThirdPartWeComRoomConfigTask> roomConfigTaskList = weComThirdPartyRoomService.getRoomConfigTasks(configIds);
            if (CollectionUtils.isEmpty(roomConfigTaskList)) {
                continue;
            }
            Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap = roomConfigTaskList.stream()
                    .filter(o -> o.getSwitchFlag() == 1).collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTask::getConfigId));
            sendStaffRoomMsg(staff, time, roomList, roomConfigMap, roomConfigTaskMap);
        }
        return ReturnT.SUCCESS;
    }

    private void sendStaffRoomMsg(ThirdPartWeComStaff staff,
                                  String time,
                                  List<ThirdPartWeComRoom> roomList,
                                  Map<Long, ThirdPartWeComRoomConfig> roomConfigMap,
                                  Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap) {
        for (ThirdPartWeComRoom room : roomList) {
            if (room.getSendStatus() != 1) {
                continue;
            }
            pool.execute(() -> {
                ThirdPartWeComRoomConfig roomConfig = roomConfigMap.get(room.getId());
                if (roomConfig == null) {
                    return;
                }
                List<ThirdPartWeComRoomConfigTask> taskList = roomConfigTaskMap.getOrDefault(roomConfig.getId(), new ArrayList<>());
                if (taskList.isEmpty()) {
                    return;
                }
                List<String> configTaskIds = taskList.stream().map(ThirdPartWeComRoomConfigTask::getId).collect(Collectors.toList());
                List<ThirdPartWeComRoomConfigTaskContent> taskContentList = weComThirdPartyRoomService.getRoomConfigTaskContents(configTaskIds);
                if (CollectionUtils.isEmpty(taskContentList)) {
                    return;
                }
                Map<String, List<ThirdPartWeComRoomConfigTaskContent>> taskContentMap = taskContentList.stream()
                        .collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTaskContent::getTaskId));
                ThirdPartWeComStaff pushStaff = getSendStaff(roomConfig);
                if (Objects.isNull(pushStaff)) {
                    LarkRobotUtil.sendWeComThirdPartMessage(
                            "【账号发送群消息，推送账号获取失败通知】\n" +
                                    "账号名称：" + staff.getName() + "\n" +
                                    "账号VID：" + staff.getThirdStaffId() + "\n" +
                                    "群名称：" + room.getName());
                    return;
                }
                sendRoomConfigTaskMsg(staff, pushStaff, time, room, roomConfig, taskList, taskContentMap);
            });
        }
    }

    private void sendRoomConfigTaskMsg(ThirdPartWeComStaff staff,
                                       ThirdPartWeComStaff pushStaff,
                                       String time,
                                       ThirdPartWeComRoom room,
                                       ThirdPartWeComRoomConfig roomConfig,
                                       List<ThirdPartWeComRoomConfigTask> taskList,
                                       Map<String, List<ThirdPartWeComRoomConfigTaskContent>> taskContentMap) {
        for (ThirdPartWeComRoomConfigTask configTask : taskList) {
            List<String> timeList = getRoomSendTime(room, roomConfig, configTask);
            if (timeList.contains(time)) {
                // 选取视频
                List<ThirdPartWeComRoomConfigTaskContent> contentList = taskContentMap.get(configTask.getId());
                if (Objects.isNull(contentList) || contentList.isEmpty()) {
                    continue;
                }
                contentList = contentList.stream().sorted(Comparator.comparing(ThirdPartWeComRoomConfigTaskContent::getSeq)).collect(Collectors.toList());
                for (ThirdPartWeComRoomConfigTaskContent configTaskContent : contentList) {
                    if (ConfigTaskContentTypeEnum.TEXT.getVal() == configTaskContent.getType()) {
                        // build发送体
                        SendTextMsgRequest request = buildSendTextMsgRequest(configTaskContent.getContent(), pushStaff, room);
                        // 发送消息
                        CommonResponse<SendTextMsgResponse> response = weComThirdPartyService.sendTextMsg(pushStaff, room, request);
                        // 存储消息
                        saveTextWeComMsg(pushStaff.getId(), configTaskContent.getContent(), request, response);
                    } else if (ConfigTaskContentTypeEnum.MINI_PROGRAM.getVal() == configTaskContent.getType()) {
                        List<CgiReplyBucketData> cgiReplyBucketDataList = getCgiReplyBucketData(room.getThirdRoomId(), staff, roomConfig, configTaskContent);
                        for (CgiReplyBucketData cgiReplyBucketData : cgiReplyBucketDataList) {
                            // build发送体
                            SendAppMsgRequest request = buildSendAppMsgRequest(cgiReplyBucketData, pushStaff, room);
                            try {
                                // 发送消息
                                CommonResponse<SendAppMsgResponse> response = weComThirdPartyService.sendAppMsg(pushStaff, room, request);
                                // 存储消息
                                saveAppWeComMsg(pushStaff.getId(), cgiReplyBucketData.getMiniVideoId(), request, response);
                            } catch (Exception e) {
                                log.error("发送群消息失败，账号名称：{}，账号VID：{}，群名称：{}，视频ID：{}，request：{}，异常信息：{}",
                                        staff.getName(), staff.getThirdStaffId(), room.getName(),
                                        cgiReplyBucketData.getMiniVideoId(), JSONObject.toJSONString(request), e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }
    }

    private ThirdPartWeComStaff getSendStaff(ThirdPartWeComRoomConfig roomConfig) {
        List<ThirdPartWeComStaff> pushStaffList = weComThirdPartyRoomService.getRoomConfigPushList(Collections.singletonList(roomConfig));
        Map<Long, ThirdPartWeComStaff> pushStaffMap = pushStaffList.stream()
                .collect(Collectors.toMap(ThirdPartWeComStaff::getThirdStaffId, Function.identity()));
        ThirdPartWeComStaff pushStaff = pushStaffMap.get(roomConfig.getPrimaryThirdStaffId());
        if (Objects.isNull(pushStaff) || pushStaff.getStatus() != ThirdPartWeComStaffStatusEnum.NORMAL.getVal()) {
            if (Objects.nonNull(roomConfig.getSecondThirdStaffId())) {
                pushStaff = pushStaffMap.get(roomConfig.getSecondThirdStaffId());
                if (Objects.isNull(pushStaff) || pushStaff.getStatus() != ThirdPartWeComStaffStatusEnum.NORMAL.getVal()) {
                    pushStaff = null;
                }
            } else {
                pushStaff = null;
            }
        }
        return pushStaff;
    }

    private List<String> getRoomSendTime(ThirdPartWeComRoom room,
                                         ThirdPartWeComRoomConfig roomConfig,
                                         ThirdPartWeComRoomConfigTask configTask) {
        String key = "wecom:room:send:time:" + room.getThirdRoomId() + ":" + roomConfig.getId() + ":" + configTask.getId();
        String timeStr = redisUtils.get(key);
        if (StringUtils.isBlank(timeStr)) {
            return JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
        }
        return JSONObject.parseArray(timeStr).toJavaList(String.class);
    }

    private SendTextMsgRequest buildSendTextMsgRequest(String content,
                                                       ThirdPartWeComStaff staff,
                                                       ThirdPartWeComRoom room) {
        String thirdRoomId = room.getThirdRoomId();
        SendTextMsgRequest request = new SendTextMsgRequest();
        request.setUuid(staff.getThirdUuid());
        request.setSend_userid(Long.valueOf(thirdRoomId));
        request.setIsRoom(true);
        request.setContent(content);
        return request;
    }

    private SendAppMsgRequest buildSendAppMsgRequest(CgiReplyBucketData cgiReplyBucketData,
                                                     ThirdPartWeComStaff staff,
                                                     ThirdPartWeComRoom room) {
        String thirdRoomId = room.getThirdRoomId();
        SendAppMsgRequest request = new SendAppMsgRequest();
        request.setUuid(staff.getThirdUuid());
        request.setSend_userid(Long.valueOf(thirdRoomId));
        request.setIsRoom(true);
        request.setAppid("wx89e7eb06478361d7");
        request.setUsername("gh_ecd1ea0b84cf@app");
        request.setAppName("票圈 l 3亿人喜欢的视频平台");
        request.setTitle(cgiReplyBucketData.getTitle());
        request.setWeappIconUrl("http://rescdn.yishihui.com/temp/1755515422185_%E7%A5%A8%E5%9C%88Vlog_logo.jpg");
        // 填充视频信息
        // 封面添加播放按钮水印
        String coverUrl = addPlayWatermark(cgiReplyBucketData.getCoverUrl());
        request.setDesc(cgiReplyBucketData.getTitle());
        request.setPagepath(cgiReplyBucketData.getMiniPagePath());
        CdnUploadImgLinkRequest cdnUploadImgLinkRequest = new CdnUploadImgLinkRequest();
        cdnUploadImgLinkRequest.setUuid(staff.getThirdUuid());
        cdnUploadImgLinkRequest.setUrl(coverUrl);
        CdnUploadImgLinkResponse uploadResponse = weComThirdPartyService.cdnUploadImgLink(cdnUploadImgLinkRequest);
        request.setCdnkey(uploadResponse.getCdn_key());
        request.setMd5(uploadResponse.getMd5());
        request.setAeskey(uploadResponse.getAes_key());
        request.setFileSize(uploadResponse.getSize().intValue());
        return request;
    }

    private String addPlayWatermark(String coverUrl) {
        if (!coverUrl.startsWith(CdnUtil.VIDEO_CDN_URL_HOST)) {
            return coverUrl;
        }
        String waterMark = "?x-oss-process=image/resize,m_fill,w_600,h_480,limit_0/format,jpg/watermark,image_eXNoL3BpYy93YXRlcm1hcmtlci9pY29uX3BsYXlfd2hpdGUucG5nP3gtb3NzLXByb2Nlc3M9aW1hZ2UvcmVzaXplLHdfMTQ0,g_center";
        if (coverUrl.contains("?")) {
            coverUrl = coverUrl.substring(0, coverUrl.indexOf("?"));
        }
        return coverUrl + waterMark;
    }

    private List<CgiReplyBucketData> getCgiReplyBucketData(String roomId,
                                                           ThirdPartWeComStaff thirdPartWeComStaff,
                                                           ThirdPartWeComRoomConfig roomConfig,
                                                           ThirdPartWeComRoomConfigTaskContent configTaskContent) {
        // 排除最近发送过的视频
        List<Long> sentVideoIds = getSentVideoIds(Long.valueOf(roomId));
        List<ContentPlatformVideo> videoList = getVideoByStrategy(roomId, videoMinScore, sentVideoIds,
                configTaskContent, 1, 100);
        if (CollectionUtils.isEmpty(videoList)) {
            LarkRobotUtil.sendWeComThirdPartMessage(
                    "【账号发送群消息，视频数量不足通知】\n" +
                            "账号名称：" + thirdPartWeComStaff.getName() + "\n" +
                            "账号VID：" + thirdPartWeComStaff.getThirdStaffId() + "\n" +
                            "群ID：" + roomId + "\n" +
                            "账号配置：" + JSONObject.toJSONString(configTaskContent));
            return Collections.emptyList();
        }
        List<CgiReplyBucketData> result = new ArrayList<>();
        ContentPlatformVideo video = videoList.get(0);
        Staff staff = new Staff();
        staff.setCarrierId(String.valueOf(thirdPartWeComStaff.getThirdStaffId()));
        staff.setRemark(thirdPartWeComStaff.getName());
        String putScene = StringUtils.isNotBlank(roomConfig.getPutScene()) ? roomConfig.getPutScene() : "touliu";
        String pageChannel = StringUtils.isNotBlank(roomConfig.getChannel()) ? roomConfig.getChannel() : "tencentqw";
        String page = messageAttachmentService.getPageNoCache("pages/category.html", putScene, pageChannel, staff, video.getVideoId(), "企微", "社群", "位置X", null);
        page = videoMultiService.setVideoMultiTitleCoverPagePath(video.getVideoId(), page, video.getTitle(), video.getCover());

        CgiReplyBucketData cgiReplyBucketData = new CgiReplyBucketData();
        cgiReplyBucketData.setMiniVideoId(video.getVideoId());
        cgiReplyBucketData.setTitle(video.getTitle());
        cgiReplyBucketData.setCoverUrl(video.getCover());
        cgiReplyBucketData.setMiniPagePath(page);
        result.add(cgiReplyBucketData);
        return result;
    }

    private List<ContentPlatformVideo> getVideoByStrategy(String roomId,
                                                          Double videoMinScore,
                                                          List<Long> sentVideoIds,
                                                          ThirdPartWeComRoomConfigTaskContent configTaskContent,
                                                          int pageNum,
                                                          int pageSize) {
        List<ContentPlatformVideo> result = new ArrayList<>();
        List<ContentPlatformVideo> videoList;
        // 0-热榜 1-标签 2-账号
        switch (configTaskContent.getSource()) {
            case 2:
                Long uid = Long.valueOf(configTaskContent.getSourceContent());
                List<WxVideoV2VO> list = videoApiService.getUserVideoList(uid, sentVideoIds, pageNum, pageSize);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                videoList = convertWxVideoV2VOToVideo(list);
                result.addAll(videoList);
                break;
            case 1:
                String tagName = configTaskContent.getSourceContent();
                list = videoApiService.getTagVideoList(tagName, roomId, sentVideoIds, pageNum, pageSize);
                if (CollectionUtils.isEmpty(list)) {
                    break;
                }
                videoList = convertWxVideoV2VOToVideo(list);
                result.addAll(videoList);
                break;
            default:
                // 按平台推荐top选取视频
                String dt = videoMapperExt.getVideoMaxDt();
                result.addAll(videoMapperExt.getVideoMinScoreList(dt, videoMinScore, roomId, 0, 100, "video.score desc"));
        }
        return result;
    }

    private List<ContentPlatformVideo> convertWxVideoV2VOToVideo(List<WxVideoV2VO> list) {
        List<ContentPlatformVideo> result = new ArrayList<>();
        for (WxVideoV2VO vo : list) {
            ContentPlatformVideo video = new ContentPlatformVideo();
            video.setVideoId(vo.getId());
            video.setTitle(vo.getTitle());
            video.setCover(vo.getVideoCoverSnapshotPath());
            result.add(video);
        }
        return result;
    }

    private List<Long> getSentVideoIds(Long roomId) {
        ThirdPartWeComMsgExample msgExample = new ThirdPartWeComMsgExample();
        msgExample.createCriteria().andSendUseridEqualTo(roomId)
                .andCreateTimeGreaterThan(DateUtil.getDaysAgoDate(duplicateDays))
                .andVideoIdIsNotNull();
        List<ThirdPartWeComMsg> msgList = msgMapper.selectByExample(msgExample);
        return msgList.stream().map(ThirdPartWeComMsg::getVideoId).collect(Collectors.toList());
    }

    private void saveAppWeComMsg(Long staffId, Long videoId, SendAppMsgRequest request, CommonResponse<SendAppMsgResponse> response) {
        ThirdPartWeComMsg msg = new ThirdPartWeComMsg();
        msg.setStaffId(staffId);
        msg.setVideoId(videoId);
        msg.setUuid(request.getUuid());
        msg.setSendUserid(request.getSend_userid());
        msg.setSendType(ConfigTaskContentTypeEnum.MINI_PROGRAM.getVal());
        msg.setIsroom(request.getIsRoom());
        msg.setAppid(request.getAppid());
        msg.setUsername(request.getUsername());
        msg.setAppname(request.getAppName());
        msg.setTitle(request.getTitle());
        msg.setWeappiconurl(request.getWeappIconUrl());
        msg.setPagepath(request.getPagepath());
        msg.setRootSourceId(MessageUtil.getRootSourceId(msg.getPagepath()));
        msg.setDesc(request.getDesc());
        msg.setCdnkey(request.getCdnkey());
        msg.setMd5(request.getMd5());
        msg.setAeskey(request.getAeskey());
        msg.setFilesize(request.getFileSize());
        if (response.getErrcode() == 0) {
            msg.setStatus(MsgSendStatusEnum.NORMAL.getVal());
        } else {
            msg.setStatus(MsgSendStatusEnum.FAIL.getVal());
        }
        msgMapper.insertSelective(msg);
    }

    private void saveTextWeComMsg(Long staffId, String content, SendTextMsgRequest request, CommonResponse<SendTextMsgResponse> response) {
        ThirdPartWeComMsg msg = new ThirdPartWeComMsg();
        msg.setStaffId(staffId);
        msg.setUuid(request.getUuid());
        msg.setSendUserid(request.getSend_userid());
        msg.setSendType(ConfigTaskContentTypeEnum.TEXT.getVal());
        msg.setContent(content);
        msg.setIsroom(request.getIsRoom());
        if (response.getErrcode() == 0) {
            msg.setStatus(MsgSendStatusEnum.NORMAL.getVal());
        } else {
            msg.setStatus(MsgSendStatusEnum.FAIL.getVal());
        }
        msgMapper.insertSelective(msg);
    }

    @XxlJob("autoOpenSendStatusJob")
    public ReturnT<String> autoOpenSendStatusJob(String param) {
        List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
        List<Long> staffIdList = activeStaffList.stream().map(ThirdPartWeComStaff::getId).collect(Collectors.toList());
        List<ThirdPartWeComStaffConfig> staffConfigList = weComThirdPartyAccountService.getStaffConfigListByStaffIds(staffIdList);
        Map<Long, ThirdPartWeComStaffConfig> staffConfigMap = staffConfigList.stream().collect(Collectors.toMap(ThirdPartWeComStaffConfig::getStaffId, a -> a));
        for (ThirdPartWeComStaff staff : activeStaffList) {
            ThirdPartWeComStaffConfig staffConfig = staffConfigMap.get(staff.getId());
            if (Objects.isNull(staffConfig) || staffConfig.getSwitchFlag() != 1 || Objects.isNull(staffConfig.getOpenRoomSendSwitchNum())) {
                continue;
            }
            List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
            for (ThirdPartWeComRoom room : roomList) {
                if (room.getSendStatus() == 1) {
                    continue;
                }
                if (room.getMemberCount() > staffConfig.getOpenRoomSendSwitchNum()) {
                    room.setSendStatus(1);
                    roomMapper.updateByPrimaryKeySelective(room);
                }
            }
        }
        return ReturnT.SUCCESS;
    }

    @XxlJob("randomRoomSendTimeJob")
    public ReturnT<String> randomRoomSendTimeJob(String param) {
        List<ThirdPartWeComStaff> activeStaffList = weComThirdPartyService.getActiveStaffList();
        String now = DateUtil.getCurrentDateStr("HH:mm");
        for (ThirdPartWeComStaff staff : activeStaffList) {
            List<ThirdPartWeComRoom> roomList = weComThirdPartyService.getStaffRoomList(staff.getId());
            List<ThirdPartWeComRoomConfig> roomConfigList = weComThirdPartyRoomService.getRoomConfigListByRoomIds(roomList.stream().map(ThirdPartWeComRoom::getId).collect(Collectors.toList()));
            Map<Long, ThirdPartWeComRoomConfig> roomConfigMap = roomConfigList.stream().collect(Collectors.toMap(ThirdPartWeComRoomConfig::getRoomId, Function.identity()));
            List<String> configIds = roomConfigList.stream().map(ThirdPartWeComRoomConfig::getId).map(String::valueOf).collect(Collectors.toList());
            List<ThirdPartWeComRoomConfigTask> roomConfigTaskList = weComThirdPartyRoomService.getRoomConfigTasks(configIds);
            Map<String, List<ThirdPartWeComRoomConfigTask>> roomConfigTaskMap = roomConfigTaskList.stream().collect(Collectors.groupingBy(ThirdPartWeComRoomConfigTask::getConfigId));
            for (ThirdPartWeComRoom room : roomList) {
                ThirdPartWeComRoomConfig roomConfig = roomConfigMap.get(room.getId());
                if (roomConfig == null) {
                    continue;
                }
                List<ThirdPartWeComRoomConfigTask> taskList = roomConfigTaskMap.getOrDefault(roomConfig.getId(), new ArrayList<>());
                if (taskList.isEmpty()) {
                    continue;
                }
                randomRoomSendTime(room, roomConfig, taskList, now);
            }
        }
        return ReturnT.SUCCESS;
    }

    public void randomRoomSendTime(ThirdPartWeComRoom room,
                                   ThirdPartWeComRoomConfig roomConfig,
                                   List<ThirdPartWeComRoomConfigTask> taskList,
                                   String now) {
        for (ThirdPartWeComRoomConfigTask configTask : taskList) {
            String key = "wecom:room:send:time:" + room.getThirdRoomId() + ":" + roomConfig.getId() + ":" + configTask.getId();
            if (redisUtils.containsKey(key)) {
                continue;
            }
            List<String> timeList = JSONObject.parseArray(room.getSendTime()).toJavaList(String.class);
            // 判断timeList中在now之后的时间，随机增加或减少20以内的分钟数
            List<String> newTimeList = new ArrayList<>();
            for (String time : timeList) {
                // time与now比较，判断是否在now之后
                int hour = Integer.parseInt(time.substring(0, 2));
                int minute = Integer.parseInt(time.substring(3, 5));
                int nowHour = Integer.parseInt(now.substring(0, 2));
                int nowMinute = Integer.parseInt(now.substring(3, 5));
                if (hour < nowHour || (hour == nowHour && minute <= nowMinute)) {
                    newTimeList.add(time);
                    continue;
                }
                // 增加或减少20以内的分钟数 -20~20
                int randomTimeRange = Objects.isNull(configTask.getRandomMin()) ? 0 : configTask.getRandomMin();
                int randomMinute = randomTimeRange == 0 ? 0 : new Random().nextInt(randomTimeRange * 2) - randomTimeRange;
                minute += randomMinute;
                if (minute < 0) {
                    hour--;
                    minute += 60;
                } else if (minute >= 60) {
                    hour++;
                    minute -= 60;
                }
                // 确保时间在now之后
                if (hour < nowHour || (hour == nowHour && minute <= nowMinute)) {
                    newTimeList.add(time);
                    continue;
                }
                newTimeList.add(String.format("%02d:%02d", hour, minute));
            }
            redisUtils.set(key, JSONObject.toJSONString(newTimeList), 18 * 60 * 60);
        }
    }
}
