package com.zcxk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcxk.common.StringUtils;
import com.zcxk.dao.OnlineMonitorMapper;
import com.zcxk.dto.*;
import com.zcxk.entity.MonitorDataEntity;
import com.zcxk.entity.MonitorDataValueEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.model.Pagination;
import com.zcxk.service.DeviceAttributeSpecsService;
import com.zcxk.service.OnlineMonitorService;
import com.zcxk.util.*;
import com.zcxk.vo.AlarmDetailsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description
 * @auto yjy
 * @data 2020-12-2
 */
@Service
public class OnlineMonitorImpl implements OnlineMonitorService {

    @Resource
    private OnlineMonitorMapper onlineMonitorMapper;
    @Autowired
    private DeviceAttributeSpecsService deviceAttributeSpecsService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private OrgInfoUtil orgInfoUtil;
    @Autowired
    private MonitorDataReportServiceImpl monitorDataReportServiceImpl;
    /**
     * 查询实时报警信息
     * @return
     */
    @Override
    public List<AlarmDetailsDto> selectAlarmDetails(AlarmDetailsDto alarmDetailsDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        alarmDetailsDto.setTenantId(loginUser.getTenantId());
        alarmDetailsDto.setProgramItems(loginUser.getProgramItemList());
        alarmDetailsDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        alarmDetailsDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectAlarmDetails(alarmDetailsDto);
    }
    /**
     * 查询实时报警数量
     * @return
     */
    @Override
    public List<Map<String, Object>> selectAlarmCount(AlarmDetailsDto alarmDetailsDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        alarmDetailsDto.setTenantId(loginUser.getTenantId());
        alarmDetailsDto.setProgramItems(loginUser.getProgramItemList());
        alarmDetailsDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        alarmDetailsDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectAlarmCount(alarmDetailsDto);
    }
    /**
     * 查询地图悬浮数据
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> selectMapSuspension(MonitorDataCollectDto monitorDataCollectDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(3);
        List<MonitorDataCollectDto> result = onlineMonitorMapper.selectMapSuspension(monitorDataCollectDto);
        if (!StringUtils.isEmpty(monitorDataCollectDto.getSceneTypeName())) {
            monitorDataCollectDto.setType(1);
            List<MonitorDataCollectDto> calculateRes = onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);
            GetCalMonitorData(result, calculateRes);
            //按水量倒序排序 如果是水源按照取水量排序，其他按照供水量
            if(monitorDataCollectDto.getSceneTypeName().equals("水源")){
                result.sort(Comparator.comparing(MonitorDataCollectDto::getIntakeWaterUsage,Comparator.nullsFirst(Double::compareTo)).reversed());
            }else{
                result.sort(Comparator.comparing(MonitorDataCollectDto::getYieldWaterUsage,Comparator.nullsFirst(Double::compareTo)).reversed());
            }
        }else{
            GetCalMonitorData(result, new ArrayList<>());
        }
        return result;
    }
    /**
     * 查询地图悬浮数据
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> selectMapSuspensionForMonth(MonitorDataCollectDto monitorDataCollectDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(3);
        List<MonitorDataCollectDto> result = onlineMonitorMapper.selectSceneParamForLastMonth(monitorDataCollectDto);

        for(MonitorDataCollectDto mon:result){
            BigDecimal yieldWaterUsage=monitorDataReportServiceImpl.getAmountCount(null,mon.getSceneId().intValue(),"泵站",3,2);
            mon.setYieldWaterUsage(yieldWaterUsage.doubleValue());
        }


        //按水量倒序排序 如果是水源按照取水量排序，其他按照供水量
//        result.sort(new Comparator<MonitorDataCollectDto>() {
//            @Override
//            public int compare(MonitorDataCollectDto o1, MonitorDataCollectDto o2) {
//                Double d1 = monitorDataCollectDto.getSceneTypeName().equals("水源") ? (o1.getIntakeWaterUsage() == null ? 0d : o1.getIntakeWaterUsage()) : (o1.getYieldWaterUsage() == null ? 0d : o1.getYieldWaterUsage());
//                Double d2 = monitorDataCollectDto.getSceneTypeName().equals("水源") ? (o2.getIntakeWaterUsage() == null ? 0d : o2.getIntakeWaterUsage()) : (o2.getYieldWaterUsage() == null ? 0d : o2.getYieldWaterUsage());
//                if (d1 > d2) {
//                    return -1;
//                }
//                return 0;
//            }
//        });
        result.sort(Comparator.comparing(MonitorDataCollectDto::getYieldWaterUsage,Comparator.nullsFirst(Double::compareTo)).reversed());

        return result;
    }
    /**
     * 查询地图参数数据
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> selectMapParam(MonitorDataCollectDto monitorDataCollectDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(4);
        List<MonitorDataCollectDto> result=onlineMonitorMapper.selectMapParam(monitorDataCollectDto);
        monitorDataCollectDto.setType(1);
        List<MonitorDataCollectDto> calculateRes=onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);

        GetCalMonitorData(result,calculateRes);
        return result;
    }
    /**
     * 分页查询
     * @return
     */
    @Override
    public IPage<OnlineDataDto> selectPage(IPage<OnlineDataDto> page, OnlineDataDto onlineDataDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        IPage<OnlineDataDto> iPage =onlineMonitorMapper.selectPage(page,onlineDataDto);
        Pagination<OnlineDataDto> pages = new Pagination<>(iPage);
        MonitorDataCollectDto monitorDataCollectDto=new MonitorDataCollectDto();
        List<Long> sceneIds = pages.getList().stream().map(OnlineDataDto::getSceneId).collect(Collectors.toList());
        monitorDataCollectDto.setType(2);
        monitorDataCollectDto.setSceneIds(sceneIds);
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        List<MonitorDataCollectDto> calculateRes=onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);

