//package com.ningdatech.pmapi.meeting.task;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import com.ningdatech.basic.util.StrPool;
//import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo;
//import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService;
//import com.ningdatech.pmapi.meeting.entity.domain.ExpertInviteRule;
//import com.ningdatech.pmapi.meeting.entity.domain.Meeting;
//import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpert;
//import com.ningdatech.pmapi.meeting.entity.dto.RandomInviteRuleDTO;
//import com.ningdatech.pmapi.meeting.entity.enumeration.ExpertInviteType;
//import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper;
//import com.ningdatech.pmapi.meeting.service.IExpertInviteRuleService;
//import com.ningdatech.pmapi.meeting.service.IMeetingExpertService;
//import com.ningdatech.pmapi.meeting.service.IMeetingService;
//import com.ningdatech.pmapi.meta.helper.DictionaryCache;
//import com.ningdatech.pmapi.sms.utils.DateUtil;
//import lombok.AllArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.PostConstruct;
//import java.time.Duration;
//import java.time.Instant;
//import java.time.LocalDateTime;
//import java.time.temporal.ChronoUnit;
//import java.util.*;
//import java.util.stream.Collectors;
//
//import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatus.AGREED;
//import static com.ningdatech.pmapi.meeting.entity.enumeration.ExpertAttendStatus.NOTICING;
//
//
///**
// * <p>
// * ExpertCallResultRewriteTask
// * <br>
// * 专家电话结果回填
// * </p>
// *
// * @author WendyYang
// * @since 14:15 2022/8/18
// */
//@Slf4j
//@Component
//@AllArgsConstructor
//public class ExpertCallResultRewriteTask {
//
//    private final RandomInviteProperties randomInviteProperties;
//
//    private final ThreadPoolTaskScheduler scheduler;
//    private final IMeetingExpertService meetingExpertService;
//    private final IExpertInviteRuleService inviteRuleService;
//    private final IMeetingService meetingService;
//    private final ISysMsgRecordDetailService msgRecordDetailService;
//    private final DictionaryCache dictionaryCache;
//    private final YxtCallOrSmsHelper yxtCallOrSmsHelper;
//    private final IExpertUserFullInfoService iExpertUserFullInfoService;
//
//    @PostConstruct
//    public void initTask() {
//        if (!randomInviteProperties.getEnable()) {
//            log.warn("随机邀请已关闭……");
//            return;
//        }
//        Instant startTime = Instant.now().plus(randomInviteProperties.getResultRewriteFixedRate(), ChronoUnit.MINUTES);
//        // 处理电话结果回填
//        scheduler.scheduleAtFixedRate(this::rewritePhoneCallResult, startTime, Duration.ofMinutes(randomInviteProperties.getResultRewriteFixedRate()));
//    }
//
//
//    public void rewritePhoneCallResult() {
//        log.info("开始执行电话结果回填任务：{}", Thread.currentThread().getName());
//        // 查询所有邀请的专家信息 状态为通话中的
//        LambdaQueryWrapper<MeetingExpert> meQuery = Wrappers.lambdaQuery(MeetingExpert.class)
//                .eq(MeetingExpert::getStatus, NOTICING.getCode())
//                .eq(MeetingExpert::getInviteType, ExpertInviteType.RANDOM.getCode());
//        List<MeetingExpert> experts = meetingExpertService.list(meQuery);
//        if (experts.isEmpty()) {
//            log.info("暂无电话结果回填任务执行");
//            return;
//        }
//        // 所有随机邀请的规则ID
//        Map<Long, String> submitKeys = new HashMap<>(experts.size());
//        Set<Long> randomRuleIds = experts.stream().peek(w -> submitKeys.put(w.getId(), w.getSubmitKey()))
//                .map(MeetingExpert::getRuleId).collect(Collectors.toSet());
//        // 查询随机邀请回调等待时间
//        Map<Long, Integer> callbackMinutes = new HashMap<>(randomRuleIds.size());
//        if (!randomRuleIds.isEmpty()) {
//            List<ExpertInviteRule> inviteRules = inviteRuleService.listByIds(randomRuleIds);
//            inviteRules.forEach(w -> {
//                RandomInviteRuleDTO rule = JSON.parseObject(w.getInviteRule(), RandomInviteRuleDTO.class);
//                callbackMinutes.put(w.getId(), rule.getWaitForCallbackMinutes());
//            });
//        }
//        LambdaQueryWrapper<SysMsgRecordDetail> msgRecordDetailQuery = Wrappers.lambdaQuery(SysMsgRecordDetail.class)
//                .in(SysMsgRecordDetail::getSubmitKey, submitKeys.values());
//        List<SysMsgRecordDetail> recordDetailList = msgRecordDetailService.list(msgRecordDetailQuery);
//        if (recordDetailList.isEmpty()) {
//            return;
//        }
//        Map<String, SysMsgRecordDetail> recordDetailMap = recordDetailList.stream()
//                .collect(Collectors.toMap(w -> w.getSubmitKey() + StrPool.UNDERSCORE + w.getReceiveNumber(), w -> w));
//        List<MeetingExpert> updates = new ArrayList<>(), agrees = new ArrayList<>();
//        for (MeetingExpert expert : experts) {
//            String key = expert.getSubmitKey() + StrPool.UNDERSCORE + expert.getMobile();
//            SysMsgRecordDetail msgRecordDetail = recordDetailMap.get(key);
//            if (msgRecordDetail == null) {
//                // 极端情况下获取不到submitKey异常情况
//                continue;
//            }
//            Integer minutes = callbackMinutes.get(expert.getRuleId());
//            Optional<Integer> status = getStatusByMsgRecordDetail(msgRecordDetail, minutes, expert.getCreateOn());
//            if (status.isPresent()) {
//                MeetingExpert update = new MeetingExpert();
//                update.setUpdateBy(0L);
//                update.setUpdateOn(LocalDateTime.now());
//                update.setId(expert.getId());
//                update.setPreStatus(expert.getStatus());
//                update.setStatus(status.get());
//                if (AGREED.eq(update.getStatus())) {
//                    sendAgreeNotice(expert);
//                    agrees.add(expert);
//                }
//                updates.add(update);
//            }
//        }
//        meetingExpertService.updateBatchById(updates);
//        if (agrees.size() > 0) {
//            obtainCallBackAfterMeetingCanceled(agrees);
//        }
//    }
//
//    private void sendAgreeNotice(MeetingExpert expert) {
//        try {
//            Meeting meeting = meetingService.getById(expert.getMeetingId());
//            if (Objects.isNull(meeting)) {
//                return;
//            }
//            ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(expert.getExpertId());
//            String expertName = null;
//            if (Objects.nonNull(expertUserFullInfo)) {
//                expertName = expertUserFullInfo.getExpertName();
//            }
//            String smsContent = String.format(YxtSmsTemplateConst.EXPERT_AGREE_NOTICE, meeting.getHoldCompany(), expertName, meeting.getName()
//                    , meeting.getStartTime().format(DateUtil.DTF_YMD_HM), meeting.getRegionDetail(), meeting.getConnecter(), meeting.getContact(), WebProperties.webUrl);
//            SendSmsContext context = new SendSmsContext();
//            context.setContent(smsContent);
//            context.setReceiveNumber(expert.getMobile());
//
//            yxtCallOrSmsHelper.sendSms(context);
//        } catch (Exception e) {
//            log.info("发送专家会议接受通知短信失败：{}", JSONObject.toJSONString(expert));
//        }
//    }
//
//    private static Optional<Integer> getStatusByMsgRecordDetail(SysMsgRecordDetail msgRecordDetail, int minutes, LocalDateTime createOn) {
//        LocalDateTime time = LocalDateTime.now().minusMinutes(minutes);
//        String callBackJson = msgRecordDetail.getCallBackJson();
//        if (StrUtils.isBlank(callBackJson) && time.isBefore(createOn)) {
//            return Optional.empty();
//        }
//        ExpertAttendStatus status;
//        if (StrUtils.isNotBlank(callBackJson)) {
//            try {
//                JSONObject callbackObject = JSON.parseObject(callBackJson);
//                Date dialBeginTime = callbackObject.getDate("dialBeginTime");
//                if (dialBeginTime == null) {
//                    return Optional.empty();
//                }
//                Integer resultCode = callbackObject.getInteger("resultCode");
//                if (resultCode != null && resultCode == 0) {
//                    String pressKeyStr = callbackObject.getString("pressKey");
//                    if (Objects.nonNull(pressKeyStr)) {
//                        pressKeyStr = pressKeyStr.replaceAll("\\*", "").trim();
//                    }
//                    Integer pressKey = null;
//                    if (StringUtils.isNotBlank(pressKeyStr)) {
//                        pressKey = Integer.parseInt(pressKeyStr);
//                    }
//                    if (pressKey == null) {
//                        if (time.isBefore(createOn)) {
//                            return Optional.empty();
//                        }
//                        status = REFUSED;
//                    } else {
//                        if (pressKey == 1) {
//                            status = AGREED;
//                        } else {
//                            status = REFUSED;
//                        }
//                    }
//                } else {
//                    status = NOT_ANSWERED;
//                }
//            } catch (Exception e) {
//                log.error("获取电话回调结果异常", e);
//                status = NOT_ANSWERED;
//            }
//        } else {
//            // 超时未回复设置为拒绝参加
//            status = REFUSED;
//        }
//        return Optional.of(status.getCode());
//    }
//
//    /**
//     * 会议取消之后拿到回调结果的话需要发送取消短信
//     **/
//    private void obtainCallBackAfterMeetingCanceled(List<MeetingExpert> experts) {
//        /*List<Long> meetingIds = CollUtils.fieldList(experts, MeetingExpert::getMeetingId);
//        LambdaQueryWrapper<Meeting> mQuery = Wrappers.lambdaQuery(Meeting.class)
//                .eq(Meeting::getStatus, Manager.CANCELED.getCode())
//                .in(Meeting::getId, meetingIds);
//        Map<Long, Meeting> meetingMap = CollUtils.listToMap(meetingService.list(mQuery), Meeting::getId);
//        if (meetingMap.size() > 0) {
//            Map<Meeting, List<MeetingExpert>> expertList = new HashMap<>(16);
//            experts.forEach(w -> {
//                Meeting meeting = meetingMap.get(w.getMeetingId());
//                if (meeting == null) {
//                    return;
//                }
//                List<MeetingExpert> list = expertList.computeIfAbsent(meeting, k -> new ArrayList<>());
//                list.add(w);
//            });
//            if (!expertList.isEmpty()) {
//                expertList.forEach((m, mes) -> {
//                    String meetingType = dictionaryCache.getByCode(m.getType()).getName();
//                    List<SendSmsContext> contexts = YxtSmsContextBuilder.smsToExpertByCancelMeeting(m, mes, meetingType);
//                    yxtCallOrSmsHelper.sendSms(contexts);
//                });
//            }
//        }*/
//    }
//
//}
