package com.yeejoin.equipmanage.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.entity.dto.EquipmentAlarmLogDto;
import com.yeejoin.equipmanage.common.entity.vo.EquiplistSpecificBySystemVO;
import com.yeejoin.equipmanage.common.enums.AlarmStatusEnum;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import com.yeejoin.equipmanage.fegin.IotFeign;
import com.yeejoin.equipmanage.fegin.VideoFeignClient;
import com.yeejoin.equipmanage.mapper.*;
import com.yeejoin.equipmanage.service.IESeqService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificAlarmLogService;
import liquibase.pro.packaged.S;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author keyong
 * @title: EquipmentSpecificAlarmLogServiceImpl
 * <pre>
 * @description:
 * </pre>
 * @date 2021/8/19 10:37
 */
@Service
public class EquipmentSpecificAlarmLogServiceImpl extends ServiceImpl<EquipmentSpecificAlarmLogMapper, EquipmentSpecificAlarmLog> implements IEquipmentSpecificAlarmLogService {

    @Autowired
    EquipmentSpecificAlarmLogMapper equipmentSpecificAlarmLogMapper;

    @Autowired
    EquipmentSpecificAlarmMapper equipmentSpecificAlarmMapper;

    @Autowired
    EquipmentSpecificMapper equipmentSpecificMapper;

    @Autowired
    EquipmentSpecificAlarmServiceImpl equipmentSpecificAlarmService;


    @Autowired
    EquipmentIndexMapper equipmentIndexMapper;

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

    @Autowired
    VideoFeignClient videoFeignClient;

    @Autowired
    IotFeign iotFeign;
    @Autowired
    IESeqService eSeqService;

    @Override
    public void updateAlarmLogByIotCodeAndIndexKey(EquipmentSpecificAlarm equipmentSpecificAlarm) {
        equipmentSpecificAlarmLogMapper.updateAlarmLogByIotCodeAndIndexKey(equipmentSpecificAlarm);
    }

    @Override
    public List<EquipmentSpecificAlarmLog> getIsConfirmByAlarmId(Long equipmentSpecificId, String equipmentSpecificIndexKey, String isConfirm) {
        List<EquipmentSpecificAlarmLog> list = equipmentSpecificAlarmLogMapper.getIsConfirmByAlarmId(equipmentSpecificId, equipmentSpecificIndexKey, isConfirm);
        if (CollectionUtils.isNotEmpty(list)) {
            return list;
        }
        return Lists.newArrayList();
    }

    @Override
    public Map<String, Object> equipAlarmLink(String date) {
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isBlank(date)) {
            date = DateUtils.convertDateToString(new Date(), "yyyy-MM-dd");
        }
        String monthDate = date.substring(0, 7);
        //  获取今日告警设备、日环比
        Map<String, Object> alarmEquipDayLink = equipmentSpecificAlarmLogMapper.alarmEquipLink(date, "%Y-%m-%d", null);
        BigDecimal bigDecimal = BigDecimal.ZERO;
        BigDecimal nowDaySum = new BigDecimal(String.valueOf(alarmEquipDayLink.get("sumNum")));
        BigDecimal lastDaySum = new BigDecimal(String.valueOf(alarmEquipDayLink.get("hbSumNum")));
        if ("0".equals(String.valueOf(alarmEquipDayLink.get("sumNum")))
                || "0".equals(String.valueOf(alarmEquipDayLink.get("hbSumNum")))
                || 0 > (Integer.valueOf(String.valueOf(alarmEquipDayLink.get("sumNum"))) - Integer.valueOf(String.valueOf(alarmEquipDayLink.get("hbSumNum"))))) {
            alarmEquipDayLink.put("hbRate", bigDecimal + "%");
        } else {
            BigDecimal rate = nowDaySum.subtract(lastDaySum).divide(lastDaySum, 2, BigDecimal.ROUND_HALF_UP);
            alarmEquipDayLink.put("hbRate", "0.00".equals(String.valueOf(rate)) ? "0%" : rate + "%");
        }

