package com.yeejoin.equipmanage.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.interceptors.PermissionInterceptorContext;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificAlarmLog;
import com.yeejoin.equipmanage.common.entity.dto.EquipTypeAmountPageDTO;
import com.yeejoin.equipmanage.common.entity.vo.EquipTypeImgAmountVO;
import com.yeejoin.equipmanage.common.enums.EmergencyEquipTypeEnum;
import com.yeejoin.equipmanage.common.enums.IndexStatusEnum;
import com.yeejoin.equipmanage.common.enums.PressurePumpAnalysisEnum;
import com.yeejoin.equipmanage.common.enums.PressurePumpRelateEnum;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.utils.UnitTransformUtil;
import com.yeejoin.equipmanage.common.vo.IotDataVO;
import com.yeejoin.equipmanage.common.vo.PressurePumpCountVo;
import com.yeejoin.equipmanage.mapper.EmergencyMapper;
import com.yeejoin.equipmanage.service.IEmergencyService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificAlarmLogService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificSerivce;
import com.yeejoin.equipmanage.service.IPressurePumpService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 四横八纵应急模块接口服务类
 */
@Service
@Slf4j
public class EmergencyServiceImpl implements IEmergencyService {


    @Autowired
    private EmergencyMapper emergencyMapper;

    @Autowired
    private IEquipmentSpecificSerivce equipmentSpecificSerivce;

    @Autowired
    private IEquipmentSpecificAlarmLogService equipmentSpecificAlarmLogService;

    @Autowired
    private SupervisionVideoServiceImpl supervisionVideoService;

    @Autowired
    private IPressurePumpService pressurePumpService;

    @Value("${equipment.pressurepump.start}")
    private String pressurePumpStart;

    @Value("${equipment.pressurepump.pipepressure}")
    private String pressurePumpPipePressure;

    @Value("${equipment.pressurepump.start.cron}")
    private String pumpYesterdayStart;

    @Value("${auth-key-auth-enabled:}")
    private String authKey;

    @Override
    public List<Map<String, Object>> getSystemState(String bizOrgCode) {
        List<Map<String, Object>> list = emergencyMapper.getSystemState(bizOrgCode);
        if (0 < list.size()) {
            list.forEach(x -> {
                List<Map<String, Object>> list1 = new ArrayList();
                Map<String, Object> map = new HashMap<>();
                map.put("name", x.get("status"));
                if ("正常".equals(String.valueOf(x.get("status")))) {
                    map.put("level", "success");
                } else {
                    map.put("level", "warning");
                }
                list1.add(map);
                x.put("status", list1);
            });
        }
        return list;
    }


