package com.yeejoin.amos.boot.module.jcs.biz.service.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.StringUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.EnumsUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.common.api.dto.FirefightersDto;
import com.yeejoin.amos.boot.module.common.api.dto.FormValue;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.service.IDutyPersonService;
import com.yeejoin.amos.boot.module.common.biz.service.impl.FirefightersServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledFormDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledObjsDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledRo;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedExtDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedSMSDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.CarStatusInfoDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.InstructionsZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerTransferCompanyDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerTransferCompanyZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.SchedulingReportingDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.TemplateDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.TemplateExtendDto;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertCalled;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertFormValue;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertSubmitted;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertSubmittedObject;
import com.yeejoin.amos.boot.module.jcs.api.entity.Template;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertBusinessTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertSchedulingTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertStageEnums;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertSubmitTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.FireCarStatusEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.SubmissionMethodEnum;
import com.yeejoin.amos.boot.module.jcs.api.mapper.AlertSubmittedMapper;
import com.yeejoin.amos.boot.module.jcs.api.mapper.PowerTransferCompanyMapper;
import com.yeejoin.amos.boot.module.jcs.api.service.IAlertSubmittedObjectService;
import com.yeejoin.amos.boot.module.jcs.api.service.IAlertSubmittedService;
import com.yeejoin.amos.boot.module.jcs.biz.rule.action.AlertCalledAction;
import com.yeejoin.amos.component.rule.config.RuleConfig;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 警情报送记录 服务实现类
 *
 * @author tb
 * @date 2021-06-17
 */
@Service
public class AlertSubmittedServiceImpl extends BaseService<AlertSubmittedDto, AlertSubmitted, AlertSubmittedMapper> implements IAlertSubmittedService {

    @Autowired
    IAlertSubmittedObjectService iAlertSubmittedObjectService;
    @Autowired
    AlertSubmittedObjectServiceImpl alertSubmittedObjectServiceImpl;
    @Autowired
    AlertCalledServiceImpl alertCalledService;
    @Autowired
    DataDictionaryServiceImpl dataDictionaryService;
    @Autowired
    TemplateServiceImpl templateService;
    @Autowired
    PowerTransferServiceImpl powerTransferService;
    @Autowired
    RuleAlertCalledService ruleAlertCalledService;
    @Autowired
    AlertCalledAction alertCalledAction;
    @Autowired
    OrgUsrServiceImpl orgUsrService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private FirefightersServiceImpl firefightersService;
    @Autowired
    OrgUsrServiceImpl iOrgUsrService;
    @Autowired
    IDutyPersonService iDutyPersonService;


    @Autowired
    private EmqKeeper emqKeeper;
    @Value("${mqtt.topic.alert.reporting}")
    private String topic;

    @Value("${mqtt.topic.command.power.deployment}")
    private String powertopic;

    @Autowired
    EquipFeignClient equipFeignClient;
    @Autowired
    PowerTransferCompanyResourcesServiceImpl powerTransferCompanyResourcesService;
    @Autowired
    AlertSubmittedMapper alertSubmittedMapper;

    @Autowired
    PowerTransferCompanyMapper powerTransferCompanyMapper;

    @Override
    public SchedulingReportingDto listSchedulingByParam(AlertSubmittedDto queryParam) {
        SchedulingReportingDto schedulingReportingDto = new SchedulingReportingDto();
        List<AlertSubmittedExtDto> alertSubmittedExtDtoList = this.baseMapper.listSchedulingByParam(queryParam);
        schedulingReportingDto.setSchedulingReportingList(alertSubmittedExtDtoList);
        Map<String, List<AlertSubmittedExtDto>> groupMap =
                alertSubmittedExtDtoList.stream().collect(Collectors.groupingBy(AlertSubmittedExtDto::getSubmissionMethodCode));
        int phoneSize = 0;
        int smsSize = 0;
        if (ObjectUtils.isNotEmpty(groupMap.get(SubmissionMethodEnum.PHONE.getCode()))) {
            phoneSize = groupMap.get(SubmissionMethodEnum.PHONE.getCode()).size();
        }
        if (ObjectUtils.isNotEmpty(groupMap.get(SubmissionMethodEnum.SMS.getCode()))) {
            smsSize = groupMap.get(SubmissionMethodEnum.SMS.getCode()).size();
        }
        String extraInfo = String.format("已调度电话%s起，短信%d批", phoneSize, smsSize);
        schedulingReportingDto.setExtraInfo(extraInfo);
        return schedulingReportingDto;
    }

