package com.xinelu.quartz.service.impl;

import com.aliyuncs.exceptions.ClientException;
import com.xinelu.common.config.AliYunSmsTwoConfig;
import com.xinelu.common.config.PushMessageRestrictions;
import com.xinelu.common.enums.ErrorStatusEnum;
import com.xinelu.common.enums.NodeExecuteResultStatusEnum;
import com.xinelu.common.enums.NodeExecuteStatusEnum;
import com.xinelu.common.enums.RouteNodeNameEnum;
import com.xinelu.common.enums.ShortMessageTypeEnum;
import com.xinelu.manage.domain.shortmessagesendrecord.ShortMessageSendRecord;
import com.xinelu.manage.dto.smssend.SmsInfoDTO;
import com.xinelu.manage.mapper.shortmessagesendrecord.ShortMessageSendRecordMapper;
import com.xinelu.manage.mapper.signpatientmanageroutenode.SignPatientManageRouteNodeMapper;
import com.xinelu.manage.service.patienttaskstatistics.IPatientTaskStatisticsService;
import com.xinelu.manage.vo.signpatientmanageroutenode.TextMessage;
import com.xinelu.manage.vo.subscribemessagesendrecord.RecordNum;
import com.xinelu.mobile.utils.SmsSendUtils;
import com.xinelu.quartz.service.SendTextMessageService;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * @Description 短信发送定时任务业务层
 * @Author zh
 * @Date 2024-07-22
 */
@Service
@Slf4j
public class SendTextMessageServiceImpl implements SendTextMessageService {

    @Resource
    private SignPatientManageRouteNodeMapper signPatientManageRouteNodeMapper;
    @Resource
    private SmsSendUtils smsSendUtils;
    @Resource
    private AliYunSmsTwoConfig aliYunSmsTwoConfig;
    @Resource
    private PushMessageRestrictions pushMessageRestrictions;
    @Resource
    private ShortMessageSendRecordMapper shortMessageSendRecordMapper;
	@Resource
	private IPatientTaskStatisticsService patientTaskStatisticsService;