    @Override
    public Map<String, Object> getSystemAlarmCount(String status, int current, int size, String bizOrgCode) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> map = emergencyMapper.getSystemAlarmTheCount(status, bizOrgCode);
        resultMap.put("total", map.get("total"));
        List<Map<String, Object>> list = emergencyMapper.getSystemAlarmCount(status,current,size,bizOrgCode);
        if (0 < list.size()) {
            list.forEach(x -> {
                x.put("statis", x.get("status"));
                if ("正常".equals(String.valueOf(x.get("status")))) {
                    x.put("level", "success");
                } else {
                    x.put("level", "warning");
                }
            });
        }
        resultMap.put("records", list);
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> getCAFSWaterTankInfo() {
        List<Map<String, Object>> list = emergencyMapper.getCAFSWaterTankInfo();
        if (0 < list.size()) {
            for (Map<String, Object> m : list) {
                Map<String, Object> transResult = UnitTransformUtil.transformValues(String.valueOf(m.get("value")),
                        String.valueOf(m.get("unit")), String.valueOf(m.get("minLevel")), String.valueOf(m.get("maxLevel")));
                m.put("value", transResult.get("nowValue"));
                if (StringUtil.isNotEmpty(IndexStatusEnum.getEnumByKey(String.valueOf(transResult.get("status"))))) {
                    m.put("statusDesc", IndexStatusEnum.getEnumByKey(String.valueOf(transResult.get("status"))).getDescribe1());
                } else {
                    m.put("statusDesc", "--");
                }
                if (!String.valueOf(transResult.get("abs")).equals("--") && !ObjectUtils.isEmpty(m.get("volume"))) {
                    BigDecimal divide = new BigDecimal(100);
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(m.get("volume"))).multiply(new BigDecimal(String.valueOf(transResult.get("abs")))).divide(divide, 0, BigDecimal.ROUND_HALF_UP);
                    m.put("sxyl", bigDecimal + "m³ " + " (" + transResult.get("abs") + "%)");
                } else {
                    m.put("sxyl", transResult.get("abs"));
                }
            }
        }
        return Optional.ofNullable(list).orElse(Lists.newArrayList());
    }

    @Override
    public Map<String, Object> emergencyMaterials() {
        return emergencyMapper.selectEmergencyMaterials();
    }

    @Override
    public Page<Map<String, Object>> emergencyMaterialsDetails(Page<Map<String, Object>> page, String bizOrgCode) {
        return emergencyMapper.selectEmergencyMaterialsDetails(page, bizOrgCode);
    }

    @Override
    public Page<Map<String, Object>> selectFireMonitor(Page<Map<String, Object>> page, String bizOrgCode, String code) {
        return emergencyMapper.selectFireMonitor(page, bizOrgCode, code);
    }

    @Override
    public Page<Map<String, Object>> selectFoamTank(Page<Map<String, Object>> page) {
        Page<Map<String, Object>> page1 = emergencyMapper.selectFoamTank(page);
        List<Map<String, Object>> res = page1.getRecords();
        if (0 < res.size()) {
            for (Map<String, Object> m : res) {
                Map<String, Object> transResult = UnitTransformUtil.transformValues(String.valueOf(m.get("nowLevel")),
                        String.valueOf(m.get("unit")), String.valueOf(m.get("minLevel")), String.valueOf(m.get("maxLevel")));
//                m.put("nowLevel", transResult.get("nowValue"));
                if (StringUtil.isNotEmpty(IndexStatusEnum.getEnumByKey(String.valueOf(transResult.get("status"))))) {
                    m.put("status", IndexStatusEnum.getEnumByKey(String.valueOf(transResult.get("status"))).getDescribe1());
                } else {
                    m.put("status", "--");
                }
                if (!String.valueOf(transResult.get("abs")).equals("--") && !ObjectUtils.isEmpty(m.get("volume"))) {
                    BigDecimal divide = new BigDecimal(100);
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(m.get("volume"))).multiply(new BigDecimal(String.valueOf(transResult.get("abs")))).divide(divide, 0, BigDecimal.ROUND_HALF_UP);
                    m.put("abs", bigDecimal + "m³ " + " (" + transResult.get("abs") + "%)");
                } else {
                    m.put("abs", transResult.get("abs"));
                }
            }
        }
        return page1;
    }

    @Override
    public Page<Map<String, Object>> selectOilDrainage(Page<Map<String, Object>> page, String bizOrgCode, String code) {
        return emergencyMapper.selectOilDrainage(page, bizOrgCode, code);
    }

    @Override
    public Page<Map<String, Object>> selectGasExtinguishing(Page<Map<String, Object>> page, String bizOrgCode, String code) {
        return emergencyMapper.selectGasExtinguishing(page, bizOrgCode, code);
    }

    @Override
    public Page<Map<String, Object>> selectPressureFlow(Page<Map<String, Object>> page, String bizOrgCode) {
        return emergencyMapper.selectPressureFlow(page, bizOrgCode);
    }

    @Override
    public List<Map<String, Object>> selectAlarmAnalysis(String startDate, String endDate, String dataType, String date, String systemType) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.selectAlarmAnalysis(startDate, endDate, dataType, date, strings);
        }
        return null;

    }

    @Override
    public List<Map<String, Object>> selectAlarmAnalysisCount(String systemType, String startDate, String endDate) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.selectAlarmAnalysisCount(startDate, endDate, strings);
        }
        return null;

    }

    @Override
    public Map<String, Object> systemAndCar() {
        return emergencyMapper.getSystemAndCarCount();
    }

    @Override
    public List<Map<String, Object>> selectFireCannonAlarmAnalysisPie(String startDate, String endDate, String systemType) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.selectFireCannonAlarmAnalysisPie(startDate, endDate, strings);
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> waterSystemAlarmAnalysisPie(String startDate, String endDate, String systemType) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.waterSystemAlarmAnalysisPie(startDate, endDate, strings);
        }
        return null;
    }

    @Override
    public List<Map<String, Object>> waterSystemAlarmAnalysis(String startDate, String endDate, String dataType, String date, String systemType) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.waterSystemAlarmAnalysis(startDate, endDate, dataType, date, strings);
        }
        return null;

    }

    @Override
    public List<Map<String, Object>> fireCannonSystemAlarmAnalysis(String startDate, String endDate, String dataType, String date, String systemType) {
        // 权限处理
        PermissionInterceptorContext.setDataAuthRule(authKey);
        List<String> strings = emergencyMapper.selectSystemCodes(systemType);
        if (!CollectionUtils.isEmpty(strings)) {
            return emergencyMapper.fireCannonSystemAlarmAnalysis(startDate, endDate, dataType, date, strings);
        }
        return null;

    }


    @Override
    public List<Map<String, Object>> getEquipExpiryStatistics(Integer expiryDayNum) {
        List<Map<String, Object>> equipExpiryStatistics = emergencyMapper.getEquipExpiryStatistics(expiryDayNum);
        equipExpiryStatistics.forEach(item -> {
            item.put("value", Integer.parseInt(item.get("value").toString()));
        });
        return equipExpiryStatistics;
    }

    @Override
    public List<Map<String, String>> getEquipExpiryList(Integer expiryDayNum) {

        return emergencyMapper.getEquipExpiryList(expiryDayNum);
    }

    @Override
    public Map<String, Integer> getStockEquipStatistics() {
        return emergencyMapper.getStockEquipStatistics();
    }

    @Override
    public List<Map<String, Object>> getPressurePumpDiagnosticAnalysis(String bizOrgCode) {
        try {
            //  从 json 配置文件获取配置信息
            List<Map> infoList = pressurePumpService.getNameKeyInfoList(PressurePumpRelateEnum.PRESSURE_PUMP.getValue());
            if (!CollectionUtils.isEmpty(infoList)) {
                Map map = infoList.get(0);
                String equipmentCode = map.get("equipmentCode").toString();
                String pipePressureEquipmentCode = map.get("pipePressureEquipmentCode").toString();
                String faultNameKey = map.get("faultNameKey").toString();
                String top = map.get("top").toString();
                String countRedisKey = map.get("countRedisKey").toString();
                long countExpire = Long.parseLong(map.get("countExpire").toString());
                //  1. 判断稳压泵整体是否故障
                List<EquipmentSpecificAlarmLog> alarmLogList = equipmentSpecificAlarmLogService.getAlarmLogInfoList(equipmentCode, faultNameKey, PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue(), PressurePumpRelateEnum.UN_CLEAN_TIME.getValue(), bizOrgCode);
                PressurePumpAnalysisEnum.PRESSURE_PUMP_FAULT.setValue(CollectionUtils.isEmpty(alarmLogList) ? PressurePumpRelateEnum.NOT_FAULT.getValue() : PressurePumpRelateEnum.FAULT.getValue());
                //  获取稳压泵数据，redis没有，从iot取
                List<Map<String, Object>> pumpInfoList = equipmentSpecificSerivce.getFirePumpInfoEQ(equipmentCode, bizOrgCode);
                Map<String, List<IotDataVO>> dataMap = pressurePumpService.getDataList(pumpInfoList, PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), equipmentCode, top, pressurePumpStart, bizOrgCode, null);
                List<IotDataVO> dataList = dataMap.get("dataList");
                List<IotDataVO> dataListFilterTrue = dataMap.get("dataListFilterTrue");
                List<IotDataVO> dataListFilterFalse = dataMap.get("dataListFilterFalse");
                Map<String, List<IotDataVO>> dataPipMap = pressurePumpService.getDataList(pumpInfoList, PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), pipePressureEquipmentCode, top, pressurePumpPipePressure, bizOrgCode, null);
                List<IotDataVO> dataPipeList = dataPipMap.get("dataList");

                String nowStrLong = DateUtils.getDateNowString();
                Date dateNow = DateUtils.getDateNow();
                //  2. 最近一次启停间隔
                long interval = pressurePumpService.getAllPressurePumpStartStopInterval(dataList, dataListFilterTrue, dataListFilterFalse, nowStrLong);
                PressurePumpAnalysisEnum.PRESSURE_PUMP_INTERVAL.setValue(interval);
                //  3. 最近一次启动时长
                long duration = pressurePumpService.getAllPressurePumpStartStopDuration(dataList, dataListFilterTrue, dataListFilterFalse, nowStrLong);
                PressurePumpAnalysisEnum.PRESSURE_PUMP_DURATION.setValue(duration);
                //  4. 半小时启动
                int halfFrequency = pressurePumpService.getAllPressurePumpStartFrequency(Double.parseDouble(PressurePumpRelateEnum.HALF_HOUR.getValue()), dataListFilterTrue, dateNow);
                PressurePumpAnalysisEnum.PRESSURE_PUMP_HALF.setValue(halfFrequency);
                //  5. 今日启动次数，前3天启动次数的均值
                //  获取稳压泵数据，redis没有，从iot取
                Date startDate = DateUtils.dateAddDays(dateNow, Integer.parseInt(PressurePumpRelateEnum.DAY_AVG.getValue()));
                String startTime = String.join(" ", DateUtils.dateFormat(startDate, DateUtils.DATE_PATTERN), "00:00:00");
                String endTime = String.join(" ", DateUtils.dateFormat(dateNow, DateUtils.DATE_PATTERN), "00:00:00");
                Map<String, List<PressurePumpCountVo>> dayAvgDataMap = pressurePumpService.getDateRangeCountList(pumpInfoList, startTime,endTime, PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), countRedisKey, equipmentCode, pressurePumpStart, countExpire, bizOrgCode);
                AtomicInteger dayAvgFrequency = new AtomicInteger();
                if (!CollectionUtils.isEmpty(dayAvgDataMap)) {
                    for (List<PressurePumpCountVo> voList : dayAvgDataMap.values()) {
                        if (!CollectionUtils.isEmpty(voList)) {
                            voList.forEach(x -> dayAvgFrequency.addAndGet(x.getValue()));
                        }
                    }
                }
                DecimalFormat df = new DecimalFormat("0.0");
                int dayAvgCount = dayAvgFrequency.get();
                String dayAvgStartNum = dayAvgCount == 0 ? "0" : df.format(dayAvgCount / (double) Math.abs(Integer.parseInt(PressurePumpRelateEnum.DAY_AVG.getValue())));
                PressurePumpAnalysisEnum.PRESSURE_PUMP_DAY_AVG.setValue(dayAvgStartNum);
                //  6. 管网压力状态
                double pressureDiff = pressurePumpService.getAllPressurePumpPipePressureDiff(dataList, dataPipeList, PressurePumpRelateEnum.PRESSURE_PUMP_START_BEFORE_MINUTE.getValue());
                PressurePumpAnalysisEnum.PRESSURE_PUMP_PIPE.setValue(pressureDiff > Double.parseDouble(PressurePumpRelateEnum.PIPE_PRESSURE_DIFF.getValue()) ? PressurePumpRelateEnum.PIPE_PRESSURE_ABNORMAL_STATUS.getValue() : PressurePumpRelateEnum.PIPE_PRESSURE_NORMAL_STATUS.getValue());
            }
        } catch (ParseException e) {
            log.error("getPressurePumpDiagnosticAnalysis-->获取稳压泵诊断与分析失败：{}", e.getMessage());
        }
        return PressurePumpAnalysisEnum.getList();
    }

    @Override
    public Map<String, Object> getPressurePumpStartStatistics(String startTime, String endTime, String bizOrgCode) {
        Map<String, Object> map = new LinkedHashMap<>();
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime) && StringUtils.isNotBlank(bizOrgCode)) {
            //  从 json 配置文件获取配置信息
            List<Map> infoList = pressurePumpService.getNameKeyInfoList(PressurePumpRelateEnum.PRESSURE_PUMP.getValue());
            if (!CollectionUtils.isEmpty(infoList)) {
                Map infoMap = infoList.get(0);
                String equipmentCode = infoMap.get("equipmentCode").toString();
                String countRedisKey = infoMap.get("countRedisKey").toString();
                long countExpire = Long.parseLong(infoMap.get("countExpire").toString());
                //  获取所有稳压泵信息
                List<Map<String, Object>> pumpInfoList = equipmentSpecificSerivce.getFirePumpInfoEQ(equipmentCode, bizOrgCode);
                //  从redis获取日期范围数据，没有从iot获取。redis存储数据并返回
                Map<String, List<PressurePumpCountVo>> dateRangeCountMap = pressurePumpService.getDateRangeCountList(pumpInfoList, startTime, endTime, PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), countRedisKey, equipmentCode, pressurePumpStart, countExpire, bizOrgCode);
                if (!CollectionUtils.isEmpty(pumpInfoList)) {
                    List<String> timeList = DateUtils.getTimeStrListByStartAndEnd(startTime, endTime, DateUtils.DATE_PATTERN);
                    List<Map<String, Object>> yDataList = new ArrayList<>();
                    for (Map<String, Object> pumpMap : pumpInfoList) {
                        Object iotCode = pumpMap.get("iotCode");
                        Map<String, Object> dataMap = new HashMap<>();
                        List<Integer> dataList = new ArrayList<>();
                        for (String time : timeList) {
                            if (!ObjectUtils.isEmpty(iotCode) && !CollectionUtils.isEmpty(dateRangeCountMap)) {
                                String iotCodeStr = iotCode.toString();
                                List<PressurePumpCountVo> countVoList = dateRangeCountMap.get(iotCodeStr);
                                Map<String, List<PressurePumpCountVo>> collect = countVoList.stream().collect(Collectors.groupingBy(PressurePumpCountVo::getTime));
                                List<PressurePumpCountVo> data = collect.get(time);
                                dataList.add(CollectionUtils.isEmpty(data) ? 0 : data.get(0).getValue());
                            } else {
                                dataList.add(0);
                            }
                        }
                        dataMap.put("name", pumpMap.get("name"));
                        dataMap.put("data", dataList);
                        yDataList.add(dataMap);
                    }
                    List<String> collect = timeList.stream().map(x -> x.substring(5)).collect(Collectors.toList());
                    map.put("xData", collect);
                    map.put("yData", yDataList);
                }
            }
        }
        return map;
    }

    @Override
    public IPage<EquipTypeImgAmountVO> getEmergencyEquipList(EquipTypeAmountPageDTO equipTypeAmountPage) {
        List<String> list = new ArrayList<>();
        if (StringUtil.isNotEmpty(equipTypeAmountPage.getSixEquipType())) {
            list = EmergencyEquipTypeEnum.getCodeList();
        } else {
            String equipCodeLike = EmergencyEquipTypeEnum.getCodeByKey(equipTypeAmountPage.getEquipCodeKey());
            equipTypeAmountPage.setEquipCodeKey(equipCodeLike);
        }
        return emergencyMapper.getEmergencyEquipList(equipTypeAmountPage.getPage(), equipTypeAmountPage, list);
    }

    @Override
    public Map<String, Object> getPressurePumpStatusChart(String startTime, String endTime, String bizOrgCode) {
        Map<String, Object> map = new LinkedHashMap<>();
        try {
            //  从 json 配置文件获取配置信息
            List<Map> infoList = pressurePumpService.getNameKeyInfoList(PressurePumpRelateEnum.PRESSURE_PUMP.getValue());
            if (!CollectionUtils.isEmpty(infoList)) {
                Date dateNow = DateUtils.getDateNow();
                String dateNowString = DateUtils.getDateNowString();
                Map infoMap = infoList.get(0);
                String equipmentCode = infoMap.get("equipmentCode").toString();
                //  获取稳压泵
                List<Map<String, Object>> list = equipmentSpecificSerivce.getListByEquipmentCode(equipmentCode, bizOrgCode);
                //  获取各稳压泵数据，及时间戳
                if (!CollectionUtils.isEmpty(list)) {
                    //  获取查询时间范围内的时间戳
                    List<String> timeHourList = DateUtils.getTimeStrListByStartAndEnd(startTime, endTime, DateUtils.MONTH_DAY_HOUR_MINUTE_PATTERN);
                    Set<String> timeSet = new LinkedHashSet<>();
                    List<Map<String, Object>> yData = new ArrayList<>();
                    LinkedHashMap<String, List<Map<String, String>>> dataListMap = new LinkedHashMap<>();
                    for (Map<String, Object> x : list) {
                        Object iotCode = x.get("iotCode");
                        if (iotCode != null) {
                            //  判断开始时间，是否在redis缓存有效期之内，是，redis获取数据，否则，iot获取数据
                            int expire = Integer.parseInt(infoMap.get("expire").toString()) * -1;
                            Date beforeDate = DateUtils.dateAddSeconds(dateNow, expire);
                            Date startDate = DateUtils.convertStrToDate(startTime, DateUtils.DATE_TIME_PATTERN);
                            Date endDate = DateUtils.convertStrToDate(endTime, DateUtils.DATE_TIME_PATTERN);
                            if (DateUtils.dateCompare(startDate, beforeDate) >= 0) {
                                //  获取redis稳压泵缓存数据，默认JSON配置最近4小时
                                List<IotDataVO> redisDataList = pressurePumpService.getDataToRedisByDateBetween(PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), pressurePumpStart, iotCode.toString(), startDate, endDate, bizOrgCode);
                                if (!CollectionUtils.isEmpty(redisDataList)) {
                                    List<Map<String, String>> dataList = new ArrayList<>();
                                    redisDataList.forEach(y -> {
                                        timeSet.add(y.getCreatedTime());
                                        Map<String, String> xMap = new HashMap<>();
                                        xMap.put(pressurePumpStart, y.getValue().toString());
                                        xMap.put(PressurePumpRelateEnum.CREATED_TIME.getValue(), y.getCreatedTime());
                                        dataList.add(xMap);
                                    });
                                    dataListMap.put(iotCode.toString(), dataList);
                                } else {
                                    List<Map<String, String>> dataList = getDataList(startTime, endTime, iotCode);
                                    dataListMap.put(iotCode.toString(), dataList);
                                }
                            } else if (iotCode.toString().length() > 8) {
                                //  iot获取数据
                                List<Map<String, String>> dataList = getDataList(startTime, endTime, iotCode);
                                dataList.forEach(z -> timeSet.add(z.get(PressurePumpRelateEnum.CREATED_TIME.getValue())));
                                dataListMap.put(iotCode.toString(), dataList);
                            }
                        }
                    }
                    timeSet.add(dateNowString);
                    //  数据时间排序
                    List<String> sortTimeList = new ArrayList<>(timeSet);
                    Collections.sort(sortTimeList);
                    //  数据时间截取，MM-dd HH:mm
                    List<String> sortTimeCollectList = sortTimeList.stream().map(x -> x.substring(5, x.length() - 3)).collect(Collectors.toList());
                    //  数据时间截取，MM-dd HH
                    List<String> sortTimeTmpCollectList = sortTimeList.stream().map(x -> x.substring(5, x.length() - 6)).collect(Collectors.toList());
                    //  组装x时间轴数据
                    List<String> timeList = new ArrayList<>();
                    timeHourList.forEach(t -> {
                        String strTime = t.substring(0, t.length() - 3);
                        if (sortTimeCollectList.contains(t)) {
                            timeList.add(t);
                        } else if (!sortTimeTmpCollectList.contains(strTime)) {
                            timeList.add(strTime + ":00");
                            sortTimeTmpCollectList.add(strTime);
                        }
                    });
                    //  遍历稳压泵，dataListMap获取各稳压泵数据，没有数据的进行补0
                    list.forEach(x -> {
                        Map<String, Object> yMap = new HashMap<>();
                        List<Integer> yList = new ArrayList<>();
                        String name = x.get("name").toString();
                        yMap.put("name", name);
                        Object iotCode = x.get("iotCode");
                        if (x.get("iotCode") != null) {
                            List<Map<String, String>> dataList = dataListMap.get(iotCode.toString());
                            String flag = null;
                            if (!CollectionUtils.isEmpty(dataList)) {
                                Collections.reverse(dataList);
                                Map<String, List<Map<String, String>>> dataMap = dataList.stream().filter(y -> y.containsKey(PressurePumpRelateEnum.CREATED_TIME.getValue())).collect(Collectors.groupingBy(e -> e.get("createdTime").substring(5, 16)));
                                List<Map<String, String>> yDataList = null;

                                for (String t : timeList) {
                                    List<Map<String, String>> data = dataMap.get(t);
                                    if (!CollectionUtils.isEmpty(data)) {
                                        yDataList = data.stream().filter(o -> PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(o.get(pressurePumpStart))).collect(Collectors.toList());
                                        flag = data.get(data.size() - 1).get(pressurePumpStart);
                                        yList.add(!CollectionUtils.isEmpty(yDataList) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(flag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue()));
                                    } else {
                                        yList.add(StringUtils.isNotBlank(flag) && PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(flag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue()));
                                    }
                                }
                            } else {
                               // timeList.forEach(t -> yList.add(Integer.parseInt(PressurePumpRelateEnum.STOP.getValue())));

                                String prefix = iotCode.toString().substring(0, 8);
                                String suffix = iotCode.toString().substring(8);
                                List<Map<String, String>> iotDataList = pressurePumpService.getIotTopSingleField("1", prefix, suffix, PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue(), pressurePumpStart);
                                if (!CollectionUtils.isEmpty(iotDataList)) {
                                    flag = iotDataList.get(0).get(pressurePumpStart);
                                }
                                String finalFlag = flag;
                                timeList.forEach(t -> yList.add(StringUtils.isNotBlank(finalFlag) && PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(finalFlag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue())));

                            }
                            yMap.put("data", yList);
                            yData.add(yMap);
                        }
                    });
                    map.put("xData", timeList);
                    map.put("yData", yData);
                }
            }
        } catch (Exception e) {
            log.error("getPressurePumpStatusChart-->获取稳压泵启停状态图失败：{}", e.getMessage());
        }
        return map;
    }

    @Override
    public Map<String, Object> getPressurePumpStatusDetailChart(String startTime, String endTime, String bizOrgCode) {
        Map<String, Object> map = new LinkedHashMap<>();
        try {
            //  从 json 配置文件获取配置信息
            List<Map> infoList = pressurePumpService.getNameKeyInfoList(PressurePumpRelateEnum.PRESSURE_PUMP.getValue());
            if (!CollectionUtils.isEmpty(infoList)) {
                Date dateNow = DateUtils.getDateNow();
                Map infoMap = infoList.get(0);
                String equipmentCode = infoMap.get("equipmentCode").toString();
                //  获取稳压泵
                List<Map<String, Object>> list = equipmentSpecificSerivce.getListByEquipmentCode(equipmentCode, bizOrgCode);
                //  获取各稳压泵数据，及时间戳
                if (!CollectionUtils.isEmpty(list)) {
                    //  获取查询时间范围内的时间戳
                    List<String> timeHourList = DateUtils.getTimeStrListByStartAndEnd(startTime, endTime, DateUtils.MONTH_DAY_HOUR_MINUTE_PATTERN);
                    List<Map<String, Object>> yData = new ArrayList<>();
                    LinkedHashMap<String, List<Map<String, String>>> dataListMap = new LinkedHashMap<>();
                    for (Map<String, Object> x : list) {
                        Object iotCode = x.get("iotCode");
                        if (iotCode != null) {
                            //  判断开始时间，是否在redis缓存有效期之内，是，redis获取数据，否则，iot获取数据
                            int expire = Integer.parseInt(infoMap.get("expire").toString()) * -1;
                            Date beforeDate = DateUtils.dateAddSeconds(dateNow, expire);
                            Date startDate = DateUtils.convertStrToDate(startTime, DateUtils.DATE_TIME_PATTERN);
                            Date endDate = DateUtils.convertStrToDate(endTime, DateUtils.DATE_TIME_PATTERN);
                            if (DateUtils.dateCompare(startDate, beforeDate) >= 0) {
                                //  获取redis稳压泵缓存数据，默认JSON配置最近4小时
                                List<IotDataVO> redisDataList = pressurePumpService.getDataToRedisByDateBetween(PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), pressurePumpStart, iotCode.toString(), startDate, endDate, bizOrgCode);
                                if (!CollectionUtils.isEmpty(redisDataList)) {
                                    List<Map<String, String>> dataList = new ArrayList<>();
                                    redisDataList.forEach(y -> {
                                        Map<String, String> xMap = new HashMap<>();
                                        xMap.put(pressurePumpStart, y.getValue().toString());
                                        xMap.put(PressurePumpRelateEnum.CREATED_TIME.getValue(), y.getCreatedTime());
                                        dataList.add(xMap);
                                    });
                                    dataListMap.put(iotCode.toString(), dataList);
                                } else {
                                    List<Map<String, String>> dataList = getDataList(startTime, endTime, iotCode);
                                    dataListMap.put(iotCode.toString(), dataList);
                                }
                            } else if (iotCode.toString().length() > 8) {
                                //  iot获取数据
                                List<Map<String, String>> dataList = getDataList(startTime, endTime, iotCode);
                                dataListMap.put(iotCode.toString(), dataList);
                            }
                        }
                    }
                    //  遍历稳压泵，dataListMap获取各稳压泵数据，没有数据的进行补0
                    list.forEach(x -> {
                        Map<String, Object> yMap = new HashMap<>();
                        List<Integer> yList = new ArrayList<>();
                        String name = x.get("name").toString();
                        yMap.put("name", name);
                        Object iotCode = x.get("iotCode");
                        if (!ObjectUtils.isEmpty(iotCode)) {
                            List<Map<String, String>> dataList = dataListMap.get(iotCode.toString());
                            //  获取最新稳压泵启动指标值，作为后续稳压泵启停参考值
                            String flag = null;
                            if (!CollectionUtils.isEmpty(dataList)) {
                                Collections.reverse(dataList);
                                Map<String, List<Map<String, String>>> dataMap = dataList.stream().filter(y -> y.containsKey(PressurePumpRelateEnum.CREATED_TIME.getValue())).collect(Collectors.groupingBy(e -> e.get("createdTime").substring(5, 16)));
                                List<Map<String, String>> yDataList = null;
                                for (String t : timeHourList) {
                                    List<Map<String, String>> data = dataMap.get(t);
                                    if (!CollectionUtils.isEmpty(data)) {
                                        yDataList = data.stream().filter(o -> PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(o.get(pressurePumpStart))).collect(Collectors.toList());
                                        flag = data.get(data.size() - 1).get(pressurePumpStart);
                                        yList.add(!CollectionUtils.isEmpty(yDataList) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(flag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue()));
                                    } else {
                                        yList.add(StringUtils.isNotBlank(flag) && PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(flag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue()));
                                    }
                                }
                            } else {
                                String prefix = iotCode.toString().substring(0, 8);
                                String suffix = iotCode.toString().substring(8);
                                List<Map<String, String>> iotDataList = pressurePumpService.getIotTopSingleField("1", prefix, suffix, PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue(), pressurePumpStart);
                                if (!CollectionUtils.isEmpty(iotDataList)) {
                                    flag = iotDataList.get(0).get(pressurePumpStart);
                                }
                                String finalFlag = flag;
                                timeHourList.forEach(t -> yList.add(StringUtils.isNotBlank(finalFlag) && PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue().equalsIgnoreCase(finalFlag) ? Integer.parseInt(PressurePumpRelateEnum.START.getValue()) : Integer.parseInt(PressurePumpRelateEnum.STOP.getValue())));
                            }
                            yMap.put("data", yList);
                            yData.add(yMap);
                        }
                    });
                    map.put("xData", timeHourList);
                    map.put("yData", yData);
                }
            }
        } catch (Exception e) {
            log.error("getPressurePumpStatusDetailChart-->获取稳压泵启停状态图失败：{}", e.getMessage());
        }
        return map;
    }

    private List<Map<String, String>> getDataList(String startTime, String endTime, Object iotCode) {
        String prefix = iotCode.toString().substring(0, 8);
        String suffix = iotCode.toString().substring(8);
        List<Map<String, String>> dataList = pressurePumpService.getIotCommonListData(startTime, endTime, prefix, suffix, null, pressurePumpStart);
        return dataList;
    }


    @Override
    public Page<Map<String, Object>> alarmList(Page<Map<String, Object>> page, String bizOrgCode, String systemCode, String systemType,
                                               List<String> types, List<String> emergencyLevels, String name, Integer cleanStatus,
                                               Integer handleStatus,String createDate,String startDate,String endDate,
                                               String sortField,String sortOrder) {
        return emergencyMapper.alarmListNew(page, bizOrgCode, systemCode, systemType, types, emergencyLevels, name, cleanStatus,
                handleStatus, createDate, startDate, endDate, sortField, sortOrder);
    }

    //稳压泵定时向缓存中存昨日启动次数任务
    @Scheduled(cron = "${equipment.pressurepump.start.cron}")
    private void stationDoubleReport() {
        System.out.println("开始定时存储昨日稳压泵启动次数，定时时间为：" + pumpYesterdayStart);
        getPressurePumpDay();
    }

    @Override
    public Map<String, List<PressurePumpCountVo>> getPressurePumpDay() {
        Map<String, List<PressurePumpCountVo>> dataMap = new HashMap<>();
        //  从 json 配置文件获取配置信息
        List<Map> infoList = pressurePumpService.getNameKeyInfoList(PressurePumpRelateEnum.PRESSURE_PUMP.getValue());
        if (!CollectionUtils.isEmpty(infoList)) {
            try {
                Date dateNow = DateUtils.convertStrToDate(DateUtils.getDateNowString(), DateUtils.DATE_PATTERN);
                Date beforeDate = DateUtils.dateAddDays(dateNow, Integer.parseInt(PressurePumpRelateEnum.CRON_BEFORE_DAY.getValue()));
                //  iot获取数据，返回并存储redis
                String startTime = DateUtils.convertDateToString(beforeDate, DateUtils.DATE_TIME_PATTERN);
                String endTime = DateUtils.convertDateToString(dateNow, DateUtils.DATE_TIME_PATTERN);
                Map infoMap = infoList.get(0);
                String equipmentCode = infoMap.get("equipmentCode").toString();
                String countRedisKey = infoMap.get("countRedisKey").toString();
                long countExpire = Long.parseLong(infoMap.get("countExpire").toString());
                List<Map<String, Object>> pumpInfoList = equipmentSpecificSerivce.getFirePumpInfoEQ(equipmentCode, null);
                if (!CollectionUtils.isEmpty(pumpInfoList)){
                    for (Map<String, Object> map : pumpInfoList) {
                        //  iot获取数据，返回并存储redis
                        Object iotCode = map.get("iotCode");
                        Object orgCode = map.get("bizOrgCode");
                        String bizOrgCode = ObjectUtils.isEmpty(orgCode) ? "" : orgCode.toString();
                        if (!ObjectUtils.isEmpty(iotCode) && !ObjectUtils.isEmpty(bizOrgCode)) {
                            // 获取公司顶级bizOrgCode
                            bizOrgCode = pressurePumpService.getCompanyBizOrgCode(bizOrgCode);
                            String iotCodeStr = iotCode.toString();
                            String prefix = ObjectUtils.isEmpty(iotCode) ? "" : iotCodeStr.substring(0, 8);
                            String suffix = ObjectUtils.isEmpty(iotCode) ? "" : iotCodeStr.substring(8);
                            List<PressurePumpCountVo> dataList = pressurePumpService.getIotCountData(startTime, endTime, PressurePumpRelateEnum.PRESSURE_PUMP.getValue(), countRedisKey, prefix, suffix, PressurePumpRelateEnum.IOT_INDEX_VALUE_TRUE.getValue(), pressurePumpStart, countExpire, bizOrgCode);
                            dataMap.put(iotCodeStr, dataList);
                        }
                    }
                }
            } catch (ParseException e) {
                log.error("redis存稳压泵昨天启动次数失败：{}", e.getMessage());
            }
        }
        return dataMap;
    }

    @Override
    public Map<String, Object> getEmergencyMaterials(String bizOrgCode) {
        return emergencyMapper.getEmergencyMaterials(bizOrgCode);
    }

    @Override
    public List<Map<String, Object>> getEquipStatistic(String bizOrgCode, String equipCodeKey) {
        String equipCodeLike = EmergencyEquipTypeEnum.getCodeByKey(equipCodeKey);
        return emergencyMapper.getEquipStatistic(bizOrgCode, equipCodeLike);
    }

    @Override
    public List<Map<String, Object>> getAllTypeEquipStatistic(String bizOrgCode) {
        List<String> list = EmergencyEquipTypeEnum.getCodeList();
        return emergencyMapper.getAllTypeEquipStatistic(bizOrgCode, list);
    }

    @Override
    public List<Map<String, Object>> fireCannonValve(String bizOrgCode) {
        List<Map<String, Object>> list = emergencyMapper.fireCannonValve(bizOrgCode);
        return Optional.ofNullable(list).orElse(org.apache.commons.compress.utils.Lists.newArrayList());
    }
}
