//package com.ningdatech.pmapi.meeting.task;
//
//import cn.hutool.crypto.SecureUtil;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import com.ningdatech.basic.util.CollUtils;
//import com.ningdatech.basic.util.StrPool;
//import com.ningdatech.cache.model.cache.CacheHashKey;
//import com.ningdatech.cache.repository.CachePlusOps;
//import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService;
//import com.ningdatech.pmapi.meeting.entity.domain.Meeting;
//import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert;
//import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatus;
//import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper;
//import com.ningdatech.pmapi.meeting.service.IMeetingExpertService;
//import com.ningdatech.pmapi.meeting.service.IMeetingService;
//import com.ningdatech.pmapi.meta.helper.DictionaryCache;
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//
//import java.time.LocalDateTime;
//import java.time.temporal.ChronoUnit;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//
///**
// * <p>
// * NoticeExpertAt24HoursBeforeMeetingTask
// * </p>
// *
// * @author WendyYang
// * @since 09:16 2022/11/16
// */
//@Slf4j
//@Component
//@AllArgsConstructor
//public class NoticeExpertAt24HoursBeforeMeetingTask {
//
//    @Data
//    private static class NoticeValue {
//
//        private LocalDateTime startTime;
//
//        private String addressMd5;
//
//    }
//
//    private final IMeetingService meetingService;
//    private final IMeetingExpertService meetingExpertService;
//    private final YxtCallOrSmsHelper yxtCallOrSmsHelper;
//    private final DictionaryCache dictionaryCache;
//    private final CachePlusOps cachePlusOps;
//    private final IExpertUserFullInfoService expertUserFullInfoService;
//
//    private static final String EXPERT_NOTICE_AT_24H_BEFORE_MEETING = "EXPERT_NOTICE_AT_24H_BEFORE_MEETING";
//
//    private void addNoticeKey(Long meetingId, Map<String, Object> noticeValue, LocalDateTime startTime) {
//        long mills = ChronoUnit.SECONDS.between(LocalDateTime.now(), startTime);
//        CacheHashKey key = new CacheHashKey();
//        key.setKey(EXPERT_NOTICE_AT_24H_BEFORE_MEETING + StrPool.COLON + meetingId);
//        key.setField(mills);
//        cachePlusOps.hSet(key, noticeValue);
//    }
//
//    private Map<Long, NoticeValue> getNoticeKey(Long meetingId) {
//        Map<Object, Object> cache = cachePlusOps.hGet(EXPERT_NOTICE_AT_24H_BEFORE_MEETING + StrPool.COLON + meetingId);
//        return cache.entrySet().stream().collect(Collectors.toMap(w -> Long.valueOf(w.getKey().toString()), w -> (NoticeValue) w.getValue()));
//    }
//
//    /**
//     * 查询需要发送通知的会议：
//     * <ul>1. 未完成</ul>
//     * <ul>2. 创建邀请</ul>
//     * <ul>3. 当前时间距离会议开始时间不足24小时</ul>
//     *
//     * @return 会议信息
//     * @author WendyYang
//     **/
//    private Map<Long, Meeting> loadMeetingAt24HoursBeforeMeeting() {
//        LambdaQueryWrapper<Meeting> query = Wrappers.lambdaQuery(Meeting.class);
//        LocalDateTime now = LocalDateTime.now(), hoursAgoBy24 = now.plusHours(24);
//        // 10分钟之内不再发送通知
//        query.between(Meeting::getStartTime, now.plusMinutes(10), hoursAgoBy24);
//        query.eq(Meeting::getStatus, MeetingStatus.Manager.UNCOMPLETED.getCode());
//        query.eq(Meeting::getInvited, Boolean.TRUE);
//        List<Meeting> meetings = meetingService.list(query);
//        return CollUtils.listToMap(meetings, Meeting::getId);
//    }
//
//    private String addressDetailMd5(Meeting meeting) {
//        String content = meeting.getRegionCode() + StrPool.HASH + meeting.getRegionLevel() + StrPool.HASH + meeting.getRegionDetail();
//        return SecureUtil.md5(content);
//    }
//
//    private boolean skipExpert(NoticeValue noticeValue, String addressMd5, LocalDateTime startTime) {
//        boolean skip = noticeValue.getAddressMd5().equals(addressMd5);
//        if (skip) {
//            skip = noticeValue.getStartTime().equals(startTime);
//        }
//        return skip;
//    }
//
//    @Scheduled(cron = "${expert-attend-notice.cron:0 0/5 7-21 * * ?}")
//    public void execute() {
//        log.info("开始执行会议开始前24小时再次短信提醒任务");
//        Map<Long, Meeting> meetingsMap = loadMeetingAt24HoursBeforeMeeting();
//        if (meetingsMap.isEmpty()) {
//            return;
//        }
//        List<MeetingExpert> expertList = meetingExpertService.listExpertByAgreeAttend(meetingsMap.keySet());
//        if (expertList.isEmpty()) {
//            return;
//        }
//        List<SendSmsCmd.SendSmsContext> contexts = new ArrayList<>();
//        Map<Long, List<MeetingExpert>> expertGroup = CollUtils.group(expertList, MeetingExpert::getMeetingId);
//        expertGroup.forEach((meetingId, experts) -> {
//            Map<String, Object> noticeCache = new HashMap<>(16);
//            Meeting meeting = meetingsMap.get(meetingId);
//            String md5 = addressDetailMd5(meeting);
//            Map<Long, NoticeValue> noticeKey = getNoticeKey(meetingId);
//            String holdCompany = meeting.getHoldCompanyBracket();
//            String startTime = meeting.getStartTime().format(DateUtil.DTF_YMD_HM);
//            String meetingType = dictionaryCache.getByCode(meeting.getType()).getName();
//            for (MeetingExpert expert : experts) {
//                NoticeValue noticeValue = noticeKey.get(expert.getId());
//                if (noticeValue != null) {
//                    if (skipExpert(noticeValue, md5, meeting.getStartTime())) {
//                        continue;
//                    }
//                }
//                NoticeValue value = new NoticeValue();
//                value.setAddressMd5(md5);
//                value.setStartTime(meeting.getStartTime());
//                noticeCache.put(expert.getId().toString(), value);
//                SendSmsCmd.SendSmsContext context = new SendSmsCmd.SendSmsContext();
//
//                ExpertUserFullInfo expertUserFullInfo = expertUserFullInfoService.getByUserId(expert.getExpertId());
//                String content = String.format(YxtSmsTemplateConst.SEND_MEETING_NOTICE, expertUserFullInfo.getName(),
//                        expert.getUpdateOn().format(DateUtil.DTF_YMD_HM), meetingType, startTime,
//                        meeting.getRegionDetail(), meeting.getContact());
//                context.setContent(holdCompany + content);
//                context.setReceiveNumber(expert.getMobile());
//                contexts.add(context);
//            }
//            if (!noticeCache.isEmpty()) {
//                addNoticeKey(meetingId, noticeCache, meeting.getStartTime());
//            }
//        });
//        if (!contexts.isEmpty()) {
//            yxtCallOrSmsHelper.sendSms(contexts);
//        }
//    }
//
//}