        //  获取今日告警设备、月环比
        Map<String, Object> alarmEquipMonthLink = equipmentSpecificAlarmLogMapper.alarmEquipLink(monthDate, "%Y-%m", null);
        BigDecimal nowMonthSum = new BigDecimal(String.valueOf(alarmEquipMonthLink.get("sumNum")));
        BigDecimal lastMonthSum = new BigDecimal(String.valueOf(alarmEquipMonthLink.get("hbSumNum")));
        if ("0".equals(String.valueOf(alarmEquipMonthLink.get("sumNum")))
                || "0".equals(String.valueOf(alarmEquipMonthLink.get("hbSumNum")))
                || 0 > (Integer.valueOf(String.valueOf(alarmEquipMonthLink.get("sumNum"))) - Integer.valueOf(String.valueOf(alarmEquipMonthLink.get("hbSumNum"))))) {
            alarmEquipMonthLink.put("hbRate", bigDecimal + "%");
        } else {
            BigDecimal rate = nowMonthSum.subtract(lastMonthSum).divide(lastMonthSum, 2, BigDecimal.ROUND_HALF_UP);
            alarmEquipMonthLink.put("hbRate", "0.00".equals(String.valueOf(rate)) ? "0%" : rate + "%");
        }
        //  获取未消除告警设备，日环比
        Map<String, Object> unCleanAlarmEquipDayLink = equipmentSpecificAlarmLogMapper.unCleanAlarmEquipLink(date, "%Y-%m-%d", "unClean");
        BigDecimal nowUncleanDaySum = new BigDecimal(String.valueOf(unCleanAlarmEquipDayLink.get("sumNum")));
        BigDecimal lastUncleanDaySum = new BigDecimal(String.valueOf(unCleanAlarmEquipDayLink.get("hbSumNum")));
        if ("0".equals(String.valueOf(unCleanAlarmEquipDayLink.get("sumNum")))
                || "0".equals(String.valueOf(unCleanAlarmEquipDayLink.get("hbSumNum")))
                || 0 > (Integer.valueOf(String.valueOf(unCleanAlarmEquipDayLink.get("sumNum"))) - Integer.valueOf(String.valueOf(unCleanAlarmEquipDayLink.get("hbSumNum"))))) {
            unCleanAlarmEquipDayLink.put("hbRate", bigDecimal + "%");
        } else {
            BigDecimal rate = nowUncleanDaySum.subtract(lastUncleanDaySum).divide(lastUncleanDaySum, 2, BigDecimal.ROUND_HALF_UP);
            unCleanAlarmEquipDayLink.put("hbRate", "0.00".equals(String.valueOf(rate)) ? "0%" : rate + "%");
        }