    @Override
    public SchedulingReportingDto listReportingByParam(AlertSubmittedDto queryParam) {
        SchedulingReportingDto schedulingReportingDto = new SchedulingReportingDto();
        List<AlertSubmittedExtDto> alertSubmittedExtDtoList = this.baseMapper.listReportingByParam(queryParam);
        if (ObjectUtils.isNotEmpty(alertSubmittedExtDtoList)) {
            // 组装额外信息
            String _extraInfo = "报送给%s、%s";
            alertSubmittedExtDtoList.forEach(alertSubmittedExtDto -> {
                try {
                    alertSubmittedExtDto.setExtraInfo(String.format(_extraInfo, alertSubmittedExtDto.getCompanyName(),
                            alertSubmittedExtDto.getUserName()));
                    TemplateExtendDto template = templateService.getByType(alertSubmittedExtDto.getBusinessTypeCode());
                    String richContent = template.getRichContent();
                    alertSubmittedExtDto.setSubmissionContentValue(JSONObject.parseObject(alertSubmittedExtDto.getSubmissionContent()));
                    alertSubmittedExtDto.setSubmissionContent(richContent);
                } catch (JSONException e) {
                    alertSubmittedExtDto.setSubmissionContentValue(alertSubmittedExtDto.getSubmitContent());
                }
            });
            schedulingReportingDto.setSchedulingReportingList(alertSubmittedExtDtoList);

            String extraInfo = String.format("已报送%d条", alertSubmittedExtDtoList.size());
            schedulingReportingDto.setExtraInfo(extraInfo);
        }
        return schedulingReportingDto;
    }

    @Override
    public Boolean save(AlertSubmittedDto alertSubmittedDto, String userName) throws Exception {
        try {
            Map<String,String> map = saveAlertSubmitted(alertSubmittedDto, userName);
            // 组装规则入参
            AlertCalled alertCalled = alertCalledService.getById(alertSubmittedDto.getAlertCalledId());
            AlertCalledObjsDto alertCalledVo  = (AlertCalledObjsDto) alertCalledService.selectAlertCalledByIdNoRedisNew(alertCalled.getSequenceNbr());
            alertCalledVo.setAlertCalled(alertCalled);

            // 调用规则
            ruleAlertCalledService.fireAlertCalledRule(alertCalledVo, map.get("alertWay"),map.get("mobiles"));
            //通知实战指挥页面发送mqtt 默认发送 String 类型 0, 新警情 1 警情状态变化
            emqKeeper.getMqttClient().publish(powertopic, "0".getBytes(), RuleConfig.DEFAULT_QOS, true);
        } catch (MqttException e) {
            throw new RuntimeException();
        }
        return true;
    }

