package com.sckw.slope.detection.consumer;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.model.enums.*;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.DateUtils;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.PasswordUtils;
import com.sckw.core.web.response.HttpResult;
import com.sckw.log.TraceLog.TraceLog;
import com.sckw.redis.config.RedisLockUtil;
import com.sckw.redis.constant.RedisConstant;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.slope.detection.common.config.SmsTemplateConfig;
import com.sckw.slope.detection.dao.mysql.*;
import com.sckw.slope.detection.dao.tdengine.SlopeDataMapper;
import com.sckw.slope.detection.model.dos.mysql.*;
import com.sckw.slope.detection.model.dos.tdengine.Devices;
import com.sckw.slope.detection.model.dos.tdengine.SlopeData;
import com.sckw.slope.detection.model.dto.AlarmList;
import com.sckw.slope.detection.model.dto.DevicesAlarm;
import com.sckw.slope.detection.model.dto.DevicesItem;
import com.sckw.slope.detection.model.dto.SystemDict;
import com.sckw.slope.detection.model.vo.DeviceIntegrationVo;
import com.sckw.slope.detection.model.vo.ProjectVo;
import com.sckw.slope.detection.service.CommonService;
import com.sckw.slope.detection.service.TdengineService;
import com.sckw.slope.detection.service.api.DetectionApiService;
import com.sckw.slope.detection.service.repository.KwsAlarmInfoRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.MD5Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description
 * @date 2023-10-26 08:10:45
 */
@Slf4j
@Service("system/iot/device_data_slope")
public class MqttCallbackHandler extends AbstractHandler {


    @Autowired
    CommonService commonService;

    @Autowired
    DetectionApiService detectionApiService;

    @Autowired
    SlopeDataMapper slopeDataMapper;

    @Autowired
    KwsDeviceMapper deviceMapper;

    @Autowired
    KwsThresholdMapper thresholdMapper;

    @Autowired
    HandlerFactory handlerFactory;

    @Autowired
    KwsDeviceIntegrationMapper deviceIntegrationMapper;

    @Autowired
    KwsIntegrationMapper integrationMapper;

    @Autowired
    KwsAlarmInfoRepository alarmInfoRepository;

    @Autowired
    SmsTemplateConfig smsTemplateConfig;

    @Autowired
    RedisLockUtil redisLockUtil;

