package com.usky.iot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.backend.client.DataQueryClient;
import com.usky.backend.domain.StatusVO;
import com.usky.common.core.bean.ApiResult;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.iot.domain.*;
import com.usky.iot.mapper.BaseAlarmMapper;
import com.usky.iot.mapper.DmpDeviceTypeMapper;
import com.usky.iot.service.*;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.iot.service.config.websocket.WebSocket;
import com.usky.iot.service.vo.BaseAlarmListVO;
import com.usky.iot.service.vo.BaseAlarmRequestVO;
import com.usky.iot.service.vo.BaseAlarmResponeVO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 统一告警表 服务实现类
 * </p>
 *
 * @author han
 * @since 2023-07-13
 */
@Slf4j
@Service
public class BaseAlarmServiceImpl extends AbstractCrudService<BaseAlarmMapper, BaseAlarm> implements BaseAlarmService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseAlarmServiceImpl.class);

    @Autowired
    private DmpProductInfoService dmpProductInfoService;

    @Autowired
    private DmpDeviceInfoService dmpDeviceInfoService;

    @Autowired
    private BaseFacilityDeviceService baseFacilityDeviceService;

    @Autowired
    private WebSocket webSocket;

    @Autowired
    private DataQueryClient dataQueryClient;

    @Autowired
    private DmpDeviceStatusService dmpDeviceStatusService;

    @Autowired
    private DmpDeviceTypeMapper dmpDeviceTypeMapper;

    @Override
    public CommonPage<BaseAlarmResponeVO> statistic(BaseAlarmRequestVO baseAlarmRequestVO){

        List<BaseAlarmResponeVO> list = new ArrayList<>();

        LambdaQueryWrapper<DmpProductInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DmpProductInfo::getDeleteFlag,0)
                .like(StringUtils.isNotBlank(baseAlarmRequestVO.getProductName()),DmpProductInfo::getProductName,baseAlarmRequestVO.getProductName())
                .eq(DmpProductInfo::getTenantId,SecurityUtils.getTenantId());
        List<DmpProductInfo> list1 = dmpProductInfoService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list1)){
            QueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.query();
            queryWrapper1.select("product_code as productCode","count(*) as count")
                    .in("service_status",1,2)
                    .eq("delete_flag",0)
                    .eq("tenant_id",SecurityUtils.getTenantId())
                    .groupBy("product_code");
            List<Map<String,Object>> mapList= dmpDeviceInfoService.listMaps(queryWrapper1);

            List<String> productCodeList = list1.stream().map(s -> s.getProductCode()).collect(Collectors.toList());
            QueryWrapper<BaseAlarm> queryWrapper2 = Wrappers.query();
            queryWrapper2.select("product_code as productCode","handle_status as handleStatus","count(*) as count")
                    .in("product_code",productCodeList)
                    .eq("tenant_id",SecurityUtils.getTenantId())
                    .groupBy("product_code","handle_status");
            List<Map<String,Object>> handleStatusList = this.listMaps(queryWrapper2);

            for(int i=0;i<list1.size();i++){
                BaseAlarmResponeVO responeVO = new BaseAlarmResponeVO();
                responeVO.setProductCode(list1.get(i).getProductCode());
                responeVO.setProductName(list1.get(i).getProductName());
                responeVO.setDeviceType(list1.get(i).getDeviceType());

                //未处理
                int untreated = 0;
                if(CollectionUtils.isNotEmpty(handleStatusList)){
                    for(int j=0;j<handleStatusList.size();j++){
                        if(list1.get(i).getProductCode().equals(handleStatusList.get(j).get("productCode")) && (0 == Integer.parseInt(handleStatusList.get(j).get("handleStatus").toString()))){
                            untreated = Integer.parseInt(String.valueOf(handleStatusList.get(j).get("count")));
                            break;
                        }
                    }
                }
                //已处理
                int processed = 0;
                if(CollectionUtils.isNotEmpty(handleStatusList)){
                    for(int j=0;j<handleStatusList.size();j++){
                        if(list1.get(i).getProductCode().equals(handleStatusList.get(j).get("productCode")) && (1 == Integer.parseInt(handleStatusList.get(j).get("handleStatus").toString()))){
                            processed = Integer.parseInt(String.valueOf(handleStatusList.get(j).get("count")));
                            break;
                        }
                    }
                }
                //总数
                int count = untreated+processed;
                //处置率
                float processRate = 0;
                if(count != 0){
                    processRate = ((float) processed/count)*100;
                }

                responeVO.setTotal(count);
                responeVO.setUntreated(untreated);
                responeVO.setProcessed(processed);
                responeVO.setProcessRate(processRate);

                //设备总数
                responeVO.setDeviceCount(0);
                if(CollectionUtils.isNotEmpty(mapList)){
                    for(int j=0;j<mapList.size();j++){
                        if(list1.get(i).getProductCode().equals(mapList.get(j).get("productCode"))){
                            responeVO.setDeviceCount(Integer.parseInt(String.valueOf(mapList.get(j).get("count"))));
                            break;
                        }
                    }
                }

                //离线告警统计
                //离线告警未处理
                int offLineUntreated = 0;
//                offLineUntreated = this.count(Wrappers.<BaseAlarm>query().lambda().eq(BaseAlarm::getHandleStatus,0).eq(BaseAlarm::getAlarmType,"001").eq(BaseAlarm::getProductCode,list1.get(i).getProductCode()).eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId()));
                //离线告警已处理
                int offLineProcessed = 0;
//                offLineProcessed = this.count(Wrappers.<BaseAlarm>query().lambda().eq(BaseAlarm::getHandleStatus,1).eq(BaseAlarm::getAlarmType,"001").eq(BaseAlarm::getProductCode,list1.get(i).getProductCode()).eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId()));
                //离线告警总数
                int offLineCount = offLineUntreated+offLineProcessed;
                //离线告警处置率
                float offLineProcessRate = 0;
                if(offLineCount != 0){
                    offLineProcessRate = ((float) offLineProcessed/offLineCount)*100;
                }
                responeVO.setOffLineUntreated(offLineUntreated);
                responeVO.setOffLineProcessed(offLineProcessed);
                responeVO.setOffLineProcessRate(offLineProcessRate);

                list.add(responeVO);
            }
        }

        int total = 0;
        if(list1.size()>0){
            total = list1.size();
        }
        int current = 0;
        Integer pageNum = baseAlarmRequestVO.getCurrent();
        Integer pageSize = baseAlarmRequestVO.getSize();
        if(pageNum != null && pageSize >0){
            current = (pageNum-1)*pageSize;
        }
        List<BaseAlarmResponeVO> records = list.stream().skip(current).limit(pageSize).collect(Collectors.toList());

        return new CommonPage<BaseAlarmResponeVO>(records,total,pageSize,pageNum);
    }

    public CommonPage<BaseAlarm> page(BaseAlarmListVO baseAlarmListVO){
        List<BaseAlarm> list = new ArrayList<>();

        List<String> devIdList = new ArrayList<>();
        LambdaQueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.lambdaQuery();
        queryWrapper1.eq(DmpDeviceInfo::getTenantId,SecurityUtils.getTenantId())
                .eq(DmpDeviceInfo::getDeleteFlag,0);
        List<DmpDeviceInfo> deviceInfo = dmpDeviceInfoService.list(queryWrapper1);
        if(CollectionUtils.isNotEmpty(deviceInfo)){
            for(int j=0;j<deviceInfo.size();j++){
                devIdList.add(deviceInfo.get(j).getDeviceId());
            }
        }

        IPage<BaseAlarm> page = new Page<>(baseAlarmListVO.getCurrent(), baseAlarmListVO.getSize());
        List<BaseAlarm> records = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(devIdList)){
            LambdaQueryWrapper<BaseAlarm> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.in(BaseAlarm::getDeviceId,devIdList)
                    .eq(StringUtils.isNotBlank(baseAlarmListVO.getDeviceId()),BaseAlarm::getDeviceId,baseAlarmListVO.getDeviceId())
                    .eq(StringUtils.isNotBlank(baseAlarmListVO.getProductCode()),BaseAlarm::getProductCode,baseAlarmListVO.getProductCode())
                    .in(CollectionUtils.isNotEmpty(baseAlarmListVO.getAlarmType()),BaseAlarm::getAlarmType,
                            baseAlarmListVO.getAlarmType())
                    .eq(null != baseAlarmListVO.getHandleStatus(),BaseAlarm::getHandleStatus,baseAlarmListVO.getHandleStatus())
                    .between(StringUtils.isNotBlank(baseAlarmListVO.getStartTime()) && StringUtils.isNotBlank(baseAlarmListVO.getEndTime()),BaseAlarm::getAlarmTime,baseAlarmListVO.getStartTime(),baseAlarmListVO.getEndTime())
                    .eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId())
                    .eq(Objects.nonNull(baseAlarmListVO.getId()),BaseAlarm::getId,baseAlarmListVO.getId());
            if (StringUtils.isNotBlank(baseAlarmListVO.getTypeCode())){
                if (baseAlarmListVO.getTypeCode().equals("1")){
                    queryWrapper.eq(BaseAlarm::getAlarmGrade,1)
                            .orderByDesc(BaseAlarm::getId);
                }else if (baseAlarmListVO.getTypeCode().equals("2")){
                    queryWrapper.ne(BaseAlarm::getAlarmGrade,1)
                            .orderByDesc(BaseAlarm::getId);
                }
            }else {
                queryWrapper.orderByDesc(BaseAlarm::getId);
            }