    /**
     * 规则回调
     */
    public void ruleCallbackAction(String smsCode, List<Map<String,Object>> sendIds, Object object) throws Exception {
        // 获取报送对象列表
        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();

        Set<String> mobiles = new HashSet<>();
        HashMap<String, String> smsParams = new HashMap<>();
        String alertCalledId = null;

        List<Map<String, Object>> orgUsers = new LinkedList<>();
        String sCode = "";
        String alertWay = "";
        if (object instanceof AlertCalledRo) {
            AlertCalledRo calledRo = (AlertCalledRo) object;
            String alertSubmittedId = calledRo.getAlertSubmittedId();
            alertCalledId = calledRo.getSequenceNbr();

            String alertTypeCode = calledRo.getAlertTypeCode();
            alertWay = calledRo.getAlertWay();
            String unitInvolved = calledRo.getUnitInvolved();

            // 警情续报 警情结案，非警情确认选择人员电话号码
            String ids = calledRo.getIds();
            if(!ValidationUtil.isEmpty(ids)) {
              List<String> ls = Arrays.asList(ids.split(","));
                ls.stream().forEach(e->mobiles.add(e));
            }
                    // 获取报送规则
            sendIds.stream().forEach(e->{

                    // 一般火灾 // 航空器救援
                    if(alertTypeCode.equals(AlertStageEnums.YBHZ.getCode()) || alertTypeCode.equals(AlertStageEnums.HKJY.getCode())) {
                        if(e.containsKey("onDuty")) {
                            // 当日值班人员：获值班表中包括消救部、综合办公室、消防支队、应急指挥科的值班人员。
                            List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyId();
                            orgUsers.addAll(mapList);
                        }
                        if(e.containsKey("fireBrigade")) {
                           //  根据人员岗位：班组长、队长、通讯员； 消防队伍--消防人员 中，对应岗位的人员
                            List<FirefightersDto> fireBrigade = firefightersService.queryById(e.get("fireBrigade").toString().split(","));
                            fireBrigade.stream().forEach(f->{
                                HashMap<String,Object> map = new HashMap<>();
                                map.put("telephone",f.getMobilePhone());
                                map.put("sequenceNbr",f.getSequenceNbr());
                                map.put("bizOrgName",f.getName());
                                orgUsers.add(map);
                            });

                        }
                        if(e.containsKey("airportUnit")) {
                            //  根据人员职务：干部&领导  机场单位 模块 消防急救保障部中，“人员职务”不为空的人员
                            List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId("消防救援部");
                            orgUsers.addAll(mapList);
                        }

                        // 安运部
                        if(e.get("type").toString().equals("AY")) {
                                if(e.containsKey("airportPost")) {
                                    List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId("安运部");
                                    orgUsers.addAll(mapList);
                                }
                        }

                        // 事发单位
                        if(e.get("type").toString().equals("SF")) {
                            if(e.containsKey("airportPost")) {
                                List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId(unitInvolved);
                                orgUsers.addAll(mapList);
                            }
                        }
                    }

                    // 突发事件救援   // 漏油现场安全保障   // 专机保障  // 其他
                    if(alertTypeCode.equals(AlertStageEnums.HKJY.getCode())  || alertTypeCode.equals(AlertStageEnums.LYXC.getCode())
                            || alertTypeCode.equals(AlertStageEnums.ZJBZ.getCode()) || alertTypeCode.equals(AlertStageEnums.QTJQ.getCode())) {
                        if(e.containsKey("onDuty")) {
                            List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyNew("消防支队");
                            orgUsers.addAll(mapList);
                        }
                    }

                    // 120急救
                    if(alertTypeCode.equals(AlertStageEnums.JJJQ.getCode())) {
                        if (e.containsKey("onDuty")) {
                            List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyNew("急救科");
                            orgUsers.addAll(mapList);
                        }
                        if (e.containsKey("airportUnit")) {
                            List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId("急救科");
                            orgUsers.addAll(mapList);
                        }
                    }
            });

            // 警情初报 续报 结案
                // 1.保存警情记录主表
                AlertSubmitted alertSubmitted = new AlertSubmitted();
                alertSubmitted.setAlertCalledId(Long.valueOf(calledRo.getSequenceNbr()));
                // 保存初报细分类型（一般火灾、航空器救援等）
                alertSubmitted.setBusinessTypeCode(calledRo.getAlertTypeCode());
                // 警情初报 --- 续报 结案
                if(alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
                    alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情初报.getName());
                } else if(alertWay.equals(AlertBusinessTypeEnum.警情续报.getCode())) {
                    alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情续报.getName());
                    sCode = "SMS_JCS_XB";
                } else if(alertWay.equals(AlertBusinessTypeEnum.警情结案.getCode())) {
                    alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情结案.getName());
                    sCode = "SMS_JCS_JA";
                } else {
                    alertSubmitted.setBusinessType(AlertBusinessTypeEnum.非警情确认.getName());
                    sCode = "SMS_JCS_QR";
                }

                Optional<SubmissionMethodEnum> submissionMethodEnum = Optional.of(SubmissionMethodEnum.SMS);
                alertSubmitted.setSubmissionMethodCode(submissionMethodEnum.get().getCode());
                alertSubmitted.setSubmissionMethod(submissionMethodEnum.get().getName());
                Optional<AlertSchedulingTypeEnum> alertSchedulingTypeEnum = Optional.of(AlertSchedulingTypeEnum.融合调度);
                alertSubmitted.setSchedulingTypeCode(alertSchedulingTypeEnum.get().getCode());
                alertSubmitted.setSchedulingType(alertSchedulingTypeEnum.get().getName());
                alertSubmitted.setSubmissionContent(JSONObject.toJSONString(objectToMap(calledRo)));
