package com.scpyun.platform.jilinsscgsdp.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.json.JSONUtil;
import com.scpyun.base.bean.Page;
import com.scpyun.base.bean.User;
import com.scpyun.base.core.annotation.Api;
import com.scpyun.base.core.annotation.ApiOperation;
import com.scpyun.base.core.exception.CustomException;
import com.scpyun.base.core.utils.DataSourceSwitcher;
import com.scpyun.base.core.utils.JedisUtils;
import com.scpyun.base.core.utils.StringUtils;
import com.scpyun.base.core.utils.UUIDUtil;
import com.scpyun.base.db.service.CommonService;
import com.scpyun.base.utils.DateUtils;
import com.scpyun.platform.jilinsscgsdp.bean.dto.RiskComparisonDTO;
import com.scpyun.platform.jilinsscgsdp.bean.entity.EventCategory;
import com.scpyun.platform.jilinsscgsdp.bean.entity.EventRiskFactor;
import com.scpyun.platform.jilinsscgsdp.bean.entity.EventTrigger;
import com.scpyun.platform.jilinsscgsdp.bean.entity.SupplementEvent;
import com.scpyun.platform.jilinsscgsdp.bean.vo.*;
import com.scpyun.platform.jilinsscgsdp.constant.NotesConstant;
import com.scpyun.platform.jilinsscgsdp.constant.NumberConstant;
import com.scpyun.platform.jilinsscgsdp.enums.HierarchyTypeEnums;
import com.scpyun.platform.jilinsscgsdp.enums.WarningLevelEnum;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.concurrent.ThreadPoolExecutor;

import static com.scpyun.platform.jilinsscgsdp.bean.dto.RiskComparisonDTO.findHighestRisk;

/**
 * @Author liu
 * @Date 2025/8/20 15:13
 * @PackageName:com.scpyun.platform.jilinsscgsdp.service.impl
 * @ClassName: SafeSoundServiceImpl
 * @Description: TODO
 * @Version 1.0
 */
@Api("平")
@Service("safeSound")
public class SafeSoundServiceImpl {
    @Autowired
    CommonService commonService;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    private final String nameSpace = "com.scpyun.platform.standard.jilinsscgsdp.safeSoundDao.";
    private static final Logger log = LoggerFactory.getLogger(SafeSoundServiceImpl.class);

    private final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    @ApiOperation(value = "纠纷类别列表", desc = "纠纷类别列表", nologin = true)
    public List<ResDictVo> selectSafeSoundDictList(ReqDictVo vo) {
        return commonService.findList(nameSpace + "selectSafeSoundDictList", vo);
    }

    @ApiOperation(value = "类别统计", desc = "类别统计", nologin = true)
    public Map<String, Object> getNewSafeSoundEvent(Map<String, Object> map) {
        return commonService.getObject(nameSpace + "getNewSafeSoundEvent", map);
    }