        //  获取未消除告警设备，月环比
        Map<String, Object> unCleanAlarmEquipMonthLink = equipmentSpecificAlarmLogMapper.unCleanAlarmEquipLink(monthDate, "%Y-%m", "unClean");
        BigDecimal nowUncleanMonthSum = new BigDecimal(String.valueOf(unCleanAlarmEquipMonthLink.get("sumNum")));
        BigDecimal lastUncleanMonthSum = new BigDecimal(String.valueOf(unCleanAlarmEquipMonthLink.get("hbSumNum")));
        if ("0".equals(String.valueOf(unCleanAlarmEquipMonthLink.get("sumNum")))
                || "0".equals(String.valueOf(unCleanAlarmEquipMonthLink.get("hbSumNum")))
                || 0 > (Integer.valueOf(String.valueOf(unCleanAlarmEquipMonthLink.get("sumNum"))) - Integer.valueOf(String.valueOf(unCleanAlarmEquipMonthLink.get("hbSumNum"))))) {
            unCleanAlarmEquipMonthLink.put("hbRate", bigDecimal + "%");
        } else {
            BigDecimal rate = nowUncleanMonthSum.subtract(lastUncleanMonthSum).divide(lastUncleanMonthSum, 2, BigDecimal.ROUND_HALF_UP);
            unCleanAlarmEquipMonthLink.put("hbRate", "0.00".equals(String.valueOf(rate)) ? "0%" : rate + "%");
        }
        map.put("alarmEquipDayLink", alarmEquipDayLink);
        map.put("alarmEquipMonthLink", alarmEquipMonthLink);
        map.put("unCleanAlarmEquipDayLink", unCleanAlarmEquipDayLink);
        map.put("unCleanAlarmEquipMonthLink", unCleanAlarmEquipMonthLink);
        return map;
    }

    @Override
    public List<EquipmentSpecificAlarmLog> getAlarmLogInfoList(String equipmentCode, String nameKeys, String value, String isCleanTime, String bizOrgCode) {
        return equipmentSpecificAlarmLogMapper.getAlarmLogInfoList(equipmentCode, nameKeys, value, isCleanTime, bizOrgCode);
    }

    @Override
    public  Page<EquipmentAlarmLogDto> getEquipAlarmLog(String code, String startTime, String endTime,long pageSize, long current)  {
        Page<EquipmentAlarmLogDto> pageBean = new Page<EquipmentAlarmLogDto>(current,pageSize);
       try {
           QueryWrapper<FireFightingSystemEntity> wrapper = new QueryWrapper<>();
           wrapper.eq("code", code);
           FireFightingSystemEntity sys = fireFightingSystemMapper.selectOne(wrapper);
           if(sys==null){
               throw new BadRequest("系统不存在！");
           }
           String systemId =sys.getId().toString();
           //获取时间梭
           SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


           Long LongstartTime=format.parse(startTime).getTime();

           Long LongendTime=format.parse(endTime.replace("00:00:00","23:59:59")).getTime();

           pageBean= eSeqService.findAllBySystemId(systemId,  LongstartTime, LongendTime, (int) pageSize,  (int)current);

       }catch (Exception e) {
           e.printStackTrace();
           throw  new BadRequest("系统异常");
       }
        return pageBean;
    }

    @Override
    public void updateStatusByAlarm() {
    String confirmUserName = "系统自动处理";
    String resolveResult = DateUtils.getDateNowString()+"系统收到设备复归（已消除）信号，系统自动处理。";
    String confirmTypeName = "故障";
    equipmentSpecificAlarmMapper.updateStatusByAlarm();
    equipmentSpecificAlarmLogMapper.updateStatusByAlarm(confirmUserName,resolveResult,confirmTypeName);

    }


    public void getEquiplistBySystemIdList(String id,  Map<String, EquiplistSpecificBySystemVO> map, List<String> iotCodes) {

        //获取系统下所有装备
        List<EquiplistSpecificBySystemVO> list = fireFightingSystemMapper.getEquiplistBySystemIdList(Long.valueOf(id));
        if (!list.isEmpty()) {
            for (EquiplistSpecificBySystemVO equiplistSpecificBySystemVO : list) {
                 map.put(equiplistSpecificBySystemVO.getIotCode()+equiplistSpecificBySystemVO.getIndexKey(),equiplistSpecificBySystemVO);
                 iotCodes.add(equiplistSpecificBySystemVO.getIotCode()+equiplistSpecificBySystemVO.getIndexKey());
            }
        }
    }


    @Override
    public void pressurePumpDisposeAlarm(Long equipmentSpecificId, String body) {
        EquipmentSpecific equipmentSpecific = equipmentSpecificMapper.selectById(equipmentSpecificId);
        EquipmentSpecificAlarm equipmentSpecificAlarm = new EquipmentSpecificAlarm();
        String sysCodes = null;
        Map<String, Object> stationCode = equipmentSpecificMapper.getStationCode(equipmentSpecificId);
        EquipmentIndex equipmentIndex = equipmentIndexMapper.getMessage(equipmentSpecificId, pressurePumpStart);
        LambdaQueryWrapper<EquipmentSpecificAlarm> lambda = new QueryWrapper<EquipmentSpecificAlarm>().lambda();
        lambda.eq(EquipmentSpecificAlarm::getEquipmentSpecificId, equipmentSpecific.getId());
        lambda.eq(EquipmentSpecificAlarm::getEquipmentSpecificIndexKey, pressurePumpStart);
        lambda.eq(EquipmentSpecificAlarm::getStatus, AlarmStatusEnum.BJ.getCode());
        lambda.orderByDesc(EquipmentSpecificAlarm::getCreateDate);
        lambda.last("limit 1");
        EquipmentSpecificAlarm specificAlarm = equipmentSpecificAlarmMapper.selectOne(lambda);
        // 已存在稳压泵漏水告警信息，告警频率+1
        if (!ObjectUtils.isEmpty(specificAlarm)) {
            specificAlarm.setFrequency(specificAlarm.getFrequency() + 1);
            equipmentSpecificAlarmMapper.updateById(specificAlarm);
            BeanUtils.copyProperties(specificAlarm, equipmentSpecificAlarm);
        } else {
            equipmentSpecificAlarm.setEquipmentSpecificId(equipmentSpecific.getId());
            equipmentSpecificAlarm.setEquipmentSpecificName(equipmentSpecific.getName());
            equipmentSpecificAlarm.setOrgCode(equipmentSpecific.getOrgCode());
            equipmentSpecificAlarm.setIotCode(equipmentSpecific.getIotCode());
            equipmentSpecificAlarm.setEquipmentSpecificIndexName("漏水提醒");
            equipmentSpecificAlarm.setEquipmentSpecificIndexKey(equipmentIndex.getPerfQuotaDefinitionId());
            equipmentSpecificAlarm.setEquipmentSpecificIndexValue("true");
            equipmentSpecificAlarm.setStatus(AlarmStatusEnum.BJ.getCode());
            equipmentSpecificAlarm.setFrequency(1);
            equipmentSpecificAlarm.setType(equipmentIndex.getTypeCode());
            equipmentSpecificAlarm.setEquipmentIndexId(equipmentIndex.getId());
            equipmentSpecificAlarm.setSystemIds(equipmentSpecific.getSystemId());
            equipmentSpecificAlarm.setEquipmentCode(equipmentSpecific.getEquipmentCode());
            equipmentSpecificAlarm.setEquipmentDetailId(equipmentSpecific.getEquipmentDetailId());
            equipmentSpecificAlarm.setLocation(equipmentSpecific.getPosition());
            equipmentSpecificAlarm.setBizOrgCode(equipmentSpecific.getBizOrgCode());
            equipmentSpecificAlarm.setBizOrgName(equipmentSpecific.getBizOrgName());
            equipmentSpecificAlarm.setEmergencyLevel(equipmentIndex.getEmergencyLevel());
            equipmentSpecificAlarm.setEmergencyLevelColor(equipmentIndex.getEmergencyLevelColor());
            equipmentSpecificAlarm.setEmergencyLevelDescribe(equipmentIndex.getEmergencyLevelDescribe());
            equipmentSpecificAlarm.setEquipmentId(ObjectUtils.isEmpty(equipmentIndex.getEquipmentId()) ? null : Long.parseLong(equipmentIndex.getEquipmentId()));
            if (!ObjectUtils.isEmpty(stationCode)) {
                equipmentSpecificAlarm.setStationCode(stationCode.get("station_code").toString());
                equipmentSpecificAlarm.setStationName(stationCode.get("station_name").toString());
            }

            if (!ObjectUtils.isEmpty(equipmentSpecificAlarm.getSystemIds())) {
                sysCodes = getSysCodes(equipmentSpecificAlarm.getSystemIds());
                equipmentSpecificAlarm.setSystemCodes(ObjectUtils.isEmpty(sysCodes) ? null : sysCodes);
            }
            equipmentSpecificAlarmMapper.insert(equipmentSpecificAlarm);
        }

        EquipmentSpecificAlarmLog equipmentSpecificAlarmLog = new EquipmentSpecificAlarmLog();
        BeanUtils.copyProperties(equipmentSpecificAlarm, equipmentSpecificAlarmLog);
        equipmentSpecificAlarmLog.setId(null);
        equipmentSpecificAlarmLog.setEquipmentSpecificIndexName(body);
        equipmentSpecificAlarmLog.setEquipmentSpecificAlarmId(equipmentSpecificAlarm.getId());
        equipmentSpecificAlarmLog.setEquipmentSpecificCode(equipmentSpecific.getCode());
        equipmentSpecificAlarmLog.setEquipmentId(ObjectUtils.isEmpty(equipmentIndex.getEquipmentId()) ? null : Long.parseLong(equipmentIndex.getEquipmentId()));
        equipmentSpecificAlarmLog.setBuildId(equipmentSpecific.getWarehouseStructureId().toString());
        equipmentSpecificAlarmLog.setEmergencyLevel(equipmentIndex.getEmergencyLevel());
        equipmentSpecificAlarmLog.setEmergencyLevelColor(equipmentIndex.getEmergencyLevelColor());
        equipmentSpecificAlarmLog.setEmergencyLevelDescribe(equipmentIndex.getEmergencyLevelDescribe());

        if (!ObjectUtils.isEmpty(sysCodes)) {
            equipmentSpecificAlarmLog.setSystemCodes(sysCodes);
        }
        if (!ObjectUtils.isEmpty(stationCode)) {
            equipmentSpecificAlarmLog.setStationCode(stationCode.get("station_code").toString());
            equipmentSpecificAlarmLog.setStationName(stationCode.get("station_name").toString());
        }
        equipmentSpecificAlarmLogMapper.insert(equipmentSpecificAlarmLog);

    }

    private String getSysCodes(String systemId){
        if (!ObjectUtils.isEmpty(systemId)) {
            List<FireFightingSystemEntity> codes = fireFightingSystemMapper.getFightingSysByIds(systemId.split(","));
            if (!ObjectUtils.isEmpty(codes)) {
               return  codes.stream().map(FireFightingSystemEntity::getCode).collect(Collectors.joining(","));
            }
        }
        return null;
    }

    @Override
    public void pressurePumpRestore(Long equipmentSpecificId) {
        // 修改报警数据为正常
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(date);
        LambdaQueryWrapper<EquipmentSpecificAlarm> lambda = new QueryWrapper<EquipmentSpecificAlarm>().lambda();
        lambda.eq(EquipmentSpecificAlarm::getEquipmentSpecificId, equipmentSpecificId);
        lambda.eq(EquipmentSpecificAlarm::getStatus, AlarmStatusEnum.BJ.getCode());
        lambda.eq(EquipmentSpecificAlarm::getEquipmentSpecificIndexKey, pressurePumpStart);
        List<EquipmentSpecificAlarm> equipmentSpecificAlarms = equipmentSpecificAlarmMapper.selectList(lambda);
        if (!ObjectUtils.isEmpty(equipmentSpecificAlarms)){
            equipmentSpecificAlarms.forEach(item ->{
                item.setStatus(AlarmStatusEnum.HF.getCode());
                item.setRecoveryDate(date);
                item.setConfirmType(item.getType());
                item.setEquipmentSpecificIndexValue("false");
            });
            equipmentSpecificAlarmService.saveOrUpdateBatch(equipmentSpecificAlarms);

        }
        LambdaQueryWrapper<EquipmentSpecificAlarmLog> lambdaLog = new QueryWrapper<EquipmentSpecificAlarmLog>().lambda();
        lambdaLog.eq(EquipmentSpecificAlarmLog::getEquipmentSpecificId, equipmentSpecificId);
        lambdaLog.eq(EquipmentSpecificAlarmLog::getStatus, AlarmStatusEnum.BJ.getCode());
        lambdaLog.eq(EquipmentSpecificAlarmLog::getEquipmentSpecificIndexKey, pressurePumpStart);
        List<EquipmentSpecificAlarmLog> equipmentSpecificAlarmLogs = equipmentSpecificAlarmLogMapper.selectList(lambdaLog);
        if (!ObjectUtils.isEmpty(equipmentSpecificAlarmLogs)){
            equipmentSpecificAlarmLogs.forEach(item ->{
                item.setAlarmReason(item.getEquipmentSpecificName() + "引起设备报警");
                item.setResolveResult(dateString + "系统收到设备复归（已消除）信号，系统自动处理。");
                item.setConfirmUser("");
                item.setConfirmUserName("系统自动处理");
                item.setConfirmDate(date);
                item.setCleanTime(date);
                item.setConfirmType(item.getType());
                item.setEquipmentSpecificIndexValue("false");
                item.setStatus(AlarmStatusEnum.HF.getCode());
            });
            this.updateBatchById(equipmentSpecificAlarmLogs);
        }
    }
}