//                String token = RequestContext.getToken();
//                ReginParams reginParams = JSONObject.parseObject(.get(RedisredisUtilsKey.buildReginKey(RequestContext.getExeUserId(),token)).toString(),
//                        ReginParams.class);
//                alertSubmitted.setRecUserName(reginParams.getUserModel().getUserName());
//                alertSubmitted.setSender(reginParams.getUserModel().getUserName());
                alertSubmitted.setUpdateTime(new Date());
                alertSubmitted.setSubmissionTime(new Date());

                this.baseMapper.insert(alertSubmitted);
                alertSubmittedId = alertSubmitted.getSequenceNbr().toString();
                Optional<AlertBusinessTypeEnum> alertBusinessTypeEnum =
                        EnumsUtils.getEnumObject(AlertBusinessTypeEnum.class,
                                e -> e.getCode().equals(calledRo.getAlertTypeCode()));
                smsCode = alertBusinessTypeEnum.get().getSms_code();
            // 组装人员信息

            for (Map<String, Object> orgUser : orgUsers) {
                AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                alertSubmittedObject.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                alertSubmittedObject.setType(false);
//                alertSubmittedObject.setCompanyId(Long.valueOf((String) orgUser.get("parentId")));
//                alertSubmittedObject.setCompanyName((String) orgUser.get("parenName"));
                alertSubmittedObject.setUserId(Long.valueOf(String.valueOf(orgUser.get("sequenceNbr"))));
                alertSubmittedObject.setUserName((String) orgUser.get("bizOrgName"));

                if (!ValidationUtil.isEmpty(orgUser.get("telephone"))) {
                    mobiles.add((String) orgUser.get("telephone"));
                    alertSubmittedObject.setUserPhone((String) orgUser.get("telephone"));
                }
                alertSubmittedObjectList.add(alertSubmittedObject);
            }
            // 组装报送内容
            smsParams.put("callTimeStr", calledRo.getCallTimeStr());
            smsParams.put("address", calledRo.getAddress());
            smsParams.put("fireLocation", calledRo.getFireLocation());
            smsParams.put("burningMaterial", calledRo.getBurningMaterial());
            smsParams.put("fireSituation", calledRo.getFireSituation());
            smsParams.put("trappedNum", calledRo.getTrappedNum());
            smsParams.put("casualtiesNum", calledRo.getCasualtiesNum());
            smsParams.put("dangerousExplosives", calledRo.getDangerousExplosives());
            smsParams.put("companyName", calledRo.getCompanyName());
            smsParams.put("contactUser", calledRo.getContactUser());
            smsParams.put("contactPhone", calledRo.getContactPhone());
            smsParams.put("replaceContent", calledRo.getReplaceContent());
            smsParams.put("alertType", calledRo.getAlertType());
            smsParams.put("feedback", calledRo.getFeedback());
        }
        // 短信报送对象
        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
        // 发送任务消息
        // 组织短信内容
        // 调用短信发送接口

        if(alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
            alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
        } else {
            alertCalledAction.sendAlertCalleCmd(sCode, mobiles, smsParams);
        }
        emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS, false);
    }

    /**
     * 短信报送
     *
     * @param alertSubmittedDto 警情信息
     * @param userName          用户名
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String,String> saveAlertSubmitted(AlertSubmittedDto alertSubmittedDto, String userName) {
        Long alertSubmittedId = alertSubmittedDto.getSequenceNbr();
        String alertWay = "";
        Map<String,String> map = new HashMap<>();
        Set<String> mobiles = new HashSet<>();
        if (alertSubmittedId == null) {

            // 1.保存警情记录主表
            AlertSubmitted alertSubmitted = new AlertSubmitted();
            String bussTypeCode;
            alertSubmitted.setAlertCalledId(alertSubmittedDto.getAlertCalledId());
            // 任务 4174  日常值班---融合调度----短信模版中的内容用户可以全部删除掉，按照自定义内容重新录入发送内容 by litw 2021年10月27日
            if("316".equals(alertSubmittedDto.getBusinessTypeCode())) {
                alertSubmitted.setBusinessTypeCode(AlertBusinessTypeEnum.警情续报.getCode());
                bussTypeCode = AlertBusinessTypeEnum.警情续报.getCode();
            } else {
                alertSubmitted.setBusinessTypeCode(alertSubmittedDto.getBusinessTypeCode());
                bussTypeCode = alertSubmittedDto.getBusinessTypeCode();
            }

            Optional<AlertBusinessTypeEnum> businessTypeEnum = EnumsUtils.getEnumObject(AlertBusinessTypeEnum.class,
                    e -> e.getCode().equals(bussTypeCode));
            alertSubmitted.setBusinessType(businessTypeEnum.get().getName());
            alertSubmitted.setCallLogId(alertSubmittedDto.getCallLogId());
            alertSubmitted.setSubmissionMethodCode(alertSubmittedDto.getSubmissionMethodCode());
            Optional<SubmissionMethodEnum> submissionMethodEnum = EnumsUtils.getEnumObject(SubmissionMethodEnum.class,
                    e -> e.getCode().equals(alertSubmittedDto.getSubmissionMethodCode()));
            alertSubmitted.setSubmissionMethod(submissionMethodEnum.get().getName());
            Optional<AlertSchedulingTypeEnum> alertSchedulingTypeEnum =
                    EnumsUtils.getEnumObject(AlertSchedulingTypeEnum.class,
                            e -> e.getCode().equals(alertSubmittedDto.getSchedulingTypeCode()));
            alertSubmitted.setSchedulingTypeCode(alertSubmittedDto.getSchedulingTypeCode());
            alertSubmitted.setSchedulingType(alertSchedulingTypeEnum.get().getName());

            // 任务 4174  日常值班---融合调度----短信模版中的内容用户可以全部删除掉，按照自定义内容重新录入发送内容 by litw 2021年10月27日
            if("316".equals(alertSubmittedDto.getBusinessTypeCode())) {
                JSONObject jsonObject = JSON.parseObject(alertSubmittedDto.getSubmitContent().toJSONString());
                alertSubmitted.setSubmissionContent(jsonObject.get("custom").toString());
            } else {
                alertSubmitted.setBusinessTypeCode(alertSubmittedDto.getBusinessTypeCode());
                alertSubmitted.setSubmissionContent(alertSubmittedDto.getSubmitContent().toJSONString());
            }

            alertSubmitted.setSender(userName);
            alertSubmitted.setRecUserName(userName);
            alertSubmitted.setUpdateTime(new Date());
            alertSubmitted.setSubmissionTime(new Date());

            this.baseMapper.insert(alertSubmitted);

            alertSubmittedId = alertSubmitted.getSequenceNbr();
        }

        // 2.保存任务表
        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();
        Long finalAlertSubmittedId = alertSubmittedId;
        // 报送给单位
        if (AlertSubmitTypeEnum.Org.getKey().equals(alertSubmittedDto.getType())) {
            alertSubmittedDto.getSubmitCompanyList().forEach(company -> {
                AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                alertSubmittedObject.setAlertSubmittedId(finalAlertSubmittedId);
                alertSubmittedObject.setType(true);
                alertSubmittedObject.setCompanyId(company.getCompanyId());
                alertSubmittedObject.setCompanyName(company.getCompanyName());
                alertSubmittedObject.setRecUserName(userName);

                alertSubmittedObjectList.add(alertSubmittedObject);
            });
        } else {
            // 报送给个人
            alertSubmittedDto.getSubmitCompanyList().forEach(company -> {
                company.getPersonList().forEach(person -> {
                    AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                    alertSubmittedObject.setAlertSubmittedId(finalAlertSubmittedId);
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setCompanyId(company.getCompanyId());
                    alertSubmittedObject.setCompanyName(company.getCompanyName());
                    alertSubmittedObject.setUserId(person.getPersonId());
                    alertSubmittedObject.setUserName(person.getPersonName());
                    alertSubmittedObject.setUserPhone(person.getPersonPhone());
                    alertSubmittedObject.setRecUserName(userName);
                    if (!ValidationUtil.isEmpty(person.getPersonPhone())) {
                        mobiles.add(person.getPersonPhone());
                    }
                    alertSubmittedObjectList.add(alertSubmittedObject);
                });
            });
        }
        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);

        // 3.更新警情状态
        alertCalledService.updateAlertCalled(alertSubmittedDto.getAlertCalledId(),
                alertSubmittedDto.getBusinessTypeCode());

        // 警情续报
        if(AlertBusinessTypeEnum.警情续报.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay = AlertBusinessTypeEnum.警情续报.getCode();
        }

        if(AlertBusinessTypeEnum.警情结案.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay =AlertBusinessTypeEnum.警情结案.getCode();
        }

        if(AlertBusinessTypeEnum.非警情确认.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay = AlertBusinessTypeEnum.非警情确认.getCode();
        }


        if (AlertBusinessTypeEnum.警情结案.getCode().equals(alertSubmittedDto.getBusinessTypeCode())
                || AlertBusinessTypeEnum.非警情确认.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            // 查询本次警情调派的车辆
            List<String> transferCarIdList =
                    powerTransferService.queryTransferCarIdsByAlertCalledId(alertSubmittedDto.getAlertCalledId());
            List<Object> carStatusInfoDtoList = Lists.newArrayList();
            if (!ValidationUtil.isEmpty(transferCarIdList)) {
                transferCarIdList.forEach(carId -> {
                    CarStatusInfoDto carStatusInfo = new CarStatusInfoDto();
                    carStatusInfo.setSequenceNbr(carId);
                    carStatusInfo.setStatus(FireCarStatusEnum.执勤.getCode());
                    carStatusInfoDtoList.add(carStatusInfo);
                });
            }

            //修改调派车辆任务

            powerTransferCompanyResourcesService.updateByAlertCalledId(alertSubmittedDto.getAlertCalledId());
            // 更新所有车辆状态为执勤
            equipFeignClient.updateCarStatus(carStatusInfoDtoList);
//            //跟车辆状态
//            powerTransferCompanyResourcesService.update(new UpdateWrapper<PowerTransferCompanyResources>().eq("resources_id", transferCarIdList).set("status", FireCarStatusEnum.返队.getCode()));
        }

        // 4.发送任务消息
        // 4.1组织短信内容
//        HashMap<String, String> smsParams = new HashMap<>();
//        JSONObject submitContent = alertSubmittedDto.getSubmitContent();
//        if(!"316".equals(alertSubmittedDto.getBusinessTypeCode())) {
//            smsParams.put("alertType", submitContent.get("alertType").toString());
//            smsParams.put("trappedNum", submitContent.get("trappedNum").toString());
//            smsParams.put("companyName", submitContent.get("companyName").toString());
//        }

        // 4.2调用短信发送接口
        //  alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);

        map.put("alertWay",alertWay);
        map.put("mobiles", StringUtils.join(mobiles,","));
        return map;
    }

    /**
     * 短信报送对象
     *
     * @param alertSubmittedObjectList 报送对象列表
     * @param smsCode                  短信模板code
     * @param mobiles                  电话号码列表
     * @param smsParams                报送内容
     */
    public void saveAlertSubmittedObject(List<AlertSubmittedObject> alertSubmittedObjectList, String smsCode,
                                         Set<String> mobiles, HashMap<String, String> smsParams) {


//        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
        // 发送任务消息
        // 组织短信内容
        // 调用短信发送接口
        alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
    }

    public void getAlertSubmittedContent(Long alertCalledId, ArrayList<TemplateDto> templateDtos, String companyName) throws IllegalAccessException {
        AlertCalled alertCalled = alertCalledService.getById(alertCalledId);
        Map<String, Object> map = objectToMap(alertCalled);
        map.put("companyName", companyName);

        // 获取模板内容
        List<DataDictionary> dataDictionaries =
                dataDictionaryService.list(new QueryWrapper<DataDictionary>().eq("type",
                        "JQBSLX"));
        for (DataDictionary dataDictionary : dataDictionaries) {
            Template template = templateService.getOne(new QueryWrapper<Template>().eq("type_code",
                    dataDictionary.getCode()).eq("format", true));
            List<PowerTransferCompanyDto> lastPowerTransferCompany;
            if ("警情续报".equals(template.getType()) && (lastPowerTransferCompany =
                    powerTransferService.getLastPowerTransferCompany(alertCalledId)).size() > 0) {
                map.put("businessType", template.getType());
                // 获取力量调派内容
                StringBuilder companyNames = new StringBuilder();
                StringBuilder resourcesInfo = new StringBuilder();
                for (PowerTransferCompanyDto powerTransferCompanyDto : lastPowerTransferCompany) {
                    companyNames.append(powerTransferCompanyDto.getCompanyName()).append("、");
                    resourcesInfo.append(powerTransferCompanyDto.getType()).append(powerTransferCompanyDto.getResourcesCount()).append("辆、");
                }
                map.put("companyNames", companyNames.deleteCharAt(companyNames.length() - 1).toString());
                map.put("resourcesInfo", resourcesInfo.deleteCharAt(resourcesInfo.length() - 1).toString());
                map.put("transferTime", lastPowerTransferCompany.get(0).getRecDate());
            }
            TemplateDto templateDto = new TemplateDto();
            BeanUtils.copyProperties(template, templateDto);
            templateDto.setData(map);
            templateDtos.add(templateDto);
        }
    }

    @Override
    public AlertSubmittedSMSDto getSchedulingContent(Long id) {
        return this.baseMapper.getSchedulingContent(id);
    }

    @Override
    public List<InstructionsZHDto> getInstructionsZHDtoList(Long id) {

        List<InstructionsZHDto> listInstructionsZHDto = new ArrayList<>();

        //获取调派记录
        List<PowerTransferCompanyZHDto> listPowerTransferCompanyZHDto = powerTransferCompanyMapper.listPowerTransferCompanyZHDto(id);

        listPowerTransferCompanyZHDto.stream().forEach(PowerTransferCompanyZHDto -> {
            String content = "";
            if (PowerTransferCompanyZHDto.getIsDistributionAgencies()) {
                content = "调派" + PowerTransferCompanyZHDto.getCompanyName() + "前往" + PowerTransferCompanyZHDto.getAddress();
            } else {
                content = "调派" + PowerTransferCompanyZHDto.getCompanyName() + PowerTransferCompanyZHDto.getSubmissionContent() + "前往" + PowerTransferCompanyZHDto.getAddress();
            }
            InstructionsZHDto instruct = new InstructionsZHDto(PowerTransferCompanyZHDto.getSequenceNbr(), PowerTransferCompanyZHDto.getDispatchType(), PowerTransferCompanyZHDto.getRecDate(), content, null);
            listInstructionsZHDto.add(instruct);
        });


        //获取融合调度信息
        List<AlertSubmittedZHDto> listAlertSubmittedZHDto = alertSubmittedMapper.listAlertSubmittedZHDto(id);

        listAlertSubmittedZHDto.stream().forEach(AlertSubmittedZHDto -> {
            JSONObject js = JSONObject.parseObject(AlertSubmittedZHDto.getSubmissionContent());
            String content = "";

            switch (AlertSubmittedZHDto.getBusinessType()) {
                case "警情初报":


                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + js.getString("address") + "发生" + js.getString("alertType");

                    break;
                case "警情续报":

                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "现场被困人数：" + js.getString("trappedNum") + "人伤亡人数：" + js.getString("casualtiesNum") + "人。";

                    break;
                case "非警情确认":

                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "此警情现场确认为假警情。";

                    break;
                case "警情结案":
                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "此警情已完场警情处置，警情已结案。";
                    break;

                default:

                    break;
            }
            InstructionsZHDto instruct = new InstructionsZHDto(AlertSubmittedZHDto.getSequenceNbr(), AlertSubmittedZHDto.getBusinessType(), AlertSubmittedZHDto.getSubmissionTime(), content,null);
            listInstructionsZHDto.add(instruct);

        });

        // 获取归并得警情信息
        LambdaQueryWrapper<AlertCalled> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AlertCalled::getFatherAlert,id);
        List<AlertCalled> alertCalleds = alertCalledService.getBaseMapper().selectList(queryWrapper);
        alertCalleds.stream().forEach(e->{
            AlertSubmittedZHDto alertSubmittedZHDto = new AlertSubmittedZHDto();
            AlertCalledFormDto alertCalledFormDto = (AlertCalledFormDto) alertCalledService.selectAlertCalledByIdNoRedis(e.getSequenceNbr());
            alertSubmittedZHDto.setAlertCalledFormDto(alertCalledFormDto);
            alertSubmittedZHDto.setSequenceNbr(e.getSequenceNbr());
            alertSubmittedZHDto.setBusinessType("警情归并");
            alertSubmittedZHDto.setSubmissionTime(alertCalledFormDto.getAlertCalled().getCallTime());
            alertSubmittedZHDto.setCompanyName(alertCalledFormDto.getAlertCalled().getCompanyName());
            alertSubmittedZHDto.setUserName(alertCalledFormDto.getAlertCalled().getRecUserName());
            InstructionsZHDto instruct = new InstructionsZHDto(alertSubmittedZHDto.getSequenceNbr(), alertSubmittedZHDto.getBusinessType(), alertSubmittedZHDto.getSubmissionTime(), null, alertSubmittedZHDto.getAlertCalledFormDto());
            listInstructionsZHDto.add(instruct);
        });

        //排序时间倒序
        /* Bug 2613 修改排序 按照发送时间排序 2021-09-01 陈召 开始*/
        Collections.sort(listInstructionsZHDto, new Comparator<InstructionsZHDto>() {
            @Override
            public int compare(InstructionsZHDto o1, InstructionsZHDto o2) {
                long i = o2.getSubmissionTime().getTime() - o1.getSubmissionTime().getTime();
                if (i == 0) {
                    return (int) (o2.getSubmissionTime().getTime() - o1.getSubmissionTime().getTime());
                }
                return (int) i;
            }
        });
        /* Bug 2613 修改排序 按照发送时间排序 2021-09-01 陈召 结束*/
        return listInstructionsZHDto;

    }

    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj 源对象
     * @return 转化结果
     * @throws IllegalAccessException IllegalAccessException
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<>();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            if ("dynamicFormAlert".equalsIgnoreCase(fieldName)) {
                List<FormValue> dynamicFormAlert = (List<FormValue>) field.get(obj);
                for (FormValue formValue : dynamicFormAlert) {
                    map.put(formValue.getLabel(), formValue.getValue());
                }
            } else {
                Object value = field.get(obj);
                map.put(fieldName, value);
            }
        }
        return map;
    }
}