    /**
     * 签约患者管理任务路径节点短信发送定时任务
     *
     * @throws ClientException 发送信息
     */
    @Override
    public void sendTextMessageSendTask() throws ClientException {
        //查询短信发送数据
        List<TextMessage> textMessages = signPatientManageRouteNodeMapper.selectMessagePushSign();
        if (CollectionUtils.isEmpty(textMessages)) {
            return;
        }
        //条件过滤后短信信息
        List<TextMessage> messages = new ArrayList<>();
        //超时短信ids
        List<Long> expiredManageRouteNodeIds = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for (TextMessage textMessage : textMessages) {
            //判断推送状态
            if (Objects.isNull(textMessage.getMessagePushSign()) || textMessage.getMessagePushSign() != 1) {
                continue;
            }
            //过滤脏数据
            if (StringUtils.isBlank(textMessage.getPatientType()) || Objects.isNull(textMessage.getRouteNodeDay())) {
                continue;
            }
            //模版暂时处理
            if (StringUtils.isBlank(textMessage.getTextMessageId()) || !aliYunSmsTwoConfig.getTemplateCode().equals(textMessage.getTextMessageId())) {
                continue;
            }
            LocalDate localDate = null;
            if (Objects.nonNull(textMessage.getDischargeTime())) {
                localDate = textMessage.getDischargeTime().plusDays(textMessage.getRouteNodeDay());
            }
            if (Objects.isNull(textMessage.getDischargeTime()) && Objects.nonNull(textMessage.getVisitDate())) {
                localDate = textMessage.getVisitDate().plusDays(textMessage.getRouteNodeDay());
            }
            if (Objects.isNull(localDate)) {
                continue;
            }
            boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
            if (before) {
                //超出7天，更改状态
                long until = localDate.until(LocalDate.now(), ChronoUnit.DAYS);
                if (until >= pushMessageRestrictions.getTime()) {
                    expiredManageRouteNodeIds.add(textMessage.getSignPatientManageRouteNodeId());
                    continue;
                }
                textMessage.setRouteNodeName(RouteNodeNameEnum.getNameByInfo(textMessage.getRouteNodeName()).getName());
                messages.add(textMessage);
            }
        }
        //更改过期执行状态
        if (CollectionUtils.isNotEmpty(expiredManageRouteNodeIds)) {
            signPatientManageRouteNodeMapper.updateNodeExecuteStatusByIds(expiredManageRouteNodeIds, NodeExecuteStatusEnum.EXECUTED.getInfo(), null, NodeExecuteResultStatusEnum.EXPIRED.getInfo(), null, now);
        }

        //判断路径节点，组装数据
//            if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_DISCHARGE.getInfo()) || textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
//                if (textMessage.getPatientType().equals(PatientTypeEnum.DISCHARGED_PATIENT.getInfo()) && Objects.nonNull(textMessage.getDischargeTime())) {
//                    LocalDate localDate = textMessage.getDischargeTime().plusDays(textMessage.getRouteNodeDay());
//                    boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
//                    if (before) {
//                        textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_DISCHARGE.getName());
//                        messages.add(textMessage);
//                    }
//                }
//            }
//            if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_ADMISSION.getInfo())) {
//                if (textMessage.getPatientType().equals(PatientTypeEnum.IN_HOSPITAL_PATIENT.getInfo()) && Objects.nonNull(textMessage.getAdmissionTime())) {
//                    LocalDate localDate = textMessage.getAdmissionTime().plusDays(textMessage.getRouteNodeDay());
//                    boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
//                    if (before) {
//                        textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_ADMISSION.getName());
//                        messages.add(textMessage);
//                    }
//                }
//            }
//            if (textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_CONSULTATION.getInfo()) || textMessage.getRouteNodeName().equals(RouteNodeNameEnum.AFTER_VISIT_DISCHARGE.getInfo())) {
//                if (textMessage.getPatientType().equals(PatientTypeEnum.OUTPATIENT.getInfo()) && textMessage.getAdmissionTime() == null && Objects.nonNull(textMessage.getVisitDate())) {
//                    LocalDate localDate = textMessage.getVisitDate().plusDays(textMessage.getRouteNodeDay());
//                    boolean before = localDate.isBefore(LocalDate.now()) || localDate.isEqual(LocalDate.now());
//                    if (before) {
//                        textMessage.setRouteNodeName(RouteNodeNameEnum.AFTER_CONSULTATION.getName());
//                        messages.add(textMessage);
//                    }
//                }
//            }
//        }
        //节点推送数量
        List<Long> collect = messages.stream().filter(Objects::nonNull).map(TextMessage::getSignPatientManageRouteNodeId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<RecordNum> recordNums = shortMessageSendRecordMapper.selectShortMessageRecordCountByManageRouteNodeIds(collect);
        //发送
        //发送失败ids
        List<Long> failSignPatientManageRouteNodeIds = new ArrayList<>();

	    Set<Long> patientIdSet = new HashSet<>();
        if (CollectionUtils.isNotEmpty(messages)) {
            List<Long> ids = new ArrayList<>();
            for (TextMessage message : messages) {
                SmsInfoDTO smsInfoDTO = new SmsInfoDTO();
                smsInfoDTO.setPhoneNumbers(message.getPatientPhone());
                smsInfoDTO.setSignName(aliYunSmsTwoConfig.getSignName());
                // 根据模版id发送
                smsInfoDTO.setTemplateCode(message.getTextMessageId());
                Boolean aBoolean = smsSendUtils.sendTextMessage(smsInfoDTO);
                ShortMessageSendRecord shortMessageSendRecord = new ShortMessageSendRecord();
                shortMessageSendRecord.setMessageType(ShortMessageTypeEnum.COMMON.getInfo());
                shortMessageSendRecord.setPatientId(message.getPatientId());
                shortMessageSendRecord.setPatientPhone(message.getPatientPhone());
                shortMessageSendRecord.setManageRouteNodeId(message.getSignPatientManageRouteNodeId());
                shortMessageSendRecord.setSendTime(LocalDateTime.now());
                shortMessageSendRecord.setMessageTemplateId(message.getTextMessageId());
                shortMessageSendRecord.setMessageNodeContent(message.getMessageNodeContent());
                shortMessageSendRecord.setCreateTime(LocalDateTime.now());
                //成功
                if (aBoolean) {
                    ids.add(message.getSignPatientManageRouteNodeId());
                    shortMessageSendRecord.setErrorCode(0L);
                    shortMessageSendRecord.setErrorStatus(ErrorStatusEnum.success.getValue());

                } else {
                    //失败
                    shortMessageSendRecord.setErrorCode(1L);
                    shortMessageSendRecord.setErrorStatus(ErrorStatusEnum.fail.getValue());
                    RecordNum recordNum = recordNums.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getManageRouteNodeId()) && item.getManageRouteNodeId().equals(message.getSignPatientManageRouteNodeId())).findFirst().orElse(new RecordNum());
                    //三次失败
                    if (Objects.nonNull(recordNum.getNum()) && recordNum.getNum() >= pushMessageRestrictions.getNumber()) {
                        failSignPatientManageRouteNodeIds.add(message.getSignPatientManageRouteNodeId());
                    }
                    shortMessageSendRecordMapper.insertShortMessageSendRecord(shortMessageSendRecord);
                }

	            // 修改患者任务统计表
	            patientIdSet.add(message.getPatientId());
            }
            //修改节点状态
            if (CollectionUtils.isNotEmpty(expiredManageRouteNodeIds)) {
                signPatientManageRouteNodeMapper.updateNodeExecuteStatusByIds(ids, NodeExecuteStatusEnum.EXECUTED.getInfo(), null, NodeExecuteResultStatusEnum.SUCCESS.getInfo(), null, now);
            }
            //修改节点状态
            if (CollectionUtils.isNotEmpty(expiredManageRouteNodeIds)) {
                signPatientManageRouteNodeMapper.updateNodeExecuteStatusByIds(failSignPatientManageRouteNodeIds, NodeExecuteStatusEnum.EXECUTED.getInfo(), null, NodeExecuteResultStatusEnum.FAILURE.getInfo(), null, now);
            }

	        // 患者任务统计表修改
	        if (CollectionUtils.isNotEmpty(patientIdSet)) {
		        patientTaskStatisticsService.updateNum(new ArrayList<>(patientIdSet));
	        }
        }
    }
}