    @ApiOperation(value = "近30天矛盾", desc = "近30天矛盾", nologin = true)
    public List<Map<String, Object>> selectDayEventList(Map<String, Object> map) throws ParseException {
        List<Map<String, Object>> returnList = new ArrayList<>();
        List<Map<String, Object>> countList = commonService.findList(nameSpace + "selectDayEventList", map);
        if (StringUtils.isNotEmpty(map.get("createTimeStart"))) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date startDate = format.parse(StringUtils.toStr(map.get("createTimeStart")));
            Date endDate = format.parse(StringUtils.toStr(map.get("createTimeEnd")));
            List<String> dateList = this.getDatesBetweenUsing(startDate, endDate);
            for (String str : dateList) {
                Map<String, Object> subMap = new HashMap<>();
                subMap.put("date", str);
                for (Map<String, Object> sub : countList) {
                    if (str.equals(StringUtils.toStr(sub.get("date")))) {
                        subMap.put("number", sub.get("number"));
                    }
                }
                if (StringUtils.isEmpty(subMap.get("number"))) {
                    subMap.put("number", 0);
                }
                returnList.add(subMap);
            }
        } else {
            List<String> dateList = this.getDatesBetweenUsingAnd();
            for (String str : dateList) {
                Map<String, Object> subMap = new HashMap<>();
                subMap.put("date", str);
                for (Map<String, Object> sub : countList) {
                    if (str.equals(StringUtils.toStr(sub.get("date")))) {
                        subMap.put("number", sub.get("number"));
                    }
                }
                if (StringUtils.isEmpty(subMap.get("number"))) {
                    subMap.put("number", 0);
                }
                returnList.add(subMap);
            }
        }
        return returnList;
    }

    @ApiOperation(value = "矛盾纠纷大类按数量统计top5", desc = "矛盾纠纷大类按数量统计top5", nologin = true)
    public List<Map<String, Object>> selectEventCategoryDictList(Map<String, Object> map) {
        return commonService.findList(nameSpace + "selectEventCategoryDictList", map);
    }

    @ApiOperation(value = "超期矛盾案件top5", desc = "超期矛盾案件top5", nologin = true)
    public List<Map<String, Object>> findSafeSoundEarlyWarningList(Map<String, Object> map) {
        return commonService.findList(nameSpace + "findSafeSoundEarlyWarningList", map);
    }

    @ApiOperation(value = "查询单条矛盾纠纷案件信息", desc = "查询单条矛盾纠纷案件信息", nologin = true)
    public ReqEventFlowLogInsertVo getSafeSoundEventById(ReqEventFlowLogInsertVo vo) {
        ReqEventFlowLogInsertVo eventMap = commonService.getObject(nameSpace + "getSafeSoundEventById", vo);
        if (eventMap == null) {
            eventMap = commonService.getObject(nameSpace + "getSafeSoundEventMById", vo);
            if (eventMap == null) {
                return eventMap;
            }
            eventMap.setUserList(commonService.findList(nameSpace + "selectSafeSoundMEventUserList", eventMap));
        } else {
            eventMap.setTypeNum("0");
            eventMap.setUserList(commonService.findList(nameSpace + "selectSafeSoundEventUserList", eventMap));
            eventMap.setProcessList(commonService.findList(nameSpace + "findSafeSoundFlowLogProcessInfo",eventMap));
        }
        if (!"".equals(eventMap.getRiskName())) {
            eventMap.setRiskNameList(Arrays.asList(eventMap.getRiskName().split(",")));
        }
        return eventMap;
    }

    @ApiOperation(value = "当事人矛盾纠纷事件列表查询", desc = "当事人矛盾纠纷事件列表查询", nologin = true)
    public List<Map<String, Object>> selectEventAllByCardList(Map<String, Object> map) {
        return commonService.findList(nameSpace + "selectEventAllByCardList", map);
    }

    @ApiOperation(value = "事件查询", desc = "事件查询")
    public Page<ReqEventFlowLogInsertVo> findSafeSoundEventLogByOfficeStatusList(Page<ReqEventFlowLogInsertVo> page) {
        return commonService.findPage(nameSpace + "findSafeSoundEventLogByOfficeStatusList", page);
    }

    @ApiOperation(value = "pc查询单条", desc = "pc查询单条")
    public ReqEventFlowLogInsertVo getSafeSoundEvent(ReqEventFlowLogInsertVo vo) {
        ReqEventFlowLogInsertVo eventMap = commonService.getObject(nameSpace + "getSafeSoundEvent", vo);
        eventMap.setUserList(commonService.findList(nameSpace + "selectSafeSoundUserByEventIdList", eventMap));
        return eventMap;
    }

    @ApiOperation(value = "手机端添加", desc = "手机端添加", nologin = true)
    public String insertSafeSoundFront(ReqSafeSoundEventInsertVo vo) {
        vo.setEventCode(this.eventCode(vo));
        vo.setStatus(NumberConstant.TWO_STRING);
        vo.setIsSpecialTasks(NumberConstant.TWO_STRING);
        if (commonService.insert(nameSpace + "insertSafeSoundEventFront", vo) != NumberConstant.ONE_INT) {
            throw new CustomException(NotesConstant.INSERT_EXCEPTION);
        }
        // 保存纠纷类型（其他）
        if (StringUtils.isNotEmpty(vo.getEvent_category_other_name()) || StringUtils.isNotEmpty(vo.getEvent_category_mini_other_name())) {
            commonService.insert(nameSpace + "insertSafeSoundEventCategoryOtherFront", vo);
        }
        List<ReqSafeSoundEventUserInsertVo> userList = vo.getUserList();
        for (ReqSafeSoundEventUserInsertVo user : userList) {
            if (user.getEventUserType().equals(NumberConstant.FOUR_STRING)) {
                if (StringUtils.isNotEmpty(user.getEventCardno())) {
                    if (!IdcardUtil.isValidCard(user.getEventCardno())) {
                        throw new CustomException("证件号码错误！");
                    }
                }
            }
            user.setEventId(vo.getId());
            user.set_user(vo.get_user());
            //添加当事人
            if (commonService.insert(nameSpace + "insertSafeSoundEventUserKeyFront", user) != NumberConstant.ONE_INT) {
                throw new CustomException(user.getEventUserName() + NotesConstant.INSERT_EXCEPTION);
            }
        }
        return NotesConstant.SAVE_SUCCESS;
    }

    @ApiOperation(value = "补填信息事件上报", desc = "补填信息事件上报")
    public String insertSafeSoundEvent(@Valid ReqEventInsertVo vo) throws InterruptedException {
        String eventId = vo.getId();
        vo.setEventId(eventId);
//        vo.setEventCode(this.eventCode(vo));
        vo.setStatus(NumberConstant.TWO_STRING);
        vo.setIsSpecialTasks(NumberConstant.TWO_STRING);
        vo.setReportingName(vo.get_user().getName()); //上报人
        vo.setReportingUnit(vo.get_user().getCompany_name());//上报人单位
        // 查询
        vo.setReportingUnitCode(vo.get_user().getCompany_id());//上报单位所属区划编码

        if (commonService.update(nameSpace + "updateSafeSoundEventByType", vo) != 1) {
            throw new CustomException(NotesConstant.INSERT_EXCEPTION);
        }

        vo.setEventCategoryId(commonService.getObject(nameSpace + "getValueNameDict", vo));

        //添加事件
        if (commonService.insert(nameSpace + "insertSafeSoundEvent", vo) != NumberConstant.ONE_INT) {
            throw new CustomException(NotesConstant.INSERT_EXCEPTION);
        }
        log.info("插入事件完成");
        // 保存纠纷类型（其他）
        if (StringUtils.isNotEmpty(vo.getEvent_category_other_name()) || StringUtils.isNotEmpty(vo.getEvent_category_mini_other_name())) {
            commonService.insert(nameSpace + "insertSafeSoundEventCategoryOther", vo);
        }
        //添加图片
        log.info("图片集合" + JSONUtil.toJsonStr(vo.getUrlList()));
        List<ReqEventAttachInsertVo> urlList = vo.getUrlList();
        if (!CollectionUtils.isEmpty(urlList)) {
            for (ReqEventAttachInsertVo sub : urlList) {
                log.info("图片对象" + JSONUtil.toJsonStr(vo.getUrlList()));
                sub.setId(vo.getId());
                if (commonService.insert(nameSpace + "insertSafeSoundEventAttach", sub) != NumberConstant.ONE_INT) {
                    throw new CustomException(NotesConstant.INSERT_EXCEPTION);
                }
            }
        }
        List<ReqEventUserInsertVo> userList = vo.getUserList();
        for (ReqEventUserInsertVo user : userList) {
            if (user.getEventUserType().equals(NumberConstant.FOUR_STRING)) {
                if (StringUtils.isNotEmpty(user.getEventCardno())) {
                    if (!IdcardUtil.isValidCard(user.getEventCardno())) {
                        throw new CustomException("证件号码错误！");
                    }
                }
            }
            user.setEventId(vo.getId());
            user.set_user(vo.get_user());
            //添加当事人
            if (commonService.insert(nameSpace + "insertSafeSoundEventUserKey", user) != NumberConstant.ONE_INT) {
                throw new CustomException(user.getEventUserName() + NotesConstant.INSERT_EXCEPTION);
            }
            if (StringUtils.isNotEmpty(user.getEventCardno())) {
                // 选择自然人的时候插入预警
                // 2:矛盾纠纷  user.getIsKeynote():是否重点人群，1：是，2：否
                if (vo.getEventType().equals("2") && StringUtils.isNotEmpty(user.getIsKeynote()) && user.getIsKeynote().equals(NumberConstant.ONE_STRING)) {
                    log.info("属于重点人群,记录重点人：{}", JSONUtil.toJsonStr(user));
                    if (commonService.insert(nameSpace + "insertSafeSoundTriggerEvent", user) != NumberConstant.ONE_INT) {
                        throw new CustomException(NotesConstant.RISK_EXCEPTION);
                    }
                } else { // 如果某个自然人 提出的矛盾纠纷，并且是处理中状态的 超过3次，则进入风险预警
                    Integer num = commonService.getObject(nameSpace + "getSafeSoundUserEventNumber", user);
                    if (num >= 3) {
                        log.info("矛盾超过3次,记录重点人：{}", JSONUtil.toJsonStr(user));
                        if (commonService.insert(nameSpace + "insertSafeSoundTriggerEvent", user) != NumberConstant.ONE_INT) {
                            throw new CustomException(NotesConstant.RISK_EXCEPTION);
                        }
                    }
                }
            }
        }
        User user = vo.get_user();
        String jobDuty = commonService.getObject(nameSpace + "getSafeSoundJobDuty", vo);
        if (vo.getLogType().equals(NumberConstant.ONE_STRING)) { //上报
            if (NumberConstant.ONE_STRING.equals(jobDuty)) {//网格员
                vo.setHierarchy(NumberConstant.ONE_INT);
                vo.setGradeUserId(user.getId());
                vo.setGradeD(NumberConstant.ZERO_STRING);
                vo.setEventFlowSettingType(NumberConstant.ONE_STRING);
                this.insertLogTypeOne(vo);
            } else {//非网格员
                vo.setHierarchy(HierarchyTypeEnums.hierarchyEnumGrad.getHierarchyGrade(user.getCompany_grade()));
                vo.setGradeUserId(NumberConstant.ONE_STRING);
                vo.setGradeD(NumberConstant.ONE_STRING);
                vo.setEventFlowSettingType(NumberConstant.ONE_STRING);
                this.insertLogTypeOne(vo);
            }
        } else if (vo.getLogType().equals(NumberConstant.SIX_STRING)) {//下派
            vo.setHierarchy(HierarchyTypeEnums.hierarchyEnumGrad.getHierarchyGrade(user.getCompany_grade()));
            vo.setGradeUserId(NumberConstant.ONE_STRING);
            vo.setGradeD(NumberConstant.ONE_STRING);
            vo.setEventFlowSettingType(NumberConstant.TWO_STRING);
            this.insertLogTypeOne(vo);
        } else { //横传
            vo.setHierarchy(HierarchyTypeEnums.hierarchyEnumGrad.getHierarchyGrade(user.getCompany_grade()));
            vo.setEventFlowSettingType(NumberConstant.ONE_STRING);
            this.insertLogTypeCross(vo);
        }
        Date occurrenceTime = DateUtils.parseDate(vo.getOccurrenceTime());
        Date createTime = new Date();
        if (com.scpyun.platform.jilinsscgsdp.utils.DateUtil.compareMonthsAcrossYears(occurrenceTime, createTime) != 0) {//计算补入
            SupplementEvent supplementEvent = new SupplementEvent();
            supplementEvent.setEventId(eventId);
            supplementEvent.setCreateTime(createTime);
            supplementEvent.setIsAreasOcus(0);
            supplementEvent.setAreaId(vo.getAreaId());
            supplementEvent.setCityId(vo.getCityId());
            supplementEvent.setOccurrenceTime(DateUtils.convertDate2String("yyyy-MM", occurrenceTime));
            supplementEvent.setEventCategoryId(vo.getEventCategoryId());
            commonService.insert(nameSpace + "insertSafeSoundEventSupplementInfo", supplementEvent);
        }
        // 重点事异步处理
        // 矛盾纠纷事件发生地点相同（社区）且属于易引发群体性事件的矛盾纠纷类型、发生时间跨度在30日以内，且矛盾纠纷大类相同、矛盾纠纷小类相同并达到5次以上
        threadPoolExecutor.execute(() -> {
            try {
                Thread.sleep(10000L);
                DataSourceSwitcher.setMaster();
                DataSourceSwitcher.setSharding("all");
                Integer groupRiskLevel;
                Integer riskFactorLevel;
                Integer stakeholderLevel;
                // 判断 群体性事件风险等级
                groupRiskLevel = getGroupRiskLevel(vo);
                // 判断 风险因子风险等级
                riskFactorLevel = getRiskFactorLevel(vo);
                // 判断 涉众时间风险等级
                stakeholderLevel = getStakeholderLevel(vo);
                // 比较风险等级
                RiskComparisonDTO.RiskLevel groupEvent = new RiskComparisonDTO.RiskLevel(RiskComparisonDTO.RiskType.GROUP_EVENT, groupRiskLevel); // 群体性事件 - 等级
                RiskComparisonDTO.RiskLevel riskFactor = new RiskComparisonDTO.RiskLevel(RiskComparisonDTO.RiskType.RISK_FACTOR, riskFactorLevel); // 风险因子 - 等级
                RiskComparisonDTO.RiskLevel stakeholder = new RiskComparisonDTO.RiskLevel(RiskComparisonDTO.RiskType.STAKEHOLDER, stakeholderLevel); // 涉众 - 等级
                List<RiskComparisonDTO.RiskLevel> risks = Arrays.asList(groupEvent, riskFactor, stakeholder);

                // 找出最高风险等级
                List<RiskComparisonDTO.RiskLevel> highestRisks = findHighestRisk(risks);
                if (highestRisks == null) {
                    return;
                }
                // 输出结果 只有一个最高等级
                if (highestRisks.size() == 1) {
                    RiskComparisonDTO.RiskLevel risk = highestRisks.get(0);
                    log.info("最高风险等级：{}", risk.getRiskType().getDescription() + " - 等级：" + risk.getLevel());
                    if (risk.getRiskType() == RiskComparisonDTO.RiskType.GROUP_EVENT) {
                        saveGroupEvent(vo, risk.getLevel());
                        // 风险因子条件触发 则保存 等级为空
                        if (riskFactorLevel != 99) {
                            saveRiskFactorEvent(vo, null);
                        }
                        // 风险因子条件触发 则保存 等级为空
                        if (stakeholderLevel != 99) {
                            saveStakeholderEvent(vo, null);
                        }
                    } else if (risk.getRiskType() == RiskComparisonDTO.RiskType.RISK_FACTOR) {
                        // 保存 风险因子高等级
                        saveRiskFactorEvent(vo, risk.getLevel());
                        // 其他非高等级 保存
                        if (groupRiskLevel != 99) {
                            saveGroupEvent(vo, null);
                        }
                        if (stakeholderLevel != 99) {
                            saveStakeholderEvent(vo, null);
                        }
                    } else {
                        // 保存涉众高等级
                        saveStakeholderEvent(vo, risk.getLevel());
                        // 其他非高等级 保存
                        if (groupRiskLevel != 99) {
                            saveGroupEvent(vo, null);
                        }
                        if (riskFactorLevel != 99) {
                            saveRiskFactorEvent(vo, null);
                        }
                    }
                } else {
                    //多个风险等级相同，均为最高
                    List<RiskComparisonDTO.RiskType> type = new ArrayList<>();
                    log.info("多个风险等级相同，均为最高，{}", JSONUtil.toJsonStr(highestRisks));
                    for (RiskComparisonDTO.RiskLevel risk : highestRisks) {
                        type.add(risk.getRiskType());
                        if (risk.getRiskType() == RiskComparisonDTO.RiskType.GROUP_EVENT) {
                            saveGroupEvent(vo, risk.getLevel());
                        } else if (risk.getRiskType() == RiskComparisonDTO.RiskType.RISK_FACTOR) {
                            // 保存 风险因子高等级
                            saveRiskFactorEvent(vo, risk.getLevel());
                        } else {
                            // 保存涉众高等级
                            saveStakeholderEvent(vo, risk.getLevel());
                        }
                    }
                    // 找出不是最高等级的数据 进行保存
                    // 排除所有在 type 中存在的 RiskType 的 RiskLevel
                    List<RiskComparisonDTO.RiskLevel> filteredRisks = risks.stream()
                            .filter(risk -> !type.contains(risk.getRiskType()))
                            .collect(Collectors.toList());
                    log.info("找出不是最高等级的数据 进行保存：{}", JSONUtil.toJsonStr(filteredRisks));
                    // 只能有一个 理论上
                    for (RiskComparisonDTO.RiskLevel filteredRisk : filteredRisks) {
                        if (filteredRisk.getRiskType().equals(RiskComparisonDTO.RiskType.GROUP_EVENT)) {
                            if (groupRiskLevel != 99) {
                                saveGroupEvent(vo, null);
                            }
                        } else if (filteredRisk.getRiskType().equals(RiskComparisonDTO.RiskType.RISK_FACTOR)) {
                            if (riskFactorLevel != 99) {
                                saveRiskFactorEvent(vo, null);
                            }
                        } else {
                            if (stakeholderLevel != 99) {
                                saveStakeholderEvent(vo, null);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.info("重点事件异步执行发生异常 eventId:{}", vo.getEventId(), e);
            }
        });
        return NotesConstant.SAVE_SUCCESS;
    }

    @ApiOperation(value = "矛盾事件处置进度查询", desc = "矛盾事件处置进度查询", nologin = true)
    public List<ReqEventFlowLogInsertVo> findSafeSoundFlowLogProcessList(ReqEventFlowLogInsertVo vo) {
        List<ReqEventFlowLogInsertVo> logList = commonService.findList(nameSpace + "findSafeSoundFlowLogProcessList", vo);
        List<ReqEventFlowLogInsertVo> mapList = new ArrayList<>();
        List<ReqEventFlowLogInsertVo> returnList = new ArrayList<>();
        ReqEventFlowLogInsertVo processMap = new ReqEventFlowLogInsertVo();
        for (ReqEventFlowLogInsertVo sub : logList) {
            sub.setCreateType("");
            if (sub.getEventStatus().equals("1") && sub.getStatus().equals("1")) {// 针对已办结事项，但是log中存在待处理的数据，进行排除
                continue;
            }
            mapList.add(sub);

        }
        for (ReqEventFlowLogInsertVo sub : mapList) {
            if (StringUtils.isNotEmpty(sub.getCreateType())) {
                processMap.setCreateTime(sub.getCreateTime());
                returnList.add(processMap);
            } else {
                returnList.add(sub);
            }
        }
        returnList.sort(Comparator.comparing(o -> StringUtils.toStr(o.getCreateTime())));
        for (int i = 0; i < returnList.size(); i++) {
            ReqEventFlowLogInsertVo item = returnList.get(i);
            if (i == returnList.size() - 1 && item.getLogType().equals(NumberConstant.TWO_STRING) && item.getStatus().equals(NumberConstant.THREE_STRING) && item.getEventStatus().equals("1")
                    && item.getIs_dispatch_office().equals("0")) {
                item.setIs_show_hf_history("1");// 是否显示回访记录按钮标识
            }
        }
        return returnList;
    }

    @ApiOperation(value = "驳回", desc = "驳回")
    public String updateSafeSoundEventTypeNum(Map<String, Object> map) {
        if (commonService.update(nameSpace + "updateSafeSoundEventTypeNum", map) != 1) {
            throw new CustomException("驳回失败");
        }
        return NotesConstant.SAVE_SUCCESS;
    }

    private void saveStakeholderEvent(ReqEventInsertVo vo, Integer level) {
        String uuid = UUIDUtil.getUUID();
        EventTrigger eventTrigger = new EventTrigger();
        eventTrigger.setId(uuid);
        eventTrigger.setTriggerType("3");// 涉众类型
        eventTrigger.setEventCategoryId(vo.getEventCategoryId());
        eventTrigger.setEventTypeId(vo.getEventTypeId());
        eventTrigger.set_user(vo.get_user());
        eventTrigger.setCityId(vo.getCityId());
        eventTrigger.setAreaId(vo.getAreaId());
        eventTrigger.setStreetId(vo.getStreetId());
        eventTrigger.setCommunityId(vo.getCommunityId());
        eventTrigger.setEventId(vo.getId());
        eventTrigger.setAlarmLevel(level);
        vo.setTriggerType("3");
        EventTrigger eventTriggerInfo = commonService.getObject(nameSpace + "getSafeSoundEventTriggerInfo", vo);
        if (eventTriggerInfo == null) {
            log.info("保存涉众重点事件：{}", JSONUtil.toJsonStr(eventTrigger));
            commonService.insert(nameSpace + "insertSafeSoundEventTriggerForRisk", eventTrigger);
        }
    }

    /**
     * 生成事件编号
     *
     * @param vo
     * @return
     */
    private String eventCode(ReqSafeSoundEventInsertVo vo) {
        String cityCode = "JL";
        String type = "MD";
        String today = DateUtil.today();
        today = today.replace("-", "");
        Long incr = JedisUtils.incr("eventCode_" + type + today);
        JedisUtils.expired("eventCode_" + type + today, 60 * 60 * 24);//设置键过期/秒
        return cityCode + type + today + String.format("%05d", incr);
    }

    /**
     * 横穿
     *
     * @param vo
     * @throws InterruptedException
     */
    private void insertLogTypeCross(ReqEventInsertVo vo) throws InterruptedException {
        ReqEventInsertVo flowSetting = new ReqEventInsertVo();
        vo.setOfficeId(vo.get_user().getCompany_id());
        vo.setStatus(NumberConstant.THREE_STRING);
        vo.setEventId(vo.getId());
        // 添加第一条提报记录
        if (commonService.insert(nameSpace + "insertSafeSoundFirstEventFlowLog", vo) != NumberConstant.ONE_INT) {
            throw new CustomException(NotesConstant.SAVE_LOG_EXCEPTION);
        }

        //根据最新版本查询上级流程
        vo.setHierarchy(vo.getHierarchy());
        vo.setVersion(flowSetting.getVersion());
        flowSetting = commonService.getObject(nameSpace + "getSafeSoundEventFlowSetting", vo);
        vo.setStatus(NumberConstant.ONE_STRING);
        vo.setFlowId(flowSetting.getId());
        List<String> officeList = vo.getOfficeList();
        for (String office : officeList) {
            vo.setOfficeId(office);
            //延迟一秒执行 拉开创建时间
            TimeUnit.SECONDS.sleep(NumberConstant.ONE_INT);
            //添加社区待处理记录
            vo.setIs_dispatch_office("1");// 分派、横传的处置部门标识
            if (commonService.insert(nameSpace + "insertSafeSoundEventFlowLog", vo) != NumberConstant.ONE_INT) {
                throw new CustomException(NotesConstant.SAVE_LOG_EXCEPTION);
            }
        }
    }

    /**
     * 上报 下派
     *
     * @param vo
     * @throws InterruptedException
     */
    private void insertLogTypeOne(ReqEventInsertVo vo) throws InterruptedException {
        ReqEventInsertVo flowSetting = new ReqEventInsertVo();
        flowSetting = commonService.getObject(nameSpace + "getSafeSoundEventFlowSetting", vo);
        //查询网格员审批流程设置当前最新版本
//        flowSettingMap = commonService.getObject(nameSpaceFlow + "getEventFlowSetting", vo);
        vo.setOfficeId(vo.get_user().getCompany_id());
        vo.setFlowId(flowSetting.getId());
        vo.setFlowVersion(flowSetting.getVersion());
        vo.setStatus(NumberConstant.THREE_STRING);
        vo.setEventId(vo.getId());
        if (vo.getGradeUserId().equals(NumberConstant.ONE_STRING)) {
            vo.setGradeUserId(null);
        }
        // 添加第一条提报记录
        if (commonService.insert(nameSpace + "insertSafeSoundFirstEventFlowLog", vo) != NumberConstant.ONE_INT) {
            throw new CustomException(NotesConstant.SAVE_LOG_EXCEPTION);
        }
        //根据最新版本查询上级流程
        // fixme hierarchy =  7 ?  没有7啊，下面查询就回空指针。。。
        if (vo.getLogType().equals(NumberConstant.SIX_STRING)) {// 下派
            vo.setHierarchy(vo.getHierarchy() - NumberConstant.ONE_INT);
        } else {
            if (vo.getHierarchy() != 6) {
                vo.setHierarchy(vo.getHierarchy() + NumberConstant.ONE_INT);
            }
        }
        vo.setVersion(flowSetting.getVersion());
        flowSetting = commonService.getObject(nameSpace + "getSafeSoundEventFlowSetting", vo);
        vo.setStatus(NumberConstant.ONE_STRING);
        vo.setFlowId(flowSetting.getId());
        if (vo.getGradeD().equals(NumberConstant.ONE_STRING)) {// 非网格员
            if (vo.getEventFlowSettingType().equals(NumberConstant.ONE_STRING)) {
                // 判断上报用户是否是横向部门，如果是横向部门，则上报到同级别综治中心
                String fax = commonService.getObject(nameSpace + "getSafeSoundFax", vo.get_user().getCompany_id());
                if (StringUtils.isNotEmpty(fax)) {// 是横向部门
                    // 获取该横向部门所属的综治中心
                    String office_id = commonService.getObject(nameSpace + "getSafeSoundOfficeId", vo.get_user().getCompany_id());
                    vo.setOfficeId(office_id);
                    vo.setHierarchy(vo.getHierarchy() - 1);
                } else {
                    vo.setOfficeId(vo.get_user().getParent_id());
                }
            } else {// 下派
                vo.setOfficeId(vo.getCrossOfficeId());
            }
        } else {
            vo.setOfficeId(vo.get_user().getCompany_id());
        }
        //延迟一秒执行 拉开创建时间
        TimeUnit.SECONDS.sleep(NumberConstant.ONE_INT);
        if (vo.getGradeD().equals(NumberConstant.ZERO_STRING)) {
            vo.setGradeUserId(null);
        }
        //添加社区待处理记录
        if (commonService.insert(nameSpace + "insertSafeSoundEventFlowLog", vo) != NumberConstant.ONE_INT) {
            throw new CustomException(NotesConstant.SAVE_LOG_EXCEPTION);
        }
    }

    private Integer getGroupRiskLevel(ReqEventInsertVo vo) {
        Integer level = 99;
        List<ReqEventInsertVo> list = new ArrayList<>();
        EventCategory eventCategory = new EventCategory();
        eventCategory.setValue(vo.getEventTypeId());
        EventCategory category = commonService.getObject("com.scpyun.platform.standard.jilinsscgsdp.safeSoundDao.selectSafeSoundEventCategory", eventCategory);
        if (category != null && Objects.equals(category.getIs_easy(), NumberConstant.ONE_STRING)) {
            Date currentOccurrenceDate = DateUtil.parse(vo.getOccurrenceTime(), "yyyy-MM-dd");
            vo.setOccurrenceTime(DateUtil.format(currentOccurrenceDate, "yyyy-MM-dd"));
            list = commonService.findList("com.scpyun.platform.standard.jilinsscgsdp.safeSoundDao.findSafeSound30DayEvent", vo);
            log.info("当前事件数量：{}", list.size());
            if (!list.isEmpty() && list.size() >= 5) {
                //不同当事人涉及的矛盾纠纷大类、小类相同，且属于易引发群体性事件矛盾纠纷类型，矛盾纠纷发生地相同，发生时间跨度在30日内，并达到5—30次的
                if (list.size() >= 5 && list.size() <= 30) {
                    log.info("当前事件数量：{}", list.size());
                    level = WarningLevelEnum.THREE_LEVEL.getStatus();
                } else if (list.size() > 31 && list.size() <= 300) {
                    //  不同当事人涉及的矛盾纠纷大类、小类相同，且属于易引发群体性事件矛盾纠纷类型，矛盾纠纷发生地相同，发生时间跨度在30日内，并达到31—300次
                    level = WarningLevelEnum.TWO_LEVEL.getStatus();
                } else {
                    //不同当事人涉及的矛盾纠纷大类、小类相同，且属于易引发群体性事件矛盾纠纷类型，矛盾纠纷发生地相同，发生时间跨度在30日内，并达到300次以上的
                    level = WarningLevelEnum.FIRST_LEVEL.getStatus();
                }
            }
        }
        return level;
    }

    private Integer getStakeholderLevel(ReqEventInsertVo vo) {
        Integer level = 99;
        if (Objects.equals(vo.getIs_involve_everyone(), NumberConstant.ONE_STRING)) {

            if (Objects.equals(vo.getIs_involve_everyone_count(), NumberConstant.ZERO_STRING)) {
                level = WarningLevelEnum.THREE_LEVEL.getStatus();
            } else if (Objects.equals(vo.getIs_involve_everyone_count(), NumberConstant.ONE_STRING)) {
                level = WarningLevelEnum.TWO_LEVEL.getStatus();
            } else {
                level = WarningLevelEnum.FIRST_LEVEL.getStatus();
            }
        }
        return level;
    }

    private Integer getRiskFactorLevel(ReqEventInsertVo vo) {
        Integer level = 99;
        String riskName = vo.getRiskName();
        String[] lengths = riskName != null ? riskName.split(",") : new String[0];
        if (lengths != null && lengths.length >= 3) {// 当存在风险因子>3 才会进行插入
            // 判断预警等级
            if (lengths.length == 3) {
                // 矛盾纠纷事件存在3个风险因子
                level = WarningLevelEnum.THREE_LEVEL.getStatus();
            } else if (lengths.length == 4) {
                //矛盾纠纷事件存在4个风险因子
                level = WarningLevelEnum.TWO_LEVEL.getStatus();
            } else {
                //矛盾纠纷事件存在4个及以上风险因子
                level = WarningLevelEnum.FIRST_LEVEL.getStatus();
            }
        }
        return level;
    }

    private void saveGroupEvent(ReqEventInsertVo vo, Integer level) {
        // 保存
        Date currentOccurrenceDate = DateUtil.parse(vo.getOccurrenceTime(), "yyyy-MM-dd");
        vo.setOccurrenceTime(DateUtil.format(currentOccurrenceDate, "yyyy-MM-dd"));

        String uuid = UUIDUtil.getUUID();
        EventTrigger eventTrigger = new EventTrigger();
        eventTrigger.setId(uuid);
        eventTrigger.setTriggerType("2");// 群体性事假 类型
        eventTrigger.setEventCategoryId(vo.getEventCategoryId());
        eventTrigger.setEventTypeId(vo.getEventTypeId());
        eventTrigger.set_user(vo.get_user());
        eventTrigger.setCityId(vo.getCityId());
        eventTrigger.setAreaId(vo.getAreaId());
        eventTrigger.setStreetId(vo.getStreetId());
        eventTrigger.setCommunityId(vo.getCommunityId());
        eventTrigger.setAlarmLevel(level);
        // 查询是否已存在重点事件
        vo.setTriggerType("2");
        EventTrigger eventTriggerInfo = commonService.getObject(nameSpace + "getSafeSoundEventTriggerInfo", vo);
        if (eventTriggerInfo == null) {
            log.info("保存群发性重点事件：{}", JSONUtil.toJsonStr(eventTrigger));
            commonService.insert(nameSpace + "insertSafeSoundEventTriggerForRisk", eventTrigger);
        } else {
            // 更新预警等级
            eventTrigger.setId(eventTriggerInfo.getId());
            commonService.update(nameSpace + "updateSafeSoundEventTriggerForRisk", eventTrigger);
            log.info("更新群发性重点事件预警等级：{}", JSONUtil.toJsonStr(eventTrigger));
        }
    }

    private void saveRiskFactorEvent(ReqEventInsertVo vo, Integer level) {
        EventRiskFactor eventRiskFactor = new EventRiskFactor();
        String eventTriggerId = UUIDUtil.getUUID();
        eventRiskFactor.setId(eventTriggerId);
        eventRiskFactor.setEventCategoryId(vo.getEventCategoryId());
        eventRiskFactor.setEventTypeId(vo.getEventTypeId());
        eventRiskFactor.set_user(vo.get_user());
        eventRiskFactor.setCityId(vo.getCityId());
        eventRiskFactor.setAreaId(vo.getAreaId());
        eventRiskFactor.setStreetId(vo.getStreetId());
        eventRiskFactor.setCommunityId(vo.getCommunityId());
        eventRiskFactor.setEventId(vo.getId());
        eventRiskFactor.setAlarmLevel(level);
        int insert = commonService.insert(nameSpace + "insertSafeSoundEventRiskFactor", eventRiskFactor);
        log.info("保存风险因子重点事件：{}", JSONUtil.toJsonStr(eventRiskFactor));
        if (insert != NumberConstant.ONE_INT) { // 重点事件预警
            throw new CustomException(NotesConstant.INSERT_EXCEPTION);
        }
    }

    public List<String> getDatesBetweenUsing(Date startDate, Date endDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        List<Date> datesInRange = new ArrayList<>();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(startDate);

        Calendar endCalendar = new GregorianCalendar();
        endCalendar.setTime(endDate);

        while (calendar.before(endCalendar)) {
            Date result = calendar.getTime();
            datesInRange.add(result);
            calendar.add(Calendar.DATE, 1);
        }
        List<String> dateList = new ArrayList<>();
        for (Date str : datesInRange) {
            dateList.add(format.format(str));
        }
        return dateList;
    }

    public static List<String> getDatesBetweenUsingAnd() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal_1 = Calendar.getInstance();//获取当前日期
        cal_1.add(Calendar.MONTH, 0);
        cal_1.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        /*String first = format.format(cal_1.getTime());
        System.out.println("===============first:"+first);*/
        //获取前月的最后一天
        Calendar cale = Calendar.getInstance();
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DAY_OF_MONTH)); //设置为1号,当前日期既为本月第一天
        /*String last = format.format(cale.getTime());
        System.out.println("===============last:"+last);*/
        List<Date> datesInRange = new ArrayList<>();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(cal_1.getTime());
        Calendar endCalendar = new GregorianCalendar();
        endCalendar.setTime(cale.getTime());
        while (calendar.before(endCalendar)) {
            Date result = calendar.getTime();
            datesInRange.add(result);
            calendar.add(Calendar.DATE, 1);
        }
        List<String> dateList = new ArrayList<>();
        for (Date str : datesInRange) {
            dateList.add(format.format(str));
        }
        return dateList;
    }

    private void verify(ReqSafeSoundEventInsertVo vo) {
        if (StringUtils.isEmpty(vo.getEventCategoryId())) {
            throw new CustomException("纠纷大类不可为空");
        }
        if (StringUtils.isEmpty(vo.getEventTypeId())) {
            throw new CustomException("纠纷小类不可为空");
        }
        if (StringUtils.isEmpty(vo.getAddress())) {
            throw new CustomException("详细地址不可为空");
        }
        if (StringUtils.isEmpty(vo.getDisputeDescription())) {
            throw new CustomException("纠纷描述不可为空");
        }
        if (StringUtils.isEmpty(vo.getCityId())) {
            throw new CustomException("市不可为空");
        }
        if (StringUtils.isEmpty(vo.getAreaId())) {
            throw new CustomException("区不可为空");
        }
        if (StringUtils.isEmpty(vo.getStreetId())) {
            throw new CustomException("街道不可为空");
        }
        if (StringUtils.isEmpty(vo.getCommunityId())) {
            throw new CustomException("社区不可为空");
        }
        if (StringUtils.isEmpty(vo.getOccurrenceTime())) {
            throw new CustomException("发生时间不可为空");
        }
        if (StringUtils.isEmpty(vo.getUserId())) {
            throw new CustomException("用户id不可为空");
        }
        List<ReqSafeSoundEventUserInsertVo> userList = vo.getUserList();
        if (CollectionUtils.isEmpty(userList)) {
            throw new CustomException("发生时间不可为空");
        }
        for (ReqSafeSoundEventUserInsertVo sub : userList) {
            if (StringUtils.isEmpty(sub.getEventCardno())) {
                throw new CustomException("身份证不可为空");
            } else {
                if (!IdcardUtil.isValidCard(sub.getEventCardno())) {
                    throw new CustomException("证件号码错误！");
                }
            }
            if (StringUtils.isEmpty(sub.getEventUserName())) {
                throw new CustomException("姓名不可为空");
            }
            if (StringUtils.isEmpty(sub.getEventTel())) {
                throw new CustomException("联系电话不可为空");
            } else {
                if (!this.isValidPhoneNumber(sub.getEventTel())) {
                    throw new CustomException("联系电话格式错误");
                }
            }
        }
    }

    private boolean isValidPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.isEmpty()) {
            return false;
        }
        Matcher matcher = PHONE_PATTERN.matcher(phoneNumber);
        return matcher.matches();
    }
}