    @TraceLog(description = "处理system/iot/device_data_slope")
    @DSTransactional
    public HttpResult handle(String topic, String payload) {
        // 根据topic分别进行消息处理。
        log.info("MqttDeviceCallbackHandler:" + topic + "|" + payload);

        DevicesAlarm devicesAlarm = JSONObject.parseObject(payload, DevicesAlarm.class);
        Map<String, SystemDict> dictByDictCode = commonService.getDictByDictCode(DictEnum.MODEL_PART);
        String key = PasswordUtils.md5(topic + "alarm" + payload);
        String alarmKey = String.format(RedisConstant.MQ_CONSUMER_ALARM_KEY, key);
        boolean flag = redisLockUtil.tryLock(alarmKey, 5);
        if (flag) {
            try {
//            DevicesAlarm devicesAlarm = JSONObject.parseObject(payload, DevicesAlarm.class);
                String deviceCode = devicesAlarm.getGuid();
                List<KwsDevice> deviceList = deviceMapper.selectList(new LambdaQueryWrapper<KwsDevice>()
                        .eq(KwsDevice::getSnCodeFullName, deviceCode)
                        .eq(KwsDevice::getDelFlag, NumberConstant.ZERO)
                );
                KwsDevice device = null;
                if (!org.springframework.util.CollectionUtils.isEmpty(deviceList)) {
                    device = deviceList.get(0);
                }
                if (device == null) {
                    log.error("接收处理数据:{}", payload);
                    log.error("设备数据并未维护+[" + devicesAlarm.getGuid() + "],不做处理");
                    return null;
                }
                List<DevicesItem> devicesItemList = devicesAlarm.getDevicesItemList();
                if (!CollectionUtils.isEmpty(devicesItemList)) {
                    HashMap<Object, Object> devicesItemMap = devicesItemList.stream().collect(HashMap::new,
                            (m, v) -> m.put(v.getItemName(), v.getItemValue()), HashMap::putAll);
                    String time = "";
                    long timeDate = 0L;
                    //2023-11-30 22:00:00
                    if (devicesItemMap != null) {
                        if (Objects.nonNull(devicesItemMap.get("time"))) {
                            time = String.valueOf(devicesItemMap.get("time").toString());
                            timeDate = DateUtils.formatDate(time).getTime() / 1000L;
                        }
                    }
                    for (DevicesItem devicesItem : devicesItemList) {
                        String itemName = devicesItem.getItemName();
                        String itemValue = devicesItem.getItemValue();
                        List<KwsThreshold> kwsThresholds = thresholdMapper.selectList(new LambdaQueryWrapper<KwsThreshold>()
                                .eq(KwsThreshold::getDeviceId, device.getId())
                                .eq(KwsThreshold::getDelFlag, NumberConstant.ZERO)
                                .eq(KwsThreshold::getItemName, itemName)
                        );
                        if (org.springframework.util.CollectionUtils.isEmpty(kwsThresholds)) {
                            continue;
                        }
                        Long ts = 0L != timeDate ? timeDate : devicesAlarm.getTs();
                        //判断是否满足设备超时离线报警
//                    checkDeviceAlarm(deviceCode, device, itemValue, ts);
                        //判断是否满足数值超阈值报警
                        Map<String, String> map = checkThresholdAlarm(devicesItem, kwsThresholds, device);
                        if ("2".equals(map.get("flag"))) {
                            Long level = Long.valueOf(map.get("level"));
                            Long thresholdId = Long.valueOf(map.get("thresholdId"));
                            String offset = map.get("offset");
                            //阈值表以及明细表存储
                            long id = insertAlarmAndDetail(level, device, thresholdId, offset, ts, AlarmTitleEnum.ALARM_TITLE_TWO.getStatus(), AlarmTypeEnum.ALARM_ONE.getCode());
                            //todo 不适用redis存统计  使用新字段处理
                            /**阈值次数存redis*/
//                        redisPutAlarmCount(id);
                            String mountainId = device.getMountainId();
                            List<KwsAlarmInfo> list = alarmInfoRepository.list(new LambdaQueryWrapper<KwsAlarmInfo>()
                                    .eq(KwsAlarmInfo::getMountainId, mountainId)
                                    .eq(KwsAlarmInfo::getLevel, level.intValue())
                                    .eq(KwsAlarmInfo::getType, NumberConstant.ONE)
                                    .eq(KwsAlarmInfo::getDelFlag, NumberConstant.ZERO)
                            );
                            List<String> pushToPhone = new ArrayList<>();
                            if (!CollectionUtils.isEmpty(list)) {
                                pushToPhone = list.stream().map(KwsAlarmInfo::getValueDesc).distinct().collect(Collectors.toList());
                            }
                            if (!CollectionUtils.isEmpty(pushToPhone) && pushToPhone.size() > 0) {
//                        KwsThreshold kwsThreshold = thresholdMapper.selectById(thresholdId);
//                        String phones = kwsThreshold.getPhones();
//                        List<String> pushToPhone = com.sckw.core.utils.StringUtils.splitStrToList(phones, String.class);
                                Map<String, String> templateParam = new HashMap<>();
                                if (StringUtils.isBlank(time)) {
                                    LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
                                    time = com.sckw.excel.utils.DateUtil.format(localDateTime);
                                }
                                templateParam.put("time", time);
                                templateParam.put("level", AlarmLevelEnum.getChineseName(level.intValue()));
                                templateParam.put("name", device.getName());
//                            templateParam.put("value", itemValue);
                                templateParam.put("value", offset);
                                commonService.pushSmsMessage(pushToPhone
                                        , smsTemplateConfig.getDataAlarm().getSmsCode()
                                        , smsTemplateConfig.getDataAlarm().getSignName()
                                        , templateParam);
                            }
                            ProjectVo vo = projectDeviceMapper.selectProjectByDeviceId(device.getId());
                            /**邮件推送*/
                            List<KwsAlarmInfo> emailList = alarmInfoRepository.list(new LambdaQueryWrapper<KwsAlarmInfo>()
                                    .eq(KwsAlarmInfo::getMountainId, mountainId)
                                    .eq(KwsAlarmInfo::getLevel, level.intValue())
                                    .eq(KwsAlarmInfo::getType, NumberConstant.TWO)
                                    .eq(KwsAlarmInfo::getDelFlag, NumberConstant.ZERO)
                            );
                            List<String> emailAddress = new ArrayList<>();
                            if (!CollectionUtils.isEmpty(emailList) && emailList.size() > 0) {
                                emailAddress = emailList.stream().map(KwsAlarmInfo::getValueDesc).distinct().collect(Collectors.toList());
                            }
                            if (!CollectionUtils.isEmpty(emailAddress)) {
                                Map<String, String> templateParam = new HashMap<>();
                                if (StringUtils.isBlank(time)) {
                                    LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
                                    time = com.sckw.excel.utils.DateUtil.format(localDateTime);
                                }
                                templateParam.put("company", smsTemplateConfig.getDataAlarm().getSignName());
                                templateParam.put("level", AlarmLevelEnum.getName(level.intValue()));
                                templateParam.put("name", device.getName());
                                templateParam.put("time", time);
                                templateParam.put("project", vo == null ? null : vo.getProjectName());
//                            templateParam.put("value", itemValue);
                                templateParam.put("value", offset);
                                templateParam.put("element", dictByDictCode.get(itemName).getLabel());
                                templateParam.put("type", AlarmTitleEnum.ALARM_TITLE_TWO.getName() + "告警");
//                                commonService.pushEmailMessage(emailAddress
//                                        , templateParam,"设备告警通知邮件");
                                commonService.pushHtmlEmailMessage(emailAddress
                                        , templateParam, "设备告警通知邮件");
                            }
                        }
                        //集成要素阈值告警
                        deviceIntegrationsAlarm(device, ts, time);
                    }
                }
            } catch (Exception e) {
                log.error("mqtt消费异常:{}", e.getMessage(), e);
            } finally {
                redisLockUtil.unlock(alarmKey);
            }
        }
        return HttpResult.ok();
    }

    private void redisPutAlarmCount(long id) {
        String key = Global.REDIS_SYS_ALARM_PREFIX + Global.POUND + String.valueOf(id) + Global.POUND + AlarmTypeEnum.ALARM_ONE.getStatus()
                + Global.POUND + AlarmTitleEnum.ALARM_TITLE_TWO.getStatus();
        String number = RedissonUtils.getString(key);
        Long count = alarmDetailMapper.selectCount(new LambdaQueryWrapper<KwsAlarmDetail>()
                .eq(KwsAlarmDetail::getAlarmId, id)
                .eq(KwsAlarmDetail::getStatus, 0)
        );
        if (StringUtils.isBlank(number)) {
            RedissonUtils.putString(key, "1", Global.COMMON_EXPIRE);
        } else {
            RedissonUtils.putString(key, count.toString(), Global.COMMON_EXPIRE);
        }
    }