//            page = this.page(page,queryWrapper);
            records = this.list(queryWrapper);
            if(records.size() == 0){
                return new CommonPage<>(new ArrayList<>(),0,0,0);

            }
        }

        if(StringUtils.isNotBlank(baseAlarmListVO.getDeviceName())){
            list = records.stream().filter(e -> baseAlarmListVO.getDeviceName().equals(e.getDeviceName())).collect(Collectors.toList());
        }else {
            if(records.size()>0){
                for(int k=0;k<records.size();k++){
                    list.add(records.get(k));
                }
            }

        }

        if(list.size()>0){
            page.setTotal(list.size());
        }
        int current = 0;
        Integer pageNum = baseAlarmListVO.getCurrent();
        Integer pageSize = baseAlarmListVO.getSize();
        if(pageNum != null && pageSize >0){
            current = (pageNum-1)*pageSize;
        }
        QueryWrapper<DmpDeviceType> queryWrapper5 = Wrappers.query();
        queryWrapper5.eq("tenant_id",SecurityUtils.getTenantId());
        List<DmpDeviceType> deviceTypeList = dmpDeviceTypeMapper.selectList(queryWrapper5);
        List<BaseAlarm> info = list.stream().sorted(Comparator.comparing(BaseAlarm::getId,Comparator.reverseOrder())).skip(current).limit(pageSize).collect(Collectors.toList());
        List<String> devList = new ArrayList<>();
        for(int i=0;i<info.size();i++){
            devList.add(info.get(i).getDeviceId());
        }

        if(devList.size() > 0){
            LambdaQueryWrapper<BaseFacilityDevice> lambdaQuery1 = Wrappers.lambdaQuery();
            lambdaQuery1.in(BaseFacilityDevice::getDeviceId,devList);
            List<BaseFacilityDevice> records1 = baseFacilityDeviceService.list(lambdaQuery1);
            if(CollectionUtils.isNotEmpty(deviceInfo)){
                for(int i=0;i<info.size();i++){
                    for(int j=0;j<deviceInfo.size();j++){
                        if(info.get(i).getDeviceId().equals(deviceInfo.get(j).getDeviceId())){
                            info.get(i).setDeviceName(deviceInfo.get(j).getDeviceName());
                            info.get(i).setDeviceType(deviceInfo.get(j).getDeviceType());
                            break;
                        }
                    }
                    for(int k=0;k<records1.size();k++){
                        if(info.get(i).getDeviceId().equals(records1.get(k).getDeviceId())){
                            info.get(i).setFacilityId(records1.get(k).getFacilityId());
                            break;
                        }
                    }
                }
            }
        }

        List<BaseAlarmType> alarmTypeList = baseMapper.getAlarmTypeList();
        if(CollectionUtils.isNotEmpty(alarmTypeList)){
            for(int i=0;i<info.size();i++){
                for(int j=0;j<alarmTypeList.size();j++){
                    if(info.get(i).getAlarmType().equals(alarmTypeList.get(j).getTypeCode())){
                        info.get(i).setTypeImg(alarmTypeList.get(j).getTypeImg());
                        break;
                    }
                }
            }
        }

        LocalDateTime toDateTime = LocalDateTime.now();
        for(int l=0;l<info.size();l++){
            LocalDateTime fromDateTime = info.get(l).getAlarmTime();
            LocalDateTime tempDateTime = LocalDateTime.from( fromDateTime );
            long days = tempDateTime.until( toDateTime, ChronoUnit.DAYS);
            tempDateTime = tempDateTime.plusDays( days );
            long hours = tempDateTime.until( toDateTime, ChronoUnit.HOURS);
            tempDateTime = tempDateTime.plusHours( hours );
            long minutes = tempDateTime.until( toDateTime, ChronoUnit.MINUTES);
            tempDateTime = tempDateTime.plusMinutes( minutes );
            long seconds = tempDateTime.until( toDateTime, ChronoUnit.SECONDS);
            if (days>0){
                info.get(l).setAlarmTime1(days+"天");
            }else {
                info.get(l).setAlarmTime1(hours+":"+minutes+":"+seconds);
            }
            for(int m=0;m<deviceTypeList.size();m++){
                if(info.get(l).getDeviceType().equals(Integer.parseInt(deviceTypeList.get(m).getTypeCode()))){
                    info.get(l).setDeviceTypeName(deviceTypeList.get(m).getTypeName());
                }
            }

        }
        page.setRecords(info);
        return new CommonPage<BaseAlarm>(page.getRecords(),page.getTotal(),pageSize,pageNum);

    }

    @Override
    public CommonPage<BaseAlarmResponeVO> statistic_notoken(BaseAlarmRequestVO baseAlarmRequestVO){

        List<BaseAlarmResponeVO> list = new ArrayList<>();

        LambdaQueryWrapper<DmpProductInfo> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DmpProductInfo::getDeleteFlag,0)
                .like(StringUtils.isNotBlank(baseAlarmRequestVO.getProductName()),DmpProductInfo::getProductName,baseAlarmRequestVO.getProductName());
        List<DmpProductInfo> list1 = dmpProductInfoService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list1)){

            List<String> productCodeList = list1.stream().map(s -> s.getProductCode()).collect(Collectors.toList());
            QueryWrapper<BaseAlarm> queryWrapper2 = Wrappers.query();
            queryWrapper2.select("product_code as productCode","handle_status as handleStatus","count(*) as count")
                    .in("product_code",productCodeList)
                    .groupBy("product_code","handle_status");
            List<Map<String,Object>> handleStatusList = this.listMaps(queryWrapper2);

            for(int i=0;i<list1.size();i++){
                BaseAlarmResponeVO responeVO = new BaseAlarmResponeVO();
                responeVO.setProductCode(list1.get(i).getProductCode());
                responeVO.setProductName(list1.get(i).getProductName());
                responeVO.setDeviceType(list1.get(i).getDeviceType());

                //未处理
                int untreated = 0;
                if(CollectionUtils.isNotEmpty(handleStatusList)){
                    for(int j=0;j<handleStatusList.size();j++){
                        if(list1.get(i).getProductCode().equals(handleStatusList.get(j).get("productCode")) && (0 == Integer.parseInt(handleStatusList.get(j).get("handleStatus").toString()))){
                            untreated = Integer.parseInt(String.valueOf(handleStatusList.get(j).get("count")));
                            break;
                        }
                    }
                }
                //已处理
                int processed = 0;
                if(CollectionUtils.isNotEmpty(handleStatusList)){
                    for(int j=0;j<handleStatusList.size();j++){
                        if(list1.get(i).getProductCode().equals(handleStatusList.get(j).get("productCode")) && (1 == Integer.parseInt(handleStatusList.get(j).get("handleStatus").toString()))){
                            processed = Integer.parseInt(String.valueOf(handleStatusList.get(j).get("count")));
                            break;
                        }
                    }
                }
                //总数
                int count = untreated+processed;
                //处置率
                float processRate = 0;
                if(count != 0){
                    processRate = ((float) processed/count)*100;
                }

                responeVO.setTotal(count);
                responeVO.setUntreated(untreated);
                responeVO.setProcessed(processed);
                responeVO.setProcessRate(processRate);

//                //设备总数
//                responeVO.setDeviceCount(0);
//                if(CollectionUtils.isNotEmpty(mapList)){
//                    for(int j=0;j<mapList.size();j++){
//                        if(list1.get(i).getProductCode().equals(mapList.get(j).get("productCode"))){
//                            responeVO.setDeviceCount(Integer.parseInt(String.valueOf(mapList.get(j).get("count"))));
//                            break;
//                        }
//                    }
//                }

                //离线告警统计
                //离线告警未处理
                int offLineUntreated = 0;
//                offLineUntreated = this.count(Wrappers.<BaseAlarm>query().lambda().eq(BaseAlarm::getHandleStatus,0).eq(BaseAlarm::getAlarmType,"001").eq(BaseAlarm::getProductCode,list1.get(i).getProductCode()).eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId()));
                //离线告警已处理
                int offLineProcessed = 0;
//                offLineProcessed = this.count(Wrappers.<BaseAlarm>query().lambda().eq(BaseAlarm::getHandleStatus,1).eq(BaseAlarm::getAlarmType,"001").eq(BaseAlarm::getProductCode,list1.get(i).getProductCode()).eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId()));
                //离线告警总数
                int offLineCount = offLineUntreated+offLineProcessed;
                //离线告警处置率
                float offLineProcessRate = 0;
                if(offLineCount != 0){
                    offLineProcessRate = ((float) offLineProcessed/offLineCount)*100;
                }
                responeVO.setOffLineUntreated(offLineUntreated);
                responeVO.setOffLineProcessed(offLineProcessed);
                responeVO.setOffLineProcessRate(offLineProcessRate);

                list.add(responeVO);
            }
        }

        int total = 0;
        if(list1.size()>0){
            total = list1.size();
        }
        int current = 0;
        Integer pageNum = baseAlarmRequestVO.getCurrent();
        Integer pageSize = baseAlarmRequestVO.getSize();
        if(pageNum != null && pageSize >0){
            current = (pageNum-1)*pageSize;
        }
        List<BaseAlarmResponeVO> records = list.stream().skip(current).limit(pageSize).collect(Collectors.toList());

        return new CommonPage<BaseAlarmResponeVO>(records,total,pageSize,pageNum);
    }

    public CommonPage<BaseAlarm> page_notoken(BaseAlarmListVO baseAlarmListVO){
        List<BaseAlarm> list = new ArrayList<>();

        LambdaQueryWrapper<BaseAlarm> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper
                .eq(StringUtils.isNotBlank(baseAlarmListVO.getProductCode()),BaseAlarm::getProductCode,baseAlarmListVO.getProductCode())
                .in(CollectionUtils.isNotEmpty(baseAlarmListVO.getAlarmType()),BaseAlarm::getAlarmType,
                        baseAlarmListVO.getAlarmType())
                .eq(null != baseAlarmListVO.getHandleStatus(),BaseAlarm::getHandleStatus,baseAlarmListVO.getHandleStatus())
                .between(StringUtils.isNotBlank(baseAlarmListVO.getStartTime()) && StringUtils.isNotBlank(baseAlarmListVO.getEndTime()),BaseAlarm::getAlarmTime,baseAlarmListVO.getStartTime(),baseAlarmListVO.getEndTime())
                .orderByDesc(BaseAlarm::getId);
        List<BaseAlarm> records = this.list(queryWrapper);
        if(records.size()>0){
            List<String> devList = new ArrayList<>();
            for(int i=0;i<records.size();i++){
                devList.add(records.get(i).getDeviceId());
            }

            if(devList.size() > 0){
                LambdaQueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.in(DmpDeviceInfo::getDeviceId,devList)
                        .eq(DmpDeviceInfo::getDeleteFlag,0);
                List<DmpDeviceInfo> deviceInfo = dmpDeviceInfoService.list(queryWrapper1);
                if(CollectionUtils.isNotEmpty(deviceInfo)){
                    for(int i=0;i<records.size();i++){
                        for(int j=0;j<deviceInfo.size();j++){
                            if(records.get(i).getDeviceId().equals(deviceInfo.get(j).getDeviceId())){
                                records.get(i).setDeviceName(deviceInfo.get(j).getDeviceName());
                                continue;
                            }
                        }

                    }
                }
            }

            List<BaseAlarmType> alarmTypeList = baseMapper.getAlarmTypeList();
            if(CollectionUtils.isNotEmpty(alarmTypeList)){
                for(int i=0;i<records.size();i++){
                    for(int j=0;j<alarmTypeList.size();j++){
                        if(records.get(i).getAlarmType().equals(alarmTypeList.get(j).getTypeCode())){
                            records.get(i).setTypeImg(alarmTypeList.get(j).getTypeImg());
                            break;
                        }
                    }
                }
            }
        }

        if(StringUtils.isNotBlank(baseAlarmListVO.getDeviceName())){
            list = records.stream().filter(e -> baseAlarmListVO.getDeviceName().equals(e.getDeviceName())).collect(Collectors.toList());
        }else {
            if(records.size()>0){
                for(int k=0;k<records.size();k++){
                    list.add(records.get(k));
                }
            }

        }
        int total = 0;
        if(list.size()>0){
            total = list.size();
        }
        int current = 0;
        Integer pageNum = baseAlarmListVO.getCurrent();
        Integer pageSize = baseAlarmListVO.getSize();
        if(pageNum != null && pageSize >0){
            current = (pageNum-1)*pageSize;
        }
        List<BaseAlarm> info = list.stream().sorted(Comparator.comparing(BaseAlarm::getId,Comparator.reverseOrder())).skip(current).limit(pageSize).collect(Collectors.toList());

        return new CommonPage<BaseAlarm>(info,total,pageSize,pageNum);

    }

    public List<BaseAlarm> getScreenAlarmList(){

        LambdaQueryWrapper<BaseAlarm> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper
                .eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId())
                .orderByDesc(BaseAlarm::getId).last("limit 6");
        List<BaseAlarm> records = this.list(queryWrapper);
        if(records.size()>0){
            List<String> devList = new ArrayList<>();
            for(int i=0;i<records.size();i++){
                devList.add(records.get(i).getDeviceId());
            }

            if(devList.size() > 0){
                LambdaQueryWrapper<DmpDeviceInfo> queryWrapper1 = Wrappers.lambdaQuery();
                queryWrapper1.in(DmpDeviceInfo::getDeviceId,devList)
                        .eq(DmpDeviceInfo::getTenantId,SecurityUtils.getTenantId())
                        .eq(DmpDeviceInfo::getDeleteFlag,0);
                List<DmpDeviceInfo> deviceInfo = dmpDeviceInfoService.list(queryWrapper1);
                if(CollectionUtils.isNotEmpty(deviceInfo)){
                    for(int i=0;i<records.size();i++){
                        for(int j=0;j<deviceInfo.size();j++){
                            if(records.get(i).getDeviceId().equals(deviceInfo.get(j).getDeviceId())){
                                records.get(i).setDeviceName(deviceInfo.get(j).getDeviceName());
                                continue;
                            }
                        }

                    }
                }
            }

            List<BaseAlarmType> alarmTypeList = baseMapper.getAlarmTypeList();
            if(CollectionUtils.isNotEmpty(alarmTypeList)){
                for(int i=0;i<records.size();i++){
                    for(int j=0;j<alarmTypeList.size();j++){
                        if(records.get(i).getAlarmType().equals(alarmTypeList.get(j).getTypeCode())){
                            records.get(i).setTypeImg(alarmTypeList.get(j).getTypeImg());
                            break;
                        }
                    }
                }
            }
        }
        return records;
    }

    public void update(BaseAlarm baseAlarm){
        int handleRange = baseAlarm.getHandleRange();
        if(handleRange == 0){  //批量
            LambdaQueryWrapper<BaseAlarm> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(BaseAlarm::getDeviceId,baseAlarm.getDeviceId())
                    .eq(BaseAlarm::getAlarmType,baseAlarm.getAlarmType())
                    .eq(BaseAlarm::getTenantId,SecurityUtils.getTenantId())
                    .eq(BaseAlarm::getHandleStatus,0);
            List<BaseAlarm> list = this.list(queryWrapper);
            if(list.size() > 0){
                for(int i=0;i<list.size();i++){
                    list.get(i).setHandleContent(baseAlarm.getHandleContent());
                    list.get(i).setAlarmFalse(baseAlarm.getAlarmFalse());
                    list.get(i).setHandleStatus(1);
                    list.get(i).setHandleBy(SecurityUtils.getUsername());
                    list.get(i).setHandleTime(LocalDateTime.now());
                    list.get(i).setHandlePhone(SecurityUtils.getLoginUser().getSysUser().getPhonenumber());
                }
            }
            this.updateBatchById(list);

        }else {  // 单一
//            LOGGER.info("alarmceshi+++++++++"+SecurityUtils.getLoginUser().getSysUser());
            baseAlarm.setHandleStatus(1);
            baseAlarm.setHandleBy(SecurityUtils.getUsername());
            baseAlarm.setHandleTime(LocalDateTime.now());
//            baseAlarm.setHandlePhone(SecurityUtils.getLoginUser().getSysUser().getPhonenumber());
            this.updateById(baseAlarm);
        }
    }
    @Override
    public boolean add(BaseAlarm baseAlarm) {
        baseAlarm.setHandleStatus(0);
        if (StringUtils.isNotBlank(baseAlarm.getProductCode()) && StringUtils.isNotBlank(baseAlarm.getDeviceId()) && StringUtils.isNotBlank(baseAlarm.getAlarmType())){
            LambdaQueryWrapper<DmpProductInfo> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.eq(DmpProductInfo::getProductCode,baseAlarm.getProductCode())
                    .eq(DmpProductInfo::getDeleteFlag,0);
            List<DmpProductInfo> records = dmpProductInfoService.list(lambdaQuery);
            LambdaQueryWrapper<BaseFacilityDevice> lambdaQuery1 = Wrappers.lambdaQuery();
            lambdaQuery1.eq(BaseFacilityDevice::getDeviceId,baseAlarm.getDeviceId());
            List<BaseFacilityDevice> records1 = baseFacilityDeviceService.list(lambdaQuery1);
            LambdaQueryWrapper<DmpDeviceInfo> lambdaQuery2 = Wrappers.lambdaQuery();
            lambdaQuery2.eq(DmpDeviceInfo::getDeviceId,baseAlarm.getDeviceId())
                    .eq(DmpDeviceInfo::getProductCode,baseAlarm.getProductCode())
                    .eq(DmpDeviceInfo::getServiceStatus,2)
                    .eq(DmpDeviceInfo::getDeleteFlag,0);
            List<DmpDeviceInfo> records2 = dmpDeviceInfoService.list(lambdaQuery2);
            BaseAlarmType baseAlarmType = baseMapper.getAlarmTypeOne(baseAlarm.getAlarmType());
            if(records.size()>0 && baseAlarmType !=null && records2.size()>0){
                baseAlarm.setTenantId(records.get(0).getTenantId());
                if (StringUtils.isNotBlank(baseAlarm.getHandleBy()) || StringUtils.isNotBlank(baseAlarm.getHandlePhone())) {
                    baseAlarm.setHandleStatus(1);
                    LambdaQueryWrapper<BaseAlarm> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.eq(BaseAlarm::getDeviceId, baseAlarm.getDeviceId())
                            .eq(BaseAlarm::getAlarmType, baseAlarm.getAlarmType())
                            .eq(BaseAlarm::getAlarmAddress, baseAlarm.getAlarmAddress())
                            .eq(BaseAlarm::getAlarmGrade, baseAlarm.getAlarmGrade());
                    return this.update(baseAlarm, queryWrapper);
                } else {
                    boolean saveResult = this.save(baseAlarm);
                    if (records1.size() > 0) {
                        baseAlarm.setFacilityId(records1.get(0).getFacilityId());
                    }
                    baseAlarm.setDeviceName(records2.get(0).getDeviceName());
                    baseAlarm.setTypeImg(baseAlarmType.getTypeImg());
                    baseAlarm.setAlarmType(baseAlarmType.getTypeName());
                    baseAlarm.setAlarmTime1(baseAlarm.getAlarmTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd " +
                            "HH:mm:ss")));
                    webSocket.sendMessage(baseAlarm, records.get(0).getTenantId().toString());
                    return saveResult;
                }
            }else {
                throw new BusinessException("告警数据投递失败，请检查产品编码、设备编号、告警类型，是否有误;设备是否激活");
            }
        }else {
            throw new BusinessException("告警数据投递失败，请检查产品编码、设备编号、告警类型，不能为空");
        }
    }

    @Async("asyncServiceExecutor")
    public void deviceAlarm(List<StatusVO> list, List<DmpDeviceInfo> devInfoList, List<BaseAlarm> baseUnAlarmList){
        log.info("定时同步设备告警数据 start");
        if(CollectionUtils.isNotEmpty(devInfoList)){
            for(int i=0;i<list.size();i++){
                String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                if(Objects.nonNull(list.get(i).getTime()) && currentDate.equals(list.get(i).getTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))){
                    //设备离线告警恢复在线自动默认处理
                    if(CollectionUtils.isNotEmpty(baseUnAlarmList)){
                        for(int j=0;j<baseUnAlarmList.size();j++){
                            if(list.get(i).getDeviceId().equals(baseUnAlarmList.get(j).getDeviceId()) && list.get(i).getProductCode().equals(baseUnAlarmList.get(j).getProductCode())){
                                LambdaUpdateWrapper<BaseAlarm> updateWrapper1 = Wrappers.lambdaUpdate();
                                updateWrapper1.set(BaseAlarm::getHandleStatus,1)
                                        .set(BaseAlarm::getHandleBy,"YT_admin")
                                        .set(BaseAlarm::getHandleTime,LocalDateTime.now())
                                        .eq(BaseAlarm::getDeviceId,list.get(i).getDeviceId())
                                        .eq(BaseAlarm::getHandleStatus,0)
                                        .eq(BaseAlarm::getProductCode,list.get(i).getProductCode());
                                this.update(updateWrapper1);
                                break;
                            }
                        }
                    }

                }else{

                    for(int j=0;j<devInfoList.size();j++){
                        if(list.get(i).getDeviceId().equals(devInfoList.get(j).getDeviceId()) && list.get(i).getProductCode().equals(devInfoList.get(j).getProductCode())){
                            int count = 0;
                            for(int k=0;k<baseUnAlarmList.size();k++){
                                if(list.get(i).getDeviceId().equals(baseUnAlarmList.get(k).getDeviceId()) && list.get(i).getProductCode().equals(baseUnAlarmList.get(k).getProductCode())){
                                    count++;
                                }
                            }
                            if(count == 0){
                                BaseAlarm baseAlarm = new BaseAlarm();
                                baseAlarm.setDeviceId(list.get(i).getDeviceId());
                                baseAlarm.setAlarmTime(LocalDateTime.parse(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH"))+":00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                                baseAlarm.setAlarmType("001");
                                baseAlarm.setAlarmObject(devInfoList.get(j).getDeviceName());
                                baseAlarm.setAlarmData("");
                                baseAlarm.setAlarmAttribute("离线告警");
                                baseAlarm.setAlarmContent("设备离线告警");
                                baseAlarm.setAlarmGrade(1);

                                baseAlarm.setAlarmAddress(devInfoList.get(j).getInstallAddress());
                                baseAlarm.setProductCode(devInfoList.get(j).getProductCode());
                                this.add(baseAlarm);
                            }
                            break;
                        }
                    }

                }
            }
        }
        log.info("定时同步设备告警数据 end");
    }

    @Override
    public void deviceOffLineAlarm(){
        List<StatusVO> list = new ArrayList<>();
        List<String> devList = new ArrayList<>();
        LambdaQueryWrapper<DmpDeviceStatus> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(DmpDeviceStatus::getProductCode,DmpDeviceStatus::getDeviceId,DmpDeviceStatus::getLastOnlineTime);
        List<DmpDeviceStatus> dmpDeviceStatusList = dmpDeviceStatusService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(dmpDeviceStatusList)){
            for (int i = 0; i < dmpDeviceStatusList.size(); i++) {
                StatusVO statusVO = new StatusVO();
                statusVO.setProductCode(dmpDeviceStatusList.get(i).getProductCode());
                statusVO.setDeviceId(dmpDeviceStatusList.get(i).getDeviceId());
                statusVO.setTime(dmpDeviceStatusList.get(i).getLastOnlineTime());
                list.add(statusVO);
                devList.add(dmpDeviceStatusList.get(i).getDeviceId());
            }
        }

        if(CollectionUtils.isNotEmpty(list)){
            List<DmpDeviceInfo> devInfoList = new ArrayList<>();
            List<BaseAlarm> baseUnAlarmList = new ArrayList<>();
            if(devList.size() > 0) {
                devInfoList = baseMapper.getDeviceInfoList(devList);
                baseUnAlarmList = baseMapper.getUnDeviceAlarmList(devList);
            }

            this.deviceAlarm(list,devInfoList,baseUnAlarmList);
        }
    }

    @Override
    public List<Object> alarmStatistic(Integer deptId) {
        List<Object> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = LocalDateTime.of(today, LocalTime.MIN);
        LocalDateTime startOfYear = now.minusYears(1);
        QueryWrapper<BaseAlarm> queryWrapper = Wrappers.query();
        queryWrapper.select("COUNT(alarm_grade=1 or null) as alarmCount","COUNT(alarm_grade!=1 or" +
                " null) as hiddenCount","COUNT(alarm_grade=1 and handle_status=1 or null) as ahAlarmCount","COUNT" +
                "(alarm_grade!=1 and handle_status=1 or null) as ahHiddenCount")
                .between("alarm_time",startOfDay,now)
                .eq("tenant_id",SecurityUtils.getTenantId());
        List<Map<String,Object>> alarmStatisticList = this.listMaps(queryWrapper);
        QueryWrapper<BaseAlarm> queryWrapper1 = Wrappers.query();
        queryWrapper1.select("COUNT(alarm_grade=1 or null) as alarmCount","COUNT(alarm_grade=1 and handle_status=1 or null) as ahAlarmCount")
                .between("alarm_time",startOfYear,now)
                .eq("tenant_id",SecurityUtils.getTenantId());
        List<Map<String,Object>> alarmStatisticList1 = this.listMaps(queryWrapper1);
        QueryWrapper<BaseAlarm> queryWrapper2 = Wrappers.query();
        queryWrapper2.select("COUNT(alarm_grade=1 and handle_status=0 or null) as alarmCount","COUNT(alarm_grade=1 " +
                "and alarm_type='111' or null) as fireAlarmCount","COUNT(alarm_grade!=1 and handle_status=0 or null) " +
                "as hiddenCount")
                .eq("tenant_id",SecurityUtils.getTenantId());
        List<Map<String,Object>> alarmStatisticList2 = this.listMaps(queryWrapper2);
        BigDecimal ahAlarmCountBig = new BigDecimal(Integer.valueOf(alarmStatisticList.get(0).get("ahAlarmCount").toString()));
        BigDecimal temp = new BigDecimal(Integer.valueOf(alarmStatisticList.get(0).get("alarmCount").toString()));
        if (Integer.valueOf(alarmStatisticList.get(0).get("alarmCount").toString()).equals(0)){
            map.put("ahAlarmCountBig", 0);
        }else {
            ahAlarmCountBig = ahAlarmCountBig.divide(temp,2, RoundingMode.HALF_UP);
            map.put("ahAlarmCountBig", ahAlarmCountBig);
        }
        BigDecimal ahHiddenCountBig = new BigDecimal(Integer.valueOf(alarmStatisticList.get(0).get("ahHiddenCount").toString()));
        BigDecimal temp1 = new BigDecimal(Integer.valueOf(alarmStatisticList.get(0).get("hiddenCount").toString()));
        if (Integer.valueOf(alarmStatisticList.get(0).get("hiddenCount").toString()).equals(0)){
            map.put("ahHiddenDayCountBig", 0);
        }else {
            ahHiddenCountBig = ahHiddenCountBig.divide(temp1,2, RoundingMode.HALF_UP);
            map.put("ahHiddenDayCountBig", ahHiddenCountBig);
        }

        BigDecimal ahAlarmYearCountBig = new BigDecimal(Integer.valueOf(alarmStatisticList1.get(0).get("ahAlarmCount").toString()));
        BigDecimal temp2 = new BigDecimal(Integer.valueOf(alarmStatisticList1.get(0).get("alarmCount").toString()));
        if (Integer.valueOf(alarmStatisticList1.get(0).get("alarmCount").toString()).equals(0)){
            map.put("ahAlarmYearCountBig", 0);
        }else {
            ahAlarmYearCountBig = ahAlarmYearCountBig.divide(temp2,2, RoundingMode.HALF_UP);
            map.put("ahAlarmYearCountBig", ahAlarmYearCountBig);
        }
        map.put("alarmDayCount", Integer.valueOf(alarmStatisticList.get(0).get("alarmCount").toString()));
        map.put("hiddenDayCount", Integer.valueOf(alarmStatisticList.get(0).get("hiddenCount").toString()));
        map.put("ahHiddenDayCount", Integer.valueOf(alarmStatisticList.get(0).get("ahHiddenCount").toString()));
        map.put("alarmYearCount", Integer.valueOf(alarmStatisticList1.get(0).get("alarmCount").toString()));
        map.put("uhAlarmCount", Integer.valueOf(alarmStatisticList2.get(0).get("alarmCount").toString()));
        map.put("fireAlarmCount", Integer.valueOf(alarmStatisticList2.get(0).get("fireAlarmCount").toString()));
        map.put("uhHiddenCount", Integer.valueOf(alarmStatisticList2.get(0).get("hiddenCount").toString()));
        list.add(map);
        return list;
    }
    @Override
    public List<Map<String,Object>> alarmStatisticDay(String startTime,String endTime) {
        List<Map<String,Object>> list = baseMapper.getAlarmStatisticDay(startTime,endTime,SecurityUtils.getTenantId());
        return list;
    }
}