        GetCalOnlineData(pages.getList(),calculateRes);//获取在线数据及计算数据
        return iPage;
    }
    /**
     * 查询设备报警分析
     * @return
     */
    @Override
    public List<Map<String, Object>> selectAlarmStats(AlarmDetailsDto alarmDetailsDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        alarmDetailsDto.setTenantId(loginUser.getTenantId());
        alarmDetailsDto.setProgramItems(loginUser.getProgramItemList());
        alarmDetailsDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        alarmDetailsDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectAlarmStats(alarmDetailsDto);
    }
    /**
     * 查询场景对应参数数据
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> selectSceneParam(MonitorDataCollectDto monitorDataCollectDto){
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);
    }
    /**
     * 按管网名称分类查询设备数量
     * @return
     */
    @Override
    public List<Map<String, Object>> selectDeviceCount(OnlineDataDto onlineDataDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectDeviceCount(onlineDataDto);
    }

    /**
     * 查询设备地图参数数据
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> selectDeviceMapParam(MonitorDataCollectDto monitorDataCollectDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        List<MonitorDataCollectDto> result=onlineMonitorMapper.selectDeviceMapParam(monitorDataCollectDto);
        GetCalMonitorData(result,new ArrayList<MonitorDataCollectDto>());
        return result;
    }
    /**
     * 统计设备合格数据
     * @return
     */
    @Override
    public List<DeviceCountStatsDto> statsDeviceQualified(OnlineDataDto onlineDataDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());
        List<DeviceCountStatsDto> result=onlineMonitorMapper.statsDeviceQualified(onlineDataDto);
        if(!StringUtils.isEmpty(onlineDataDto.getSceneTypeName())&&result.size()>0&&onlineDataDto.getFlag()==null) {
            List<DeviceCountStatsDto> parmResult=onlineMonitorMapper.statsParmQualified(onlineDataDto);
            result.get(0).setParmQualified(parmResult);
            for(DeviceCountStatsDto parm : result.get(0).getParmQualified()){
                parm.setTotalCount(result.get(0).getTotalCount());
                parm.setNormalCount(result.get(0).getTotalCount()-parm.getAlarmCount());
            }
        }
        return result;
    }
    /**
     * 统计今日累计流量
     * @return
     */
    @Override
    public List<MonitorDataCollectDto> statsDeviceFlow(OnlineDataDto onlineDataDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        List<MonitorDataCollectDto> result=onlineMonitorMapper.statsDeviceParm(onlineDataDto);
        GetCalMonitorData(result,result);
        //去掉没有数据的值
        result.removeIf(r->r.getYieldWaterUsage() == null);
        //按水量倒序排序
        result.sort(new Comparator<MonitorDataCollectDto>() {
            @Override
            public int compare(MonitorDataCollectDto o1, MonitorDataCollectDto o2) {
                if(o1.getYieldWaterUsage()!=null&&o2.getYieldWaterUsage()!=null&&
                        o1.getYieldWaterUsage()>o2.getYieldWaterUsage()){
                    return -1;
                }
                return 0;
            }
        });
        return result;
    }
    /**
     * 统计压力、瞬时流量的分布区间
     * @return
     */
    @Override
    public DistributeIntervalDto statsDeviceParmCount(OnlineDataDto onlineDataDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        int[] deviceCount=new int[5];
        int count=0;
        Double sumValue=null,maxValue=null,minValue=null;
        String maxDeviceName=null,minDeviceName=null;
        List<MonitorDataCollectDto> result=onlineMonitorMapper.statsDeviceParm(onlineDataDto);
        for(MonitorDataCollectDto monDataCol :result) {
            //取缓存里的数据
            byte[] bytes = redisUtil.get(("sms_water_" + monDataCol.getDeviceCode()).getBytes());
            MonitorDataEntity monitorDataEntity = null;
            if (bytes != null && bytes.length > 0) {
                monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
            }
            for (MonitorDataDto monitorData : monDataCol.getMonitorDataEntities()) {
                if (monitorDataEntity != null) {
                    monDataCol.setCollectDate(monitorDataEntity.getCollectDate());
                    SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");//日期算换格式
                    //筛选该设备相同属性的值
                    List<MonitorDataValueEntity> attributeEntities = monitorDataEntity.getDataValues().stream().filter((MonitorDataValueEntity m)
                            -> m.getAttributeId().equals(monitorData.getAttributeId())).collect(Collectors.toList());
                    MonitorDataValueEntity attributeEntity = attributeEntities.size() > 0 ? attributeEntities.get(0) : null;
                    if (attributeEntity != null) {
                       Double dataValue= attributeEntity.getDataValue();
                       if(dataValue!=null){
                           if(onlineDataDto.getSceneTypeName().equals("压力")){
                               count++;
                               sumValue=sumValue==null?dataValue:sumValue+dataValue;
                               boolean isMaxEquals=dataValue.equals(maxValue);
                               boolean isMinEquals=dataValue.equals(minValue);
                               if(isMaxEquals) {
                                   maxDeviceName += ","+monDataCol.getDeviceName();
                               }
                               if(isMinEquals){
                                   minDeviceName += ","+monDataCol.getDeviceName();
                               }
                               maxValue=Math.max(maxValue==null?dataValue:maxValue,dataValue);
                               minValue=Math.min(minValue==null?dataValue:minValue,dataValue);
                               if(maxValue.equals(dataValue)&&!isMaxEquals) {
                                   maxDeviceName = monDataCol.getDeviceName();
                               }
                               if(minValue.equals(dataValue)&&!isMinEquals) {
                                   minDeviceName = monDataCol.getDeviceName();
                               }
                               if(dataValue<=0.2){
                                   deviceCount[0]++;
                               }else if(dataValue<=0.25) {
                                   deviceCount[1]++;
                               }else if(dataValue<=0.3) {
                                   deviceCount[2]++;
                               }else if(dataValue<=0.35) {
                                   deviceCount[3]++;
                               }else if(dataValue>0.35) {
                                   deviceCount[4]++;
                               }
                           }else if(onlineDataDto.getSceneTypeName().equals("流量")){
                               if(dataValue<=0){
                                   deviceCount[0]++;
                               }else if(dataValue<=200) {
                                   deviceCount[1]++;
                               }else if(dataValue<=400) {
                                   deviceCount[2]++;
                               }else if(dataValue<=600) {
                                   deviceCount[3]++;
                               }else if(dataValue>600) {
                                   deviceCount[4]++;
                               }
                           }
                       }
                    }
                }
            }
        }
        deviceCount[0]=result.size()-deviceCount[1]-deviceCount[2]-deviceCount[3]-deviceCount[4];
        DistributeIntervalDto distributeIntervalDto=new DistributeIntervalDto();
        distributeIntervalDto.setDistributeValue(deviceCount);
        distributeIntervalDto.setAvgValue(count==0?null:sumValue/count);
        distributeIntervalDto.setMaxValue(maxValue);
        distributeIntervalDto.setMinValue(minValue);
        distributeIntervalDto.setMaxDeviceName(maxDeviceName);
        distributeIntervalDto.setMinDeviceName(minDeviceName);
        return distributeIntervalDto;
    }
    /**
     * 管网分页查询
     * @return
     */
    @Override
    public IPage<OnlineDataDto> selectPipeNetPage(IPage<OnlineDataDto> page, OnlineDataDto onlineDataDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        IPage<OnlineDataDto> iPage =onlineMonitorMapper.selectPipeNetPage(page,onlineDataDto);
        Pagination<OnlineDataDto> pages = new Pagination<>(iPage);

        List<Long> deviceIds = pages.getList().stream().map(OnlineDataDto::getDeviceId).collect(Collectors.toList());
        onlineDataDto.setDeviceIds(deviceIds);
        onlineDataDto.setTenantId(loginUser.getTenantId());
        List<MonitorDataCollectDto> calculateRes=onlineMonitorMapper.statsDeviceParm(onlineDataDto);

        GetCalOnlineData(pages.getList(),calculateRes);//获取在线数据及计算数据
        return iPage;
    }
    /**
     * 查询管网地图图层
     * @return
     */
    @Override
    public  List<PipeNetLayerDto> selectPipeNetLayer(OnlineDataDto onlineDataDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());
        List<PipeNetLayerDto> result=onlineMonitorMapper.selectPipeNetLayer(onlineDataDto);
        for(PipeNetLayerDto pipeNetLayerDto :result){
            GetCalMonitorData(pipeNetLayerDto.getDeviceDataList(), new ArrayList<>());
        }
        return result;
    }

    /**
     * 统计从水源地到水龙头汇总数据
     * @return
     */
    @Override
    public DispatchSummaryDto statsDispatchSummary(MonitorDataCollectDto monitorDataCollectDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(1);
        DispatchSummaryDto result=new DispatchSummaryDto();

        monitorDataCollectDto.setSceneTypeName("水源");
        List<MonitorDataCollectDto> waterHead=onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);
        MonitorDataCollectDto waterHeadRes=GetCalTotalData(waterHead);
        result.setIntakeWaterUsage(waterHeadRes.getIntakeWaterUsage());

        monitorDataCollectDto.setSceneTypeName("水厂");
        List<MonitorDataCollectDto> waterWorks=onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);
        MonitorDataCollectDto waterWorksRes=GetCalTotalData(waterWorks);
        result.setYieldWaterUsage(waterWorksRes.getYieldWaterUsage());
        result.setPowerUsage(waterWorksRes.getPowerUsage());

        Double invName=onlineMonitorMapper.selectTotalYieldWater(monitorDataCollectDto);
        result.setInvNameRate(invName!=null&&waterWorksRes.getYieldWaterUsage()!=null?waterWorksRes.getYieldWaterUsage()/invName*100:null);

        OnlineDataDto onlineDataDto=new OnlineDataDto();
        onlineDataDto.setSceneTypeName("压力");
        onlineDataDto.setSceneIds(monitorDataCollectDto.getSceneIds());
        List<DeviceCountStatsDto> pres=statsDeviceQualified(onlineDataDto);
        result.setPresQualifiedRate(pres.size()>0&&pres.get(0).getTotalCount()!=0&&pres.get(0).getParmQualified().size()>0?
                (double)pres.get(0).getParmQualified().get(0).getNormalCount()/pres.get(0).getTotalCount()*100:100);

        onlineDataDto.setSceneTypeName("水质");
        List<DeviceCountStatsDto> water=statsDeviceQualified(onlineDataDto);
        result.setWaterQualifiedRate(water.size()>0&&water.get(0).getTotalCount()!=0?(double)water.get(0).getNormalCount()/water.get(0).getTotalCount()*100:100);

        //售水量造假 产销差率30%~40%
        if(result.getYieldWaterUsage()!=null){
            result.setNrwRate(Math.random()*10+30);
            result.setSellWaterUsage((1-result.getNrwRate()/100)*result.getYieldWaterUsage());
        }
        return result;
    }

    @Override
    public List<SecDataCollectDto> selectMapForWholeCompany(MonitorDataCollectDto monitorDataCollectDto) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(3);
        List<MonitorDataCollectDto> result=onlineMonitorMapper.selectMapSuspension(monitorDataCollectDto);
        List<SecDataCollectDto> secDataCollectDtos = new ArrayList<>();
        if(!StringUtils.isEmpty(monitorDataCollectDto.getSceneTypeName()))
        {
            Map<Long,SecDataCollectDto> map = new HashMap<>();
            // 按公司进行汇总
            for(MonitorDataCollectDto item : result) {
                System.out.println("公司ID:"+item.getCompanyOrgId());
                if (!map.containsKey(item.getCompanyOrgId())) {
                    SecDataCollectDto secDataCollectDto = new SecDataCollectDto();
                    secDataCollectDto.setCount(1);
                    secDataCollectDto.setComName(orgInfoUtil.getOrgName(item.getCompanyOrgId().intValue()));
                    BigDecimal yieldWaterUsage=monitorDataReportServiceImpl.getAmountCount(item.getCompanyOrgId().intValue(),null,"泵站",3,2);
                    secDataCollectDto.setYieldWaterUsage(yieldWaterUsage.doubleValue());
                    map.put(item.getCompanyOrgId(), secDataCollectDto);
                } else {
                    Integer count = map.get(item.getCompanyOrgId()).getCount() != null ? map.get(item.getCompanyOrgId()).getCount() : 1;
                    map.get(item.getCompanyOrgId()).setCount(count + 1);
                }
            }
            for (SecDataCollectDto value : map.values()) {
                secDataCollectDtos.add(value);
            }

            //按水量倒序排序 如果是水源按照取水量排序，其他按照供水量

            secDataCollectDtos.sort(Comparator.comparing(SecDataCollectDto::getYieldWaterUsage,Comparator.nullsFirst(Double::compareTo)).reversed());

//            //按水量倒序排序 如果是水源按照取水量排序，其他按照供水量
//            secDataCollectDtos.sort(new Comparator<SecDataCollectDto>() {
//                @Override
//                public int compare(SecDataCollectDto o1, SecDataCollectDto o2) {
//                    Double d1= monitorDataCollectDto.getSceneTypeName().equals("水源")?(o1.getYieldWaterUsage()==null?0d:o1.getYieldWaterUsage()):(o1.getYieldWaterUsage()==null?0d:o1.getYieldWaterUsage());
//                    Double d2= monitorDataCollectDto.getSceneTypeName().equals("水源")?(o2.getYieldWaterUsage()==null?0d:o2.getYieldWaterUsage()):(o2.getYieldWaterUsage()==null?0d:o2.getYieldWaterUsage());
//                    if(d1>d2){
//                        return -1;
//                    }
//                    return 0;
//                }
//            });
        }
        return secDataCollectDtos;
    }
    /**
     * 查询场景列表
     * @return
     */
    @Override
    public List<OnlineDataDto> selectList(OnlineDataDto onlineDataDto){
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        List<OnlineDataDto> result =onlineMonitorMapper.selectList(onlineDataDto);
        MonitorDataCollectDto monitorDataCollectDto=new MonitorDataCollectDto();
        List<Long> sceneIds = result.stream().map(OnlineDataDto::getSceneId).collect(Collectors.toList());
        monitorDataCollectDto.setType(5);
        monitorDataCollectDto.setSceneIds(sceneIds);
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        List<MonitorDataCollectDto> calculateRes=onlineMonitorMapper.selectSceneParam(monitorDataCollectDto);

        GetCalOnlineData(result,calculateRes);//获取在线数据及计算数据
        return result;
    }
    /**
     * 查询管网设备列表
     * @return
     */
    @Override
    public List<OnlineDataDto> selectPipeNetList(OnlineDataDto onlineDataDto){
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());

        List<OnlineDataDto> result =onlineMonitorMapper.selectPipeNetList(onlineDataDto);
        List<Long> deviceIds = result.stream().map(OnlineDataDto::getDeviceId).collect(Collectors.toList());
        onlineDataDto.setDeviceIds(deviceIds);
        onlineDataDto.setTenantId(loginUser.getTenantId());
        List<MonitorDataCollectDto> calculateRes=onlineMonitorMapper.statsDeviceParm(onlineDataDto);

        GetCalOnlineData(result,calculateRes);//获取在线数据及计算数据
        return result;
    }
    /**
     * 获取在线数据及计算数据
     */
    public void GetCalMonitorData(List<MonitorDataCollectDto> result,List<MonitorDataCollectDto> calculateRes){
        for(MonitorDataCollectDto monDataCol : result) {
            MonitorDataEntity monitorDataEntity =null;
            if(monDataCol.getDeviceId()!=null) {
                //取缓存里的数据
                byte[] bytes = redisUtil.get(("sms_water_"+monDataCol.getDeviceCode()).getBytes());
                if(bytes != null && bytes.length>0) {
                    monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                }
            }
            //获取最新数据 更新
            for(MonitorDataDto monData : monDataCol.getMonitorDataEntities()) {
                if(monDataCol.getDeviceId()==null) {
                    byte[] bytes = redisUtil.get(("sms_water_"+monData.getDeviceCode()).getBytes());
                    if(bytes != null && bytes.length>0) {
                        monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                    }else {
                        monitorDataEntity=null;
                    }
                }
                if(monitorDataEntity != null) {
                    if(monDataCol.getCollectDate()==null || monitorDataEntity.getCollectDate().getTime()>monDataCol.getCollectDate().getTime() ){
                        monDataCol.setCollectDate(monitorDataEntity.getCollectDate());
                    }
                    SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");//日期算换格式
                    //筛选该设备相同属性的值
                    List<MonitorDataValueEntity>  attributeEntities=monitorDataEntity.getDataValues().stream().filter((MonitorDataValueEntity m)
                            ->m.getAttributeId().equals(monData.getAttributeId())).collect(Collectors.toList());
                    MonitorDataValueEntity  attributeEntity=attributeEntities.size()>0?attributeEntities.get(0):null;
                    if(attributeEntity != null) {
                        //赋值
                        monData.setDataValue(attributeEntity.getDataValue());
                        //monData.setUnit(attributeEntity.getUnit());
                        if (monData.getAttributeType() != null && (monData.getAttributeType().equals("1") || monData.getAttributeType().equals("2"))) {//如果是状态值 需转换
                            DecimalFormat decimalFormat = new DecimalFormat("###################.###########");//去掉末尾小数点
                            String specsValue = attributeEntity.getDataValue() == null ? null : decimalFormat.format(attributeEntity.getDataValue());
                            monData.setSpecsName(specsValue == null ? null : deviceAttributeSpecsService.selectSpecsName(attributeEntity.getAttributeId(), specsValue));
                        }
                    }
                }
            }
            //计算数据 更新
            for(MonitorDataCollectDto calculate :calculateRes ) {
                //相同场景或设备 则取值计算
                if((monDataCol.getDeviceId()==null&&monDataCol.getSceneId().equals(calculate.getSceneId()))||
                    (monDataCol.getDeviceId()!=null&&monDataCol.getDeviceId().equals(calculate.getDeviceId()))) {
                    for(MonitorDataDto monitorData : calculate.getMonitorDataEntities()){
                        if(monDataCol.getDeviceId()==null) {
                            byte[] bytes = redisUtil.get(("sms_water_"+monitorData.getDeviceCode()).getBytes());
                            if(bytes != null && bytes.length>0) {
                                monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                            }else{
                                monitorDataEntity=null;
                            }
                        }
                        if(monitorDataEntity != null) {
                            SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");//日期算换格式
                            //计算今日数据
                            if(formatdate.format(new Date()).equals(formatdate.format(monitorDataEntity.getCollectDate()))) {
                                //筛选该设备相同属性的值
                                List<MonitorDataValueEntity> attributeEntities = monitorDataEntity.getDataValues().stream().filter((MonitorDataValueEntity m)
                                        -> m.getAttributeId().equals(monitorData.getAttributeId())).collect(Collectors.toList());
                                MonitorDataValueEntity  attributeEntity=attributeEntities.size()>0?attributeEntities.get(0):null;
                                if (attributeEntity != null) {
                                    Double attributeValue =0d;
                                    if(attributeEntity.getDataValue() != null && monitorData.getLatestValue() != null){
                                        attributeValue=attributeEntity.getDataValue() - monitorData.getLatestValue();
                                    }
                                    switch (monitorData.getAttributeType()) {
                                        case "3":
                                        case "16":
                                            monDataCol.setYieldWaterUsage(monDataCol.getYieldWaterUsage() != null ? monDataCol.getYieldWaterUsage() + attributeValue : attributeValue);
                                            break;
                                        case "4":
                                            monDataCol.setIntakeWaterUsage(monDataCol.getIntakeWaterUsage() != null ? monDataCol.getIntakeWaterUsage() + attributeValue : attributeValue);
                                            break;
                                        case "5":
                                            monDataCol.setPowerUsage(monDataCol.getPowerUsage() != null ? monDataCol.getPowerUsage() + attributeValue : attributeValue);
                                            break;
                                        case "6":
                                            monDataCol.setDrugUsage(monDataCol.getDrugUsage() != null ? monDataCol.getDrugUsage() + attributeValue : attributeValue);
                                            break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        for(MonitorDataCollectDto mon : result){
            if(!StringUtils.isEmpty(mon.getSceneTypeName())&&(mon.getSceneTypeName().equals("水源")||mon.getSceneTypeName().equals("水厂"))){
                if(mon.getYieldWaterUsage()!=null) {
                    mon.setYieldWaterUsage(mon.getYieldWaterUsage() / 10000);
                }
                if(mon.getIntakeWaterUsage()!=null) {
                    mon.setIntakeWaterUsage(mon.getIntakeWaterUsage() / 10000);
                }
                if(mon.getPowerUsage()!=null) {
                    mon.setPowerUsage(mon.getPowerUsage() / 10000);
                }
            }
        }
    }
    /**
     * 获取在线数据及计算数据
     */
    public void GetCalOnlineData(List<OnlineDataDto> result,List<MonitorDataCollectDto> calculateRes){
        for(MonitorDataCollectDto calculate :calculateRes ) {
            MonitorDataEntity monitorDataEntity =null;
            if(calculate.getDeviceId()!=null) {
                //取缓存里的数据
                byte[] bytes = redisUtil.get(("sms_water_"+calculate.getDeviceCode()).getBytes());
                if(bytes != null && bytes.length>0) {
                    monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();}
            }
            for(OnlineDataDto monDataCol : result) {
                //相同场景或设备 则取值计算
                if((monDataCol.getDeviceId()==null&&monDataCol.getSceneId().equals(calculate.getSceneId()))||
                   (monDataCol.getDeviceId()!=null&&monDataCol.getDeviceId().equals(calculate.getDeviceId()))) {
                    List<MonitorDataDto> pumpStatus=new ArrayList<>(0);//水泵状态
                    for(MonitorDataDto monitorData : calculate.getMonitorDataEntities()){
                        if(monDataCol.getDeviceId()==null) {
                            byte[] bytes = redisUtil.get(("sms_water_"+monitorData.getDeviceCode()).getBytes());
                            if(bytes != null && bytes.length>0) {
                                monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                            }else{
                                monitorDataEntity=null;
                            }
                        }
                        if(monitorDataEntity != null) {
                            if(monDataCol.getCollectDate()==null||monitorDataEntity.getCollectDate().getTime()>monDataCol.getCollectDate().getTime()){
                                monDataCol.setCollectDate(monitorDataEntity.getCollectDate());
                            }
                            //筛选该设备相同属性的值
                            List<MonitorDataValueEntity> attributeEntities = monitorDataEntity.getDataValues().stream().filter((MonitorDataValueEntity m)
                                    -> m.getAttributeId().equals(monitorData.getAttributeId())).collect(Collectors.toList());
                            MonitorDataValueEntity  attributeEntity=attributeEntities.size()>0?attributeEntities.get(0):null;
                            if (attributeEntity != null) {
                                //实时数据
                                monitorData.setDataValue(attributeEntity.getDataValue());
                                //monitorData.setUnit(attributeEntity.getUnit());
                                SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");//日期算换格式
                                //计算今日数据
                                if(formatdate.format(new Date()).equals(formatdate.format(monitorDataEntity.getCollectDate()))) {
                                    Double attributeValue =0d;
                                    if(attributeEntity.getDataValue() != null && monitorData.getLatestValue() != null){
                                        attributeValue=attributeEntity.getDataValue() - monitorData.getLatestValue();
                                    }
                                    switch (monitorData.getAttributeType()) {
                                        case "3"://供水量or出水量
                                            monDataCol.setYieldWaterUsage(monDataCol.getYieldWaterUsage() != null ? monDataCol.getYieldWaterUsage() + attributeValue : attributeValue);
                                            break;
                                        case "4"://取水量or进水量
                                            monDataCol.setIntakeWaterUsage(monDataCol.getIntakeWaterUsage() != null ? monDataCol.getIntakeWaterUsage() + attributeValue : attributeValue);
                                            break;
                                        case "5"://耗电量
                                            monDataCol.setPowerUsage(monDataCol.getPowerUsage() != null ? monDataCol.getPowerUsage() + attributeValue : attributeValue);
                                            break;
                                        case "6"://耗药量
                                            monDataCol.setDrugUsage(monDataCol.getDrugUsage() != null ? monDataCol.getDrugUsage() + attributeValue : attributeValue);
                                            break;
                                    }
                                }
                                switch (monitorData.getAttributeType()) {
                                    case "7"://取水PHor进水PH
                                        monDataCol.setIntakePh(monitorData);
                                        break;
                                    case "8"://供水PHor出水PH
                                        monDataCol.setYieldPh(monitorData);
                                        break;
                                    case "9"://取水浊度or进水浊度
                                        monDataCol.setIntakeTurbidity(monitorData);
                                        break;
                                    case "10"://供水浊度or出水浊度
                                        monDataCol.setYieldTurbidity(monitorData);
                                        break;
                                    case "11"://余氯
                                        monDataCol.setResidualChlorine(monitorData);
                                        break;
                                    case "12"://水位
                                        monDataCol.setWaterLevel(monitorData);
                                        break;
                                    case "13"://压力
                                        monDataCol.setPressure(monitorData);
                                        break;
                                    case "14"://瞬时流量
                                        monDataCol.setInstantFlow(monitorData);
                                        break;
                                    case "2"://水泵状态
                                        DecimalFormat decimalFormat = new DecimalFormat("###################.###########");//去掉末尾小数点
                                        String specsValue = attributeEntity.getDataValue() == null ? null : decimalFormat.format(attributeEntity.getDataValue());
                                        monitorData.setSpecsName(specsValue == null ? null : deviceAttributeSpecsService.selectSpecsName(attributeEntity.getAttributeId(), specsValue));
                                        pumpStatus.add(monitorData);
                                        monDataCol.setPumpStatus(pumpStatus);
                                        break;
                                    case "16"://累计流量
                                        monDataCol.setTotalFlow(monitorData);
                                        break;
                                    case "18"://电导率
                                        monDataCol.setConductivity(monitorData);
                                        break;
                                    case "20"://进口压力
                                        monDataCol.setImportPressure(monitorData);
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        }
        for(OnlineDataDto mon : result){
            if(!StringUtils.isEmpty(mon.getSceneTypeName())&&(mon.getSceneTypeName().equals("水源")||mon.getSceneTypeName().equals("水厂"))){
                if(mon.getYieldWaterUsage()!=null) {
                    mon.setYieldWaterUsage(mon.getYieldWaterUsage() / 10000);
                }
                if(mon.getIntakeWaterUsage()!=null) {
                    mon.setIntakeWaterUsage(mon.getIntakeWaterUsage() / 10000);
                }
                if(mon.getPowerUsage()!=null) {
                    mon.setPowerUsage(mon.getPowerUsage() / 10000);
                }
            }
        }
    }
    /**
     * 获取计算数据总值
     */
    public MonitorDataCollectDto GetCalTotalData(List<MonitorDataCollectDto> calculateRes){
        MonitorDataCollectDto result=new MonitorDataCollectDto();
        for(MonitorDataCollectDto calculate :calculateRes){
            result.setSceneTypeName(calculate.getSceneTypeName());
            for(MonitorDataDto monitorData : calculate.getMonitorDataEntities()){
                byte[] bytes = redisUtil.get(("sms_water_"+monitorData.getDeviceCode()).getBytes());
                if(bytes != null && bytes.length>0) {
                    MonitorDataEntity monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                    //筛选该设备相同属性的值
                    List<MonitorDataValueEntity> attributeEntities = monitorDataEntity.getDataValues().stream().filter((MonitorDataValueEntity m)
                            -> m.getAttributeId().equals(monitorData.getAttributeId())).collect(Collectors.toList());
                    MonitorDataValueEntity  attributeEntity=attributeEntities.size()>0?attributeEntities.get(0):null;
                    if (attributeEntity != null) {
                        SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");//日期算换格式
                        //计算今日数据
                        if(formatdate.format(new Date()).equals(formatdate.format(monitorDataEntity.getCollectDate()))) {
                            Double attributeValue =0d;
                            if(attributeEntity.getDataValue() != null && monitorData.getLatestValue() != null){
                                attributeValue=attributeEntity.getDataValue() - monitorData.getLatestValue();
                            }
                            switch (monitorData.getAttributeType()) {
                                case "3"://供水量or出水量
                                    result.setYieldWaterUsage(result.getYieldWaterUsage() != null ? result.getYieldWaterUsage() + attributeValue : attributeValue);
                                    break;
                                case "4"://取水量or进水量
                                    result.setIntakeWaterUsage(result.getIntakeWaterUsage() != null ? result.getIntakeWaterUsage() + attributeValue : attributeValue);
                                    break;
                                case "5"://耗电量
                                    result.setPowerUsage(result.getPowerUsage() != null ? result.getPowerUsage() + attributeValue : attributeValue);
                                    break;
                                case "6"://耗药量
                                    result.setDrugUsage(result.getDrugUsage() != null ? result.getDrugUsage() + attributeValue : attributeValue);
                                    break;
                            }
                        }
                    }
                }
            }
        }
        if(!StringUtils.isEmpty(result.getSceneTypeName())&&(result.getSceneTypeName().equals("水源")||result.getSceneTypeName().equals("水厂"))){
            if(result.getYieldWaterUsage()!=null) {
                result.setYieldWaterUsage(result.getYieldWaterUsage() / 10000);
            }
            if(result.getIntakeWaterUsage()!=null) {
                result.setIntakeWaterUsage(result.getIntakeWaterUsage() / 10000);
            }
            if(result.getPowerUsage()!=null) {
                result.setPowerUsage(result.getPowerUsage() / 10000);
            }
        }
        return result;
    }
    /**
     * 查询场景实时状态数量
     * @return
     */
    @Override
    public List<Map<String, Object>> selectStateCount(OnlineDataDto onlineDataDto)
    {
        LoginUser loginUser = UserUtil.getCurrentUser();
        onlineDataDto.setTenantId(loginUser.getTenantId());
        onlineDataDto.setProgramItems(loginUser.getProgramItemList());
        onlineDataDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        onlineDataDto.setPermissonType(loginUser.getPermissonType());
        return onlineMonitorMapper.selectStateCount(onlineDataDto);
    }

    /**
     * 查询场景实时状态数量
     * @return
     */
    @Override
    public List<AlarmDetailsVo> selectAlarmStatsInfo(AlarmDetailsQueryDto dto)
    {
        List<AlarmDetailsVo> alarmDetailsVos =  onlineMonitorMapper.selectAlarmStatsInfo(dto);
        if (CollectionUtil.isEmpty(alarmDetailsVos)) {
            return new ArrayList<>();
        }
        Map<Long, AlarmDetailsVo> dataMap = new HashMap<>();
        Long sendId  = null;
        long minutes = 0;
        Date startTime = null;
        Date endTime = null;
        Date nowTime = new Date();
        for (AlarmDetailsVo alarmDetails : alarmDetailsVos) {
            sendId = alarmDetails.getId();
            AlarmDetailsVo alarmDetailsVo = dataMap.get(sendId);
            if (alarmDetailsVo == null) {
                alarmDetailsVo = new AlarmDetailsVo();
            }
            endTime   = alarmDetails.getAlarmEndTime() != null ? alarmDetails.getAlarmEndTime() : nowTime;
            startTime = DatesUtil.parseDate(dto.getStartTime(), "yyyy-MM-dd HH:mm:ss");
            startTime = startTime.after(alarmDetails.getAlarmStartTime()) ? startTime : alarmDetails.getAlarmStartTime();
            minutes   = DatesUtil.minutesBetween(startTime, endTime);
            alarmDetailsVo.setDeviceName(alarmDetails.getDeviceName());
            alarmDetailsVo.setId(sendId);
            alarmDetailsVo.setAlarmCount( alarmDetailsVo.getAlarmCount() + 1 );
            alarmDetailsVo.setAlarmDuration(alarmDetailsVo.getAlarmDuration()  + minutes);
            dataMap.put(sendId, alarmDetailsVo);
        }
        return dataMap.values().stream().collect(Collectors.toList());
    }

}
