package com.ruoyi.web.controller.task;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.zhdd.domain.IncidentProcess;
import com.ruoyi.zhdd.domain.SmsOutbox;
import com.ruoyi.zhdd.domain.bo.MessagePushBo;
import com.ruoyi.zhdd.domain.bo.MessagePushUser;
import com.ruoyi.zhdd.domain.vo.IncidentTaskVo;
import com.ruoyi.zhdd.domain.vo.IncidentVo;
import com.ruoyi.zhdd.feign.FeignNoticeInfoService;
import com.ruoyi.zhdd.service.IIncidentProcessService;
import com.ruoyi.zhdd.service.IIncidentService;
import com.ruoyi.zhdd.service.IIncidentTaskService;
import com.ruoyi.zhdd.service.ISmsOutboxService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: TODO
 * @Author: huangcheng
 * @Date: 2022/1/12
 * @Version V1.0
 */
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class NoticeInfoListiner {

    private final FeignNoticeInfoService feignNoticeInfoService;
    private final IIncidentService incidentService;
    private final IIncidentTaskService incidentTaskService;
    private final IIncidentProcessService incidentProcessService;
    private final ISmsOutboxService smsOutboxService;
    private final ISysUserService sysUserService;

    @Value("${spring.profiles.active}")
    private String env;

    /**
     * 消息发送
     * A:事件接报。B:处置方案
     */
    @Bean
    public void sendNotice() {
        RedisUtils.subscribe(Constants.NOTICE_PUSH, String.class, msg -> {
            // 查询事件信息并发送消息
            MessagePushBo messagePushBo = new MessagePushBo();
            String type = msg.substring(0, 1);
            String title = "未知";
            String synopsis = "未知";
            String text = "未知";
            String messageUser = "";
            IncidentProcess incidentProcess = new IncidentProcess();
            boolean sendFlag = true;
            incidentProcess.setStatus(1);
            if ("A".equals(type)) {
                IncidentVo incidentVo = incidentService.queryById(msg.substring(1));
                title = StrUtil.concat(true, "应急事件:", incidentVo.getName());
                synopsis = "请查看应急事件";
                text = StrUtil.concat(true, incidentVo.getAddr(), "发生应急事件，请关注消息，做好应急准备");
                incidentProcess.setDes("事件上报");
                incidentProcess.setIncidentStatus(1);
                incidentProcess.setIncidentId(msg.substring(1));
                messageUser = incidentVo.getExprJson();
            } else if ("B".equals(type)) {
                // 查询处置方案
                IncidentTaskVo incidentTaskVo = incidentTaskService.queryById(msg.substring(1));
                IncidentVo incidentVo = incidentService.queryById(incidentTaskVo.getIncidentId());
                title = "应急处置";
                synopsis = "请查看应急处置方案";
                text = StrUtil.concat(true, "请查看", incidentVo.getName(), "事件的", incidentTaskVo.getTaskName(), "方案");
                incidentProcess.setDes("新增处置方案：" + incidentTaskVo.getTaskName() + "，并发送");
                incidentProcess.setIncidentStatus(3);
                incidentProcess.setIncidentId(incidentTaskVo.getIncidentId());
                messageUser = incidentTaskVo.getExprJson();
            }
            if (StrUtil.isBlank(messageUser)) {
                sendFlag = false;
                log.info("无发送人员");
                incidentProcess.setDes("新增处置方案");
                // 发送的标识，用于是否去查询已读未读人员的
                incidentProcess.setStatus(0);
            }
            List<MessagePushUser> messagePushUsers = JSONUtil.toList(messageUser, MessagePushUser.class);
            incidentProcessService.save(incidentProcess);
            if (sendFlag) {
                messagePushBo.setMsTitle(title);
                messagePushBo.setMsSynopsis(synopsis);
                messagePushBo.setMsText(text);
                messagePushBo.setMsNo(incidentProcess.getId());
                messagePushBo.setMessageReadInfoList(messagePushUsers);
                if (!"dev".equals(env)) {
                    feignNoticeInfoService.messagePush(messagePushBo);
                }
                // 查询发送用户的手机号
                List<String> collect = messagePushUsers.stream().map(MessagePushUser::getUserId).collect(Collectors.toList());
                List<SysUser> list = sysUserService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, collect));
                // 组装短信内容
                List<SmsOutbox> smsOutboxes = new ArrayList<>();
                for (SysUser sysUser : list) {
                    if (StrUtil.isNotBlank(sysUser.getPhonenumber()) && Validator.isMobile(sysUser.getPhonenumber())) {
                        SmsOutbox smsOutbox = new SmsOutbox();
                        smsOutbox.setDestaddr(sysUser.getPhonenumber());
                        smsOutbox.setMessagecontent("有新的应急事件或应急方案，请注意查看！");
                        smsOutbox.setRequesttime(new Date());
                        smsOutboxes.add(smsOutbox);
                    }
                }
                if (!"dev".equals(env)) {
                    smsOutboxService.saveBatch(smsOutboxes);
                }
                log.debug("发送短信：{}", smsOutboxes);
                log.info("发送消息体 => {}", messagePushBo);
                log.info("订阅事件消息 => {}", msg);
            }
        });
    }

    @Bean
    public void processRecord() {
        RedisUtils.subscribe(Constants.PROCESS_RECORD, JSONObject.class, msg -> {
            // 记录处置详情
            String incidentId = msg.getStr("incidentId");
            Integer incidentStatus = msg.getInt("incidentStatus");
            String des = msg.getStr("des");
            IncidentProcess incidentProcess = new IncidentProcess();
            if (incidentStatus == 2) {
                des = "转为事件";
            } else if (incidentStatus == 1) {
                des = "事件续报";
            } else if (incidentStatus == 4) {
                des = "事件归档";
            } else if (incidentStatus == 5) {
                des = "事件忽略";
            }
            incidentProcess.setDes(des);
            incidentProcess.setIncidentStatus(incidentStatus);
            incidentProcess.setIncidentId(incidentId);
            incidentProcess.setStatus(0);
            log.info("保存事件处置执行日志：{}", incidentProcess);
            incidentProcessService.save(incidentProcess);
        });
    }

}