    /**
     * 集成要素阈值告警
     *
     * @param device 设备
     * @param ts     ts
     * @param time   时间
     */
    private void deviceIntegrationsAlarm(KwsDevice device, Long ts, String time) throws IOException {
        Map<String, SystemDict> dictByDictCode = commonService.getDictByDictCode(DictEnum.INTEGRATION_UNIT);
//        List<KwsDeviceIntegration> deviceIntegrations = deviceIntegrationMapper.selectList(
//                new LambdaQueryWrapper<KwsDeviceIntegration>()
//                        .eq(KwsDeviceIntegration::getDeviceId, device.getId())
//                        .eq(KwsDeviceIntegration::getDelFlag, 0)
//        );
//        List<Long> integrationIds = null;
//        if (!org.springframework.util.CollectionUtils.isEmpty(deviceIntegrations)) {
//            integrationIds = deviceIntegrations.stream().map(KwsDeviceIntegration::getIntegrationId).collect(Collectors.toList());
//        }
//        List<KwsIntegration> integrations = integrationMapper.selectList(
//                new LambdaQueryWrapper<KwsIntegration>()
//                        .in(KwsIntegration::getId, integrationIds)
//                        .eq(KwsIntegration::getDelFlag, NumberConstant.ZERO)
//        );
//        Map<String, Long> integrationMap = new HashMap<>(NumberConstant.SIXTEEN);
//        if (!org.springframework.util.CollectionUtils.isEmpty(integrations)) {
//            integrationMap = integrations.stream().collect(Collectors.toMap(KwsIntegration::getPartNames, KwsIntegration::getId));
//        }
        //获取集成要素
        if (StringUtils.isBlank(time)) {
            LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
            time = com.sckw.excel.utils.DateUtil.format(localDateTime);
        }
        List<DeviceIntegrationVo> intergData = new ArrayList<>();
        String snCode = device.getSnCode();
        intergData = deviceIntegrationMapper.selectListParamsAndInterNameByDeviceId(device.getId());
        if (!Objects.isNull(intergData) || intergData.size() > 0) {
            for (DeviceIntegrationVo deviceIntegration : intergData) {
                String unit = "";
                //获取到当前测量值--现在只有单一值
                List<SlopeData> slopeData = slopeDataMapper.selectListByTwoLine(snCode, deviceIntegration.getPartNames());
                if (!Objects.isNull(slopeData) && slopeData.size() == 2) {
                    List<KwsThreshold> thresholdList = thresholdMapper.selectList(new LambdaQueryWrapper<KwsThreshold>()
                            .eq(KwsThreshold::getDeviceId, device.getId())
                            .eq(KwsThreshold::getItemName, deviceIntegration.getIntegrationName())
                    );
                    double offset = commonService.returnIntegrationData(snCode, slopeData, deviceIntegration);
                    Map<String, String> map = newAlarmCompute(new BigDecimal(offset), thresholdList);
                    if ("2".equals(map.get("flag"))) {
                        Long level = Long.valueOf(map.get("level"));
                        Long thresholdId = Long.valueOf(map.get("thresholdId"));
                        //阈值表以及明细表存储
//                        String url = deviceIntegration.getUnit() == null ? null : deviceIntegration.getUnit();
//                        String itemValueAndUnit = StringUtils.isBlank(url) ? String.valueOf(offset) : (offset + deviceIntegration.getUnit());
//                        long id = insertAlarmAndDetail(level, device, thresholdId, itemValueAndUnit, ts, AlarmTitleEnum.ALARM_TITLE_TWO.getStatus(), AlarmTypeEnum.ALARM_ONE.getCode());
                        unit = dictByDictCode.get(deviceIntegration.getUnit()) == null ? deviceIntegration.getUnit() : dictByDictCode.get(deviceIntegration.getUnit()).getDescription();
                        long id = insertAlarmAndDetail(level, device, thresholdId, offset + unit, ts, AlarmTitleEnum.ALARM_TITLE_TWO.getStatus(), AlarmTypeEnum.ALARM_ONE.getCode());
                        /**最初发送短信模式*/
//                        oldPushSms(device,level,thresholdId);
                        /**目前发送短信模式*/
                        String mountainId = device.getMountainId();
                        List<KwsAlarmInfo> list = alarmInfoRepository.list(new LambdaQueryWrapper<KwsAlarmInfo>()
                                .eq(KwsAlarmInfo::getMountainId, mountainId)
                                .eq(KwsAlarmInfo::getLevel, level.intValue())
                                .eq(KwsAlarmInfo::getType, NumberConstant.ONE)
                                .eq(KwsAlarmInfo::getDelFlag, NumberConstant.ZERO)
                        );
                        List<String> pushToPhone = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(list)) {
                            pushToPhone = list.stream().map(KwsAlarmInfo::getValueDesc).distinct().collect(Collectors.toList());
                        }
                        if (!CollectionUtils.isEmpty(pushToPhone)) {
                            LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
                            time = DateUtil.format(localDateTime, "yyyy-MM-dd HH:mm:ss");
                            Map<String, String> templateParam = new HashMap<>();
                            if (StringUtils.isBlank(time)) {
                                LocalDateTime localDateTimes = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
                                time = com.sckw.excel.utils.DateUtil.format(localDateTimes);
                            }
                            templateParam.put("time", time);
                            templateParam.put("level", AlarmLevelEnum.getChineseName(level.intValue()));
                            templateParam.put("name", device.getName());
//                            templateParam.put("value", itemValueAndUnit);
                            unit = dictByDictCode.get(deviceIntegration.getUnit()) == null ? deviceIntegration.getUnit() : dictByDictCode.get(deviceIntegration.getUnit()).getDescription();
                            BigDecimal bd = new BigDecimal(offset);
                            bd = bd.setScale(2, RoundingMode.HALF_UP);
                            templateParam.put("value", String.valueOf(bd) + unit);
                            if (pushToPhone.size() > 0) {
                                commonService.pushSmsMessage(pushToPhone
                                        , smsTemplateConfig.getDataAlarm().getSmsCode()
                                        , smsTemplateConfig.getDataAlarm().getSignName()
                                        , templateParam);
                            }
                        }
                        ProjectVo vo = projectDeviceMapper.selectProjectByDeviceId(device.getId());
                        /**邮件推送*/
                        List<KwsAlarmInfo> emailList = alarmInfoRepository.list(new LambdaQueryWrapper<KwsAlarmInfo>()
                                .eq(KwsAlarmInfo::getMountainId, mountainId)
                                .eq(KwsAlarmInfo::getLevel, level.intValue())
                                .eq(KwsAlarmInfo::getType, NumberConstant.TWO)
                                .eq(KwsAlarmInfo::getDelFlag, NumberConstant.ZERO)
                        );
                        List<String> emailAddress = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(emailList)) {
                            emailAddress = emailList.stream().map(KwsAlarmInfo::getValueDesc).distinct().collect(Collectors.toList());
                        }
                        if (!CollectionUtils.isEmpty(emailAddress)) {
                            Map<String, String> templateParam = new HashMap<>();
                            if (StringUtils.isBlank(time)) {
                                LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
                                time = com.sckw.excel.utils.DateUtil.format(localDateTime);
                            }
                            templateParam.put("company", smsTemplateConfig.getDataAlarm().getSignName());
                            templateParam.put("level",AlarmLevelEnum.getName(level.intValue()));
                            templateParam.put("name", device.getName());
                            templateParam.put("time", time);
                            templateParam.put("project", vo == null ? null : vo.getProjectName());
//                            templateParam.put("value", itemValueAndUnit);
                            unit = dictByDictCode.get(deviceIntegration.getUnit()) == null ? deviceIntegration.getUnit() : dictByDictCode.get(deviceIntegration.getUnit()).getDescription();
                            BigDecimal bd = new BigDecimal(offset);
                            bd = bd.setScale(2, RoundingMode.HALF_UP);
//                            DecimalFormat df = new DecimalFormat("#.##");
//                            String formattedNumber = df.format(bd);
                            templateParam.put("value", String.valueOf(bd) + unit);
                            templateParam.put("type", AlarmTitleEnum.ALARM_TITLE_TWO.getName());
                            templateParam.put("element", deviceIntegration.getIntegrationName());
                            commonService.pushHtmlEmailMessage(emailAddress
                                    , templateParam, "设备告警通知邮件");
                        }
                    }
                }
            }
        }
    }

    private void oldPushSms(KwsDevice device, Long level, Long thresholdId) {
        Map<String, Object> messageMap = new HashMap<>();
        Long deviceId = device.getId();
        KwsProjectDevice projectDevice = projectDeviceMapper.selectOne(new LambdaQueryWrapper<KwsProjectDevice>()
                .eq(KwsProjectDevice::getDeviceId, deviceId)
                .eq(KwsProjectDevice::getDelFlag, 0)
                .eq(KwsProjectDevice::getStatus, 0)
                .orderByDesc(KwsProjectDevice::getCreateTime)
                .last(" limit 1")
        );
        LambdaQueryWrapper<KwsAlarm> wrapper = new LambdaQueryWrapper<KwsAlarm>()
                .eq(KwsAlarm::getLevel, level.intValue())
                .eq(KwsAlarm::getDeviceId, deviceId)
                .eq(KwsAlarm::getType, NumberConstant.ONE)
                .orderByDesc(KwsAlarm::getCreateTime);
        if (projectDevice != null) {
            wrapper.eq(KwsAlarm::getProjectId, projectDevice.getProjectId())
                    .eq(KwsAlarm::getMountainId, projectDevice.getMountainId());
            if (projectDevice.getProjectId() != null) {
                wrapper.eq(KwsAlarm::getCompanyId, projectDevice.getCompanyId());
            }
        }
        KwsThreshold kwsThreshold = thresholdMapper.selectById(thresholdId);
        String phones = kwsThreshold.getPhones();
        List<String> pushToPhone = com.sckw.core.utils.StringUtils.splitStrToList(phones, String.class);
    }


    private void checkDeviceAlarm(String deviceCode, KwsDevice device, String itemValue, Long ts) {
        try {
            Devices devices = tdengineService.selectLastData(device.getSnCode());
            if (devices != null) {
                Date deviceTime = devices.getTs();
                Date date = new Date();
                long diff = Math.abs(date.getTime() - deviceTime.getTime());
                long diffHours = diff / (60 * 60 * 1000) % 24;
                if (diffHours > 24) {
                    long id = insertAlarmAndDetail(1L, device, device.getId(), itemValue, ts, AlarmTitleEnum.ALARM_TITLE_ONE.getStatus(), AlarmTypeEnum.ALARM_TWO.getCode());
                    // todo 暂未设备告警电话，设备告警不推送短信
                    device.setOnline(1);
                    deviceMapper.updateById(device);
                } else {
                    device.setOnline(0);
                    deviceMapper.updateById(device);
                }
            }
        } catch (Exception e) {
            log.error("判断是否满足设备超时离线报警 error ", e.getMessage(), e);
        }
    }

    @Autowired
    KwsAlarmMapper alarmMapper;

    @Autowired
    KwsAlarmDetailMapper alarmDetailMapper;

    @Autowired
    KwsDeviceRelationMapper deviceRelationMapper;

    @Autowired
    KwsProjectDeviceMapper projectDeviceMapper;

    @Autowired
    KwsDeviceReferenceMapper deviceReferenceMapper;

    @Autowired
    private TdengineService tdengineService;


    private Map<String, String> checkThresholdAlarm(DevicesItem devicesItem, List<KwsThreshold> kwsThresholds, KwsDevice device) {
        String itemName = devicesItem.getItemName();
        String itemValue = devicesItem.getItemValue();
        Long deviceId = device.getId();
        KwsDeviceReference deviceRelation = deviceReferenceMapper.selectOne(new LambdaQueryWrapper<KwsDeviceReference>()
                .eq(KwsDeviceReference::getDeviceId, deviceId)
                .eq(KwsDeviceReference::getDelFlag, NumberConstant.ZERO)
                .eq(KwsDeviceReference::getType, "1")
                .eq(KwsDeviceReference::getItem, itemName)
        );
        /**x、y、z要进行偏移量计算  其他数值保持源数据进行计算*/
        List<String> checkItemName = new ArrayList<>();
        checkItemName.add(DictItemEnum.ALTITUDE_Z.getValue());
        checkItemName.add(DictItemEnum.LONGITUDE_X.getValue());
        checkItemName.add(DictItemEnum.LATITUDE_Y.getValue());
        //放入告警数值-告警等级
        //放入告警等级-告警主键id
        Map<String, String> map = new HashMap<>();
        Map<String, SystemDict> dictByDictCode = commonService.getDictByDictCode(DictEnum.MODEL_PART);
        if (checkItemName.contains(itemName)) {
            BigDecimal offset = commonService.computeOffset(itemValue, itemName, deviceRelation);
            map = newAlarmCompute(offset, kwsThresholds);
            String url = dictByDictCode.get(itemName) == null ? null : dictByDictCode.get(itemName).getUrl();
            map.put("offset", String.valueOf(offset.setScale(2, RoundingMode.HALF_UP)) + url);
        } else {
            map = newAlarmCompute(new BigDecimal(itemValue), kwsThresholds);
            String remarkUnit = dictByDictCode.get(itemName) == null ? null : dictByDictCode.get(itemName).getRemark();
            map.put("offset", itemValue + remarkUnit);
        }
//        map = oldAlarmCompute(checkItemName, itemName, itemValue, deviceRelation, kwsThresholds);
        return map;
    }

    /**
     * 之前的阈值告警计算方式
     */
    private Map<String, String> oldAlarmCompute(List<String> checkItemName, String itemName, String itemValue, KwsDeviceReference deviceRelation, List<KwsThreshold> kwsThresholds) {
        //需要计算的阈值
        if (checkItemName.contains(itemName)) {
            BigDecimal offset = commonService.computeOffset(itemValue, itemName, deviceRelation);
            Map<String, Long> maxMap = new HashMap<>();
            Map<String, Long> minMap = new HashMap<>();
            List<BigDecimal> maxList = new ArrayList<>();
            List<BigDecimal> minList = new ArrayList<>();
            //添加阈值map
            for (KwsThreshold kwsThreshold : kwsThresholds) {
                String max = kwsThreshold.getMax();
                Long thresholdId = kwsThreshold.getId();
                String min = kwsThreshold.getMin();
                Integer level = kwsThreshold.getLevel();
                maxMap.put(max, level.longValue());
                maxMap.put(level.toString(), thresholdId.longValue());
                minMap.put(min, level.longValue());
                minMap.put(level.toString(), thresholdId.longValue());
            }
            for (KwsThreshold kwsThreshold : kwsThresholds) {
                maxList.add(new BigDecimal(kwsThreshold.getMax()));
                minList.add(new BigDecimal(kwsThreshold.getMin()));
                String max = kwsThreshold.getMax();
                Long thresholdId = kwsThreshold.getId();
                String min = kwsThreshold.getMin();
                Integer level = kwsThreshold.getLevel();
                /**为了获取最阈值等级*/
                if (maxMap.get(max) != null) {
                    Long integer = maxMap.get(max);
                    if (integer <= level) {
                        maxMap.put(max, level.longValue());
                        maxMap.put(level.toString(), thresholdId.longValue());
                    }
                }
                if (minMap.get(min) != null) {
                    Long integer = minMap.get(min);
                    if (integer <= level) {
                        minMap.put(min, level.longValue());
                        minMap.put(level.toString(), thresholdId.longValue());
                    }
                }
            }
//        minList = minList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            minList = minList.stream().sorted().distinct().collect(Collectors.toList());
            maxList = maxList.stream().sorted(Comparator.reverseOrder()).distinct().collect(Collectors.toList());
            /**计算阈值界限*/
            BigDecimal max = getMaxNumber(offset, maxList);
            BigDecimal min = getMinNumber(offset, minList);
            /**存在阈值触发*/
            Map<String, String> map = new HashMap<>();
            map.put("level", "1");
            map.put("thresholdId", "1");
            map.put("flag", "1");
            if (min != null || max != null) {
                if (max != null) {
                    Long level = maxMap.get(max.toString());
                    Long thresholdId = maxMap.get(level.toString());
                    map.put("level", level.toString());
                    map.put("thresholdId", thresholdId.toString());
                    map.put("flag", "2");
//                    insertAlarmAndDetail(level, device, thresholdId, itemValue, ts);
                }
                if (min != null) {
                    Long level = minMap.get(min.toString());
                    Long thresholdId = minMap.get(level.toString());
                    map.put("level", level.toString());
                    map.put("thresholdId", thresholdId.toString());
                    map.put("flag", "2");
                }
            }
            return map;
        } else {
            //直接阈值计算的处理
            Map<String, Long> maxMap = new HashMap<>();
            Map<String, Long> minMap = new HashMap<>();
            List<BigDecimal> maxList = new ArrayList<>();
            List<BigDecimal> minList = new ArrayList<>();
            for (KwsThreshold kwsThreshold : kwsThresholds) {
                String max = kwsThreshold.getMax();
                Long thresholdId = kwsThreshold.getId();
                String min = kwsThreshold.getMin();
                Integer level = kwsThreshold.getLevel();
                maxMap.put(max, level.longValue());
                maxMap.put(level.toString(), thresholdId.longValue());
                minMap.put(min, level.longValue());
                minMap.put(level.toString(), thresholdId.longValue());
            }
            for (KwsThreshold kwsThreshold : kwsThresholds) {
                maxList.add(new BigDecimal(kwsThreshold.getMax()));
                minList.add(new BigDecimal(kwsThreshold.getMin()));
                String max = kwsThreshold.getMax();
                Long thresholdId = kwsThreshold.getId();
                String min = kwsThreshold.getMin();
                Integer level = kwsThreshold.getLevel();
                /**为了获取最阈值等级*/
                if (maxMap.get(max) != null) {
                    Long integer = maxMap.get(max);
                    if (integer <= level) {
                        maxMap.put(max, level.longValue());
                        maxMap.put(level.toString(), thresholdId.longValue());
                    }
                }
                if (minMap.get(min) != null) {
                    Long integer = minMap.get(min);
                    if (integer <= level) {
                        minMap.put(min, level.longValue());
                        minMap.put(level.toString(), thresholdId.longValue());
                    }
                }
            }
//        minList = minList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            minList = minList.stream().sorted().distinct().collect(Collectors.toList());
            maxList = maxList.stream().sorted().distinct().collect(Collectors.toList());
            /**计算阈值界限*/
            BigDecimal max = getMaxNumber(new BigDecimal(itemValue), maxList);
            BigDecimal min = getMinNumber(new BigDecimal(itemValue), minList);
            /**存在阈值触发*/
            Map<String, String> map = new HashMap<>();
            map.put("level", "1");
            map.put("thresholdId", "1");
            map.put("flag", "1");
            if (min != null && max != null) {
                if (max != null) {
                    Long level = maxMap.get(max);
                    Long thresholdId = maxMap.get(level.toString());
                    map.put("level", level.toString());
                    map.put("thresholdId", thresholdId.toString());
                    map.put("flag", "2");
//                    insertAlarmAndDetail(level, device, thresholdId, itemValue, ts);
                }
                if (min != null) {
                    Long level = minMap.get(min);
                    Long thresholdId = minMap.get(level.toString());
                    map.put("level", level.toString());
                    map.put("thresholdId", thresholdId.toString());
                    map.put("flag", "2");
                }
            }
            return map;
        }
    }

    private Map<String, String> newAlarmCompute(BigDecimal offset, List<KwsThreshold> kwsThresholds) {
        //最大值从大到小计算 告警阈值
        List<AlarmList> maxAlarmList = new ArrayList<>();
        for (KwsThreshold kwsThreshold : kwsThresholds) {
            if (kwsThreshold.getMax() != null) {
                AlarmList alarmList = new AlarmList();
                alarmList.setLevel(kwsThreshold.getLevel().toString());
                alarmList.setId(kwsThreshold.getId());
                alarmList.setValue(new BigDecimal(kwsThreshold.getMax()));
                maxAlarmList.add(alarmList);
            }
        }
        //最小值从小到大计算 告警阈值
        List<AlarmList> minAlarmList = new ArrayList<>();
        for (KwsThreshold kwsThreshold : kwsThresholds) {
            if (kwsThreshold.getMin() != null) {
                AlarmList alarmList = new AlarmList();
                alarmList.setLevel(kwsThreshold.getLevel().toString());
                alarmList.setId(kwsThreshold.getId());
                alarmList.setValue(new BigDecimal(kwsThreshold.getMin()));
                minAlarmList.add(alarmList);
            }
        }
        maxAlarmList = maxAlarmList.stream().sorted(Comparator.comparing(AlarmList::getValue).reversed()).collect(Collectors.toList());
//            HashMap<Object, Object> maxAlarmMap = kwsThresholds.stream().collect(HashMap::new,
//                    (m, v) -> m.put(v.getMax(), v.getId()), HashMap::putAll);
        minAlarmList = minAlarmList.stream().sorted(Comparator.comparing(AlarmList::getValue)).collect(Collectors.toList());
//            HashMap<Object, Object> mixAlarmMap = kwsThresholds.stream().collect(HashMap::new,
//                    (m, v) -> m.put(v.getMax(), v.getId()), HashMap::putAll);
        String maxLevel = getListMaxNumber(offset, maxAlarmList);
        String minLevel = getListMinNumber(offset, minAlarmList);
        /**存在阈值触发*/
        Map<String, String> map = new HashMap<>();
        map.put("level", "1");
        map.put("thresholdId", "1");
        map.put("flag", "1");
        if (maxLevel != null || minLevel != null) {
            if (maxLevel != null) {
                for (AlarmList alarmList : maxAlarmList) {
                    if (maxLevel.equals(alarmList.getLevel())) {
                        map.put("level", maxLevel);
                        map.put("thresholdId", alarmList.getId().toString());
                        map.put("flag", "2");
                    }
                }
            }
            if (minLevel != null) {
                for (AlarmList alarmList : maxAlarmList) {
                    if (minLevel.equals(alarmList.getLevel())) {
                        map.put("level", minLevel);
                        map.put("thresholdId", alarmList.getId().toString());
                        map.put("flag", "2");
                    }
                }
            }
        }
        return map;
    }

    /**
     * 保存阈值主表以及明细表
     *
     * @param level       阈值等级
     * @param device      设备
     * @param thresholdId 阈值id/设备id
     * @param itemValue   td数据当时检测值
     * @param ts          td时间
     * @param alarmTitle  设备类型明细
     * @param type        设备类型
     */
    @Transactional
    public long insertAlarmAndDetail(Long level, KwsDevice device, Long thresholdId,
                                     String itemValue, Long ts,
                                     String alarmTitle, Integer type
    ) {
        Long deviceId = device.getId();
//        KwsProjectDevice projectDevice = projectDeviceMapper.selectOne(new LambdaQueryWrapper<KwsProjectDevice>()
//                .eq(KwsProjectDevice::getDeviceId, deviceId)
//                .eq(KwsProjectDevice::getDelFlag, 0)
//                .orderByDesc(KwsProjectDevice::getCreateTime)
//                .last(" limit 1")
//        );
        KwsProjectDevice projectDevice = projectDeviceMapper.selectProjectDeviceByDeviceId(deviceId);
        //新增未读数据
        long alarmId = insertUnread(level, device, thresholdId, itemValue, ts, alarmTitle, type, deviceId, projectDevice);
        //新增历史数据
        insertHistoryRead(level, device, thresholdId, itemValue, ts, alarmTitle, type, deviceId, projectDevice);

        return alarmId;
    }

    public void insertHistoryRead(Long level, KwsDevice device, Long thresholdId, String itemValue, Long ts, String alarmTitle, Integer type, Long deviceId, KwsProjectDevice projectDevice) {
        LambdaQueryWrapper<KwsAlarm> wrapper = new LambdaQueryWrapper<KwsAlarm>()
                .eq(KwsAlarm::getStatus, NumberConstant.ONE)
                .eq(KwsAlarm::getType, type)
                .eq(KwsAlarm::getLevel, level.intValue())
                .eq(KwsAlarm::getDeviceId, deviceId)
                .eq(KwsAlarm::getIsHistory, 1)
                .eq(KwsAlarm::getTitle, alarmTitle)
                .eq(KwsAlarm::getDelFlag, 0)
                .orderByDesc(KwsAlarm::getCreateTime);
        if (projectDevice != null) {
            wrapper.eq(Objects.nonNull(projectDevice.getProjectId()), KwsAlarm::getProjectId, projectDevice.getProjectId())
                    .eq(StringUtils.isNotBlank(device.getMountainId()), KwsAlarm::getMountainId, projectDevice.getMountainId());
            if (projectDevice.getProjectId() != null) {
                wrapper.eq(StringUtils.isNotBlank(projectDevice.getCompanyId()), KwsAlarm::getCompanyId, projectDevice.getCompanyId());
            }
        }
        long alarmId = new IdWorker(NumberConstant.ONE).nextId();
        KwsAlarm alarms = alarmMapper.selectOne(wrapper);
        if (alarms == null) {
            KwsAlarm alarm = new KwsAlarm();
            String mountainId = device == null ? null : device.getMountainId();
            String companyId = projectDevice == null ? null : projectDevice.getCompanyId();
            String projectId = projectDevice == null ? null :
                    (projectDevice.getProjectId() == null ? null : projectDevice.getProjectId().toString());
            alarm.setId(alarmId);
            alarm.setCompanyId(companyId);
            alarm.setMountainId(mountainId);
            alarm.setProjectId(projectId);
            alarm.setDeviceId(deviceId);
            alarm.setTitle(alarmTitle);
            alarm.setLevel(level.intValue());
            alarm.setType(type);
            LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
            alarm.setCreateTime(localDateTime);
            alarm.setUpdateTime(localDateTime);
            alarm.setStatus(1);
            alarm.setTriggerTimes(0);
            alarm.setIsHistory(1);
            alarmMapper.insert(alarm);
        }
    }

    public long insertUnread(Long level, KwsDevice device, Long thresholdId,
                             String itemValue, Long ts,
                             String alarmTitle, Integer type, Long deviceId, KwsProjectDevice projectDevice) {

        long alarmId = new IdWorker(NumberConstant.ONE).nextId();
        KwsAlarm alarms = selectAlarmData(level, deviceId, type, alarmTitle, projectDevice, device);
//        if (!CollectionUtils.isEmpty() && alarms.size() > 1) {
//            //去重
//            checkAlarmData(alarms, level, deviceId, type, alarmTitle, projectDevice);
//        }
//        alarms = selectAlarmData(level, deviceId, type, alarmTitle, projectDevice);
        if (alarms == null) {
            KwsAlarm alarm = new KwsAlarm();
            String mountainId = device == null ? null : device.getMountainId();
            String companyId = projectDevice == null ? null : projectDevice.getCompanyId();
            String projectId = projectDevice == null ? null :
                    (projectDevice.getProjectId() == null ? null : projectDevice.getProjectId().toString());
            alarm.setId(alarmId);
            alarm.setCompanyId(companyId);
            alarm.setMountainId(mountainId);
            alarm.setProjectId(projectId);
            alarm.setDeviceId(deviceId);
            alarm.setTitle(alarmTitle);
            alarm.setLevel(level.intValue());
            alarm.setType(type);
            LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
//            LocalDateTime localDateTime = new Date(ts).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
            alarm.setCreateTime(localDateTime);
            alarm.setUpdateTime(localDateTime);
            alarm.setStatus(0);
            alarm.setTriggerTimes(1);
            alarmMapper.insert(alarm);
            KwsAlarmDetail alarmDetail = new KwsAlarmDetail();
            alarmDetail.setId(new IdWorker(NumberConstant.ONE).nextId());
            alarmDetail.setMountainId(mountainId);
            alarmDetail.setCompanyId(companyId);
            alarmDetail.setAlarmId(alarmId);
            alarmDetail.setPid(thresholdId);
            alarmDetail.setVal(itemValue);
            alarmDetail.setLat(device.getLogicLat());
            alarmDetail.setLng(device.getLogicLng());
            alarmDetail.setAlt(device.getLogicAlt());
            alarmDetail.setCreateTime(localDateTime);
            alarmDetail.setUpdateTime(localDateTime);
            alarmDetail.setStatus(0);
            alarmDetail.setDelFlag(NumberConstant.ZERO);
            alarmDetail.setIsHistory(NumberConstant.ZERO);
            alarmDetailMapper.insert(alarmDetail);
        } else {
            alarmId = alarms.getId();
            KwsAlarm alarm = alarms;
            LocalDateTime localDateTime = Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault()).toLocalDateTime();
//            LocalDateTime localDateTime = new Date(ts).toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
            alarm.setUpdateTime(localDateTime);
            alarm.setStatus(0);
            Long aLong = alarmDetailMapper.selectCount(new LambdaQueryWrapper<KwsAlarmDetail>()
                    .eq(KwsAlarmDetail::getAlarmId, alarmId)
                    .eq(KwsAlarmDetail::getStatus, 0)
                    .eq(KwsAlarmDetail::getIsHistory, 0)
                    .eq(KwsAlarmDetail::getDelFlag, 0)
            );
            alarm.setTriggerTimes(aLong.intValue() + 1);
            alarmMapper.updateById(alarm);
            String mountainId = device == null ? null : device.getMountainId();
            String companyId = projectDevice == null ? null : projectDevice.getCompanyId();
            String projectId = projectDevice == null ? null :
                    (projectDevice.getProjectId() == null ? null : projectDevice.getProjectId().toString());
            KwsAlarmDetail alarmDetail = new KwsAlarmDetail();
            alarmDetail.setId(new IdWorker(NumberConstant.TWO).nextId());
            alarmDetail.setMountainId(mountainId);
            alarmDetail.setCompanyId(companyId);
            alarmDetail.setAlarmId(alarm.getId());
            alarmDetail.setPid(thresholdId);
            alarmDetail.setVal(itemValue);
            alarmDetail.setLat(device.getLogicLat());
            alarmDetail.setLng(device.getLogicLng());
            alarmDetail.setAlt(device.getLogicAlt());
            alarmDetail.setCreateTime(localDateTime);
            alarmDetail.setUpdateTime(localDateTime);
            alarmDetail.setStatus(0);
            alarmDetail.setDelFlag(NumberConstant.ZERO);
            alarmDetail.setIsHistory(NumberConstant.ZERO);
            alarmDetailMapper.insert(alarmDetail);
        }
        return alarmId;
    }

    private KwsAlarm selectAlarmData(Long level, Long deviceId, Integer type, String alarmTitle, KwsProjectDevice projectDevice, KwsDevice device) {
        LambdaQueryWrapper<KwsAlarm> wrapper = new LambdaQueryWrapper<KwsAlarm>()
                .eq(KwsAlarm::getLevel, level.intValue())
                .eq(KwsAlarm::getDeviceId, deviceId)
                .eq(KwsAlarm::getStatus, NumberConstant.ZERO)
                .eq(KwsAlarm::getType, type)
                .eq(KwsAlarm::getTitle, alarmTitle)
                .eq(KwsAlarm::getIsHistory, NumberConstant.ZERO)
                .eq(KwsAlarm::getDelFlag, NumberConstant.ZERO)
                .orderByDesc(KwsAlarm::getCreateTime);
        if (projectDevice != null) {
            wrapper.eq(Objects.nonNull(projectDevice.getProjectId()), KwsAlarm::getProjectId, projectDevice.getProjectId())
                    .eq(StringUtils.isNotBlank(device.getMountainId()), KwsAlarm::getMountainId, device.getMountainId());
            if (projectDevice.getProjectId() != null) {
                wrapper.eq(StringUtils.isNotBlank(projectDevice.getCompanyId()), KwsAlarm::getCompanyId, projectDevice.getCompanyId());
            }
        }
        KwsAlarm kwsAlarm = null;
        List<KwsAlarm> alarms = alarmMapper.selectList(wrapper);
        if (alarms.size() > 0) {
            kwsAlarm = alarms.get(0);
        }
        return kwsAlarm;
    }

    private void checkAlarmData(List<KwsAlarm> alarms, Long level, Long deviceId, Integer type, String alarmTitle, KwsProjectDevice projectDevice) {
        for (KwsAlarm alarm : alarms) {
            List<KwsAlarmDetail> details = alarmDetailMapper.selectList(new LambdaQueryWrapper<KwsAlarmDetail>().eq(KwsAlarmDetail::getAlarmId, alarm.getDeviceId()));
            if (org.springframework.util.CollectionUtils.isEmpty(details) && details.size() == 0) {
                alarm.setDelFlag(1);
                alarmMapper.updateById(alarm);
            }
        }
        LambdaQueryWrapper<KwsAlarm> wrapper = new LambdaQueryWrapper<KwsAlarm>()
                .eq(KwsAlarm::getLevel, level.intValue())
                .eq(KwsAlarm::getDeviceId, deviceId)
                .eq(KwsAlarm::getStatus, NumberConstant.ZERO)
                .eq(KwsAlarm::getType, type)
                .eq(KwsAlarm::getTitle, alarmTitle)
                .eq(KwsAlarm::getIsHistory, NumberConstant.ZERO)
                .eq(KwsAlarm::getDelFlag, NumberConstant.ZERO)
                .orderByDesc(KwsAlarm::getCreateTime);
        if (projectDevice != null) {
            wrapper.eq(KwsAlarm::getProjectId, projectDevice.getProjectId())
                    .eq(KwsAlarm::getMountainId, projectDevice.getMountainId());
            if (projectDevice.getProjectId() != null) {
                wrapper.eq(KwsAlarm::getCompanyId, projectDevice.getCompanyId());
            }
        }
    }

    /**
     * 计算最小值
     *
     * @param number
     * @param list
     * @return
     */
    private static BigDecimal getMinNumber(BigDecimal number, List<BigDecimal> list) {
        for (BigDecimal decimal : list) {
            if (number.compareTo(decimal) < 0) {
                return decimal;
            }
        }
        return null;
    }

    private static BigDecimal getMaxNumber(BigDecimal number, List<BigDecimal> list) {
        for (BigDecimal decimal : list) {
            if (number.compareTo(decimal) > 0) {
                return decimal;
            }
        }
        return null;
    }

    private static String getListMaxNumber(BigDecimal number, List<AlarmList> alarmLists) {
        for (AlarmList list : alarmLists) {
            if (number.compareTo(list.getValue()) > 0) {
                return list.getLevel();
            }
        }
        return null;
    }

    /**
     * 计算最小值
     *
     * @param number
     * @param alarmLists
     * @return
     */
    private static String getListMinNumber(BigDecimal number, List<AlarmList> alarmLists) {
        for (AlarmList list : alarmLists) {
            if (number.compareTo(list.getValue()) < 0) {
                return list.getLevel();
            }
        }
        return null;
    }

    public static void main(String[] args) {
        String s = "2023-11-30 22:00:00";
        Date date = DateUtils.formatDate(s);
        long time1 = date.getTime();
        long ts = 1700970600l;
        Instant timestamp = Instant.ofEpochSecond(ts);

        ts = ts * 1000;
        Instant instant = new Date(ts).toInstant();
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.of("+8"));
        LocalDateTime timeLocalDateTime = offsetDateTime.toLocalDateTime();

        instant = Instant.ofEpochMilli(ts);
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
        LocalDateTime localDateTimes = zonedDateTime.toLocalDateTime();
        System.out.println(localDateTimes);

        String aaa = "{\"ts\":1700808976,\"guid\":\"0838161D-4C64-EC3E-A3A8-C736C47D93D4\",\"tslver_id\":\"3\",\"msg_id\":\"586569123094614016\",\"raw_ts\":\"\",\"check_arr\":[{\"itemName\":\"lng\",\"itemValue\":\"103.51826198069217\"},{\"itemName\":\"lat\",\"itemValue\":\"29.46725728245242\"},{\"itemName\":\"high\",\"itemValue\":\"710.1730218537282\"},{\"itemName\":\"fix\",\"itemValue\":4015},{\"itemName\":\"e\",\"itemValue\":\"302.7644742928626\"},{\"itemName\":\"n\",\"itemValue\":\"711.0632664506148\"},{\"itemName\":\"u\",\"itemValue\":\"-271.97856155098333\"},{\"itemName\":\"num\",\"itemValue\":7200},{\"itemName\":\"time\",\"itemValue\":\"2023-11-0818:00:00\"}]}";
        DevicesAlarm alarm = new DevicesAlarm();
        List<DevicesItem> list = new ArrayList<>();
        DevicesItem item = new DevicesItem();
        item.setItemName("alt");
        item.setItemValue("20.12646584");
        long time = new Date().getTime();
        String md5 = new MD5Utils().getMd5(String.valueOf(time));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        list.add(item);
        alarm.setDevicesItemList(list);
        String demoTest = "{\"deviceCode\":\"s8\",\"devicesItemList\":[{\"guid\":\"c7653b298bec06eb78be3140b5c2ea9b\",\"itemName\":\"alt\",\"itemValue\":\"20.12646584\",\"msg_id\":\"2023-11-18 14:49:06\",\"raw_ts\":\"2023-11-18 14:49:06\",\"ts\":1700290146508,\"tslver_Id\":\"2023-11-18 14:49:06\"}]}";
        System.out.println("alarm:" + JSONObject.toJSONString(alarm));
        List<BigDecimal> maxList = new ArrayList<>();
        maxList.add(new BigDecimal("52"));
        maxList.add(new BigDecimal("40"));
        maxList.add(new BigDecimal("35"));
        List<BigDecimal> minList = new ArrayList<>();
        minList.add(new BigDecimal("30"));
        minList.add(new BigDecimal("26"));
        minList.add(new BigDecimal("10"));
        minList = minList.stream().sorted().distinct().collect(Collectors.toList());
        maxList = maxList.stream().sorted().distinct().collect(Collectors.toList());
        BigDecimal max = getMaxNumber(new BigDecimal("38"), maxList);
        System.out.println(max);
        BigDecimal min = getMinNumber(new BigDecimal("8"), minList);
        System.out.println(min);
    }
}

