package com.ruoyi.ems.record.service.impl;

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

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ems.base.domain.EmsBaseCollectDeviceInfo;
import com.ruoyi.ems.base.domain.EmsBaseMonitorThreshold;
import com.ruoyi.ems.base.mapper.EmsBaseCollectDeviceInfoMapper;
import com.ruoyi.ems.base.mapper.EmsBaseMonitorThresholdMapper;
import com.ruoyi.ems.record.domain.EmsRecordAlarmRule;
import com.ruoyi.ems.record.domain.EmsRecordDnbInstant;
import com.ruoyi.ems.record.mapper.EmsRecordAlarmRuleMapper;
import com.ruoyi.ems.record.mapper.EmsRecordDnbInstantMapper;
import com.ruoyi.ems.report.domain.EmsReportPointDnb;
import com.ruoyi.ems.report.mapper.EmsReportPointDnbMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ems.record.mapper.EmsRecordAlarmDataMapper;
import com.ruoyi.ems.record.domain.EmsRecordAlarmData;
import com.ruoyi.ems.record.service.IEmsRecordAlarmDataService;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;

/**
 * 异常数据记录Service业务层处理
 *
 * @author Yinq
 * @date 2024-05-15
 */
@Service("AlarmDataService")
public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService {
    @Autowired
    private EmsRecordAlarmDataMapper emsRecordAlarmDataMapper;

    @Autowired
    private EmsRecordAlarmRuleMapper emsRecordAlarmRuleMapper;

    @Autowired
    private EmsBaseCollectDeviceInfoMapper emsBaseCollectDeviceInfoMapper;

    @Autowired
    private EmsRecordDnbInstantMapper emsRecordDnbInstantMapper;

    @Autowired
    private EmsBaseMonitorThresholdMapper emsBaseMonitorThresholdMapper;

    @Autowired
    private EmsReportPointDnbMapper emsReportPointDnbMapper;

    /**
     * 查询异常数据记录
     *
     * @param objId 异常数据记录主键
     * @return 异常数据记录
     */
    @Override
    public EmsRecordAlarmData selectEmsRecordAlarmDataByObjId(Long objId) {
        return emsRecordAlarmDataMapper.selectEmsRecordAlarmDataByObjId(objId);
    }

    /**
     * 查询异常数据记录列表
     *
     * @param emsRecordAlarmData 异常数据记录
     * @return 异常数据记录
     */
    @Override
    public List<EmsRecordAlarmData> selectEmsRecordAlarmDataList(EmsRecordAlarmData emsRecordAlarmData) {
        return emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(emsRecordAlarmData);
    }

    /**
     * 新增异常数据记录
     *
     * @param emsRecordAlarmData 异常数据记录
     * @return 结果
     */
    @Override
    public int insertEmsRecordAlarmData(EmsRecordAlarmData emsRecordAlarmData) {
        emsRecordAlarmData.setCreateTime(DateUtils.getNowDate());
        return emsRecordAlarmDataMapper.insertEmsRecordAlarmData(emsRecordAlarmData);
    }

    /**
     * 修改异常数据记录
     *
     * @param emsRecordAlarmData 异常数据记录
     * @return 结果
     */
    @Override
    public int updateEmsRecordAlarmData(EmsRecordAlarmData emsRecordAlarmData) {
        emsRecordAlarmData.setUpdateTime(DateUtils.getNowDate());
        return emsRecordAlarmDataMapper.updateEmsRecordAlarmData(emsRecordAlarmData);
    }

    /**
     * 批量删除异常数据记录
     *
     * @param objIds 需要删除的异常数据记录主键
     * @return 结果
     */
    @Override
    public int deleteEmsRecordAlarmDataByObjIds(Long[] objIds) {
        return emsRecordAlarmDataMapper.deleteEmsRecordAlarmDataByObjIds(objIds);
    }

    /**
     * 删除异常数据记录信息
     *
     * @param objId 异常数据记录主键
     * @return 结果
     */
    @Override
    public int deleteEmsRecordAlarmDataByObjId(Long objId) {
        return emsRecordAlarmDataMapper.deleteEmsRecordAlarmDataByObjId(objId);
    }

    /**
     * 处理异常数据
     *
     * @param objIds
     * @return
     */
    @Override
    public int handleExceptionsAlarmData(Long[] objIds) {
        for (Long objId : objIds) {
            EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
            alarmData.setObjId(objId);
            alarmData.setAlarmStatus(0L);
            alarmData.setOperationName(getUsername());
            alarmData.setOperationTime(DateUtils.getNowDate());
            emsRecordAlarmDataMapper.updateEmsRecordAlarmData(alarmData);
        }
        return 1;
    }

    /**
     * 采集设备告警定时任务
     */
    public void collectDeviceAlarmsTask() {
        long minuteValue = 1000 * 60;
        Date date = new Date();
        EmsRecordAlarmRule alarmRule = new EmsRecordAlarmRule();
        alarmRule.setTriggerRule(1L);
        List<EmsRecordAlarmRule> alarmRules = emsRecordAlarmRuleMapper.selectEmsRecordAlarmRuleList(alarmRule);
        if (alarmRules.size() > 0) {
            minuteValue = alarmRules.get(0).getDeviceOfflineTime() * minuteValue;
        } else {
            return;
        }

        EmsBaseCollectDeviceInfo collectDeviceInfo = new EmsBaseCollectDeviceInfo();
        collectDeviceInfo.setIsFlag("1");
        List<EmsBaseCollectDeviceInfo> deviceInfoList = emsBaseCollectDeviceInfoMapper.selectEmsBaseCollectDeviceInfoList(collectDeviceInfo);

        if (deviceInfoList.size() > 0) {
            EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
            recordAlarmData.setAlarmType(1L);
            recordAlarmData.setAlarmStatus(1L);
            List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
            List<String> collectDeviceIdList = alarmDataList.stream().map(EmsRecordAlarmData::getCollectDeviceId).collect(Collectors.toList());
            for (EmsBaseCollectDeviceInfo deviceInfo : deviceInfoList) {
                if (collectDeviceIdList.contains(deviceInfo.getCollectDeviceId())) {
                    continue;
                }
                if ((deviceInfo.getUpdateTime().getTime() + minuteValue) < date.getTime()) {
                    EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
                    alarmData.setCollectDeviceId(deviceInfo.getCollectDeviceId());
                    alarmData.setCollectTime(new Date());
                    alarmData.setAlarmType(1L);
                    alarmData.setAlarmStatus(1L);
                    alarmData.setAlarmData("设备离线已超过" + alarmRules.get(0).getDeviceOfflineTime() + "分钟");
                    this.insertEmsRecordAlarmData(alarmData);
                }
            }
        }
    }

    /**
     * 超过电阈值定时任务
     */
    public void exceedDnbThresholdAlarmsTask() {
        EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
        monitorThreshold.setMonitorType(2L);
        List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);

        EmsRecordDnbInstant dnbInstant = new EmsRecordDnbInstant();
        List<EmsRecordDnbInstant> dnbInstantList = emsRecordDnbInstantMapper.selectEmsRecordDnbInstantList(dnbInstant);
        Map<String, String> thresholdMap = compareThresholdAndRecord(thresholdList, dnbInstantList);
        //防止多次存入异常数据
        EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
        recordAlarmData.setAlarmType(0L);
        recordAlarmData.setAlarmStatus(1L);
        List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
        List<String> monitorIdList = alarmDataList.stream().map(EmsRecordAlarmData::getMonitorId).collect(Collectors.toList());
        for (String monitorId : thresholdMap.keySet()) {
            if (monitorIdList.contains(monitorId)) {
                continue;
            }
            EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
            alarmData.setMonitorId(monitorId);
            alarmData.setCollectTime(new Date());
            alarmData.setAlarmType(0L);
            alarmData.setAlarmStatus(1L);
            alarmData.setAlarmData(thresholdMap.get(monitorId));
            this.insertEmsRecordAlarmData(alarmData);
        }

    }

    /**
     * 超过电阈值 对比记录
     *
     * @param baseDnbThresholds
     * @param recordDnbInstants
     * @return
     */
    public Map<String, String> compareThresholdAndRecord(List<EmsBaseMonitorThreshold> baseDnbThresholds, List<EmsRecordDnbInstant> recordDnbInstants) {
        Map<String, String> resultMap = new HashMap<>();
        for (EmsRecordDnbInstant recordDnbInstant : recordDnbInstants) {
            String monitorCode = recordDnbInstant.getMonitorCode();
            EmsBaseMonitorThreshold baseDnbThreshold = null;
            for (EmsBaseMonitorThreshold threshold : baseDnbThresholds) {
                if (threshold.getMonitorCode().equals(monitorCode)) {
                    baseDnbThreshold = threshold;
                    break;
                }
            }
            if (baseDnbThreshold != null) {
                String reason = compare(recordDnbInstant, baseDnbThreshold);
                if (reason != null) {
                    resultMap.put(monitorCode, reason);
                }
            }
        }
        return resultMap;
    }

    private String compare(EmsRecordDnbInstant recordDnbInstant, EmsBaseMonitorThreshold baseDnbThreshold) {
        if (StringUtils.isNull(recordDnbInstant.getIA())) {
            return null;
        }
        BigDecimal zero = new BigDecimal("0.00");
        if (recordDnbInstant.getVA().compareTo(zero) == 0 || recordDnbInstant.getVB().compareTo(zero) == 0
                || recordDnbInstant.getVC().compareTo(zero) == 0) {
            return "缺项报警";
        }
        if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getiAMax()) > 0) {
            return "超过A相电流最大值";
        }
        if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getiBMax()) > 0) {
            return "超过B相电流最大值";
        }
        if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getiCMax()) > 0) {
            return "超过C相电流最大值";
        }
        if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getvAMax()) > 0) {
            return "超过A相电压最大值";
        }
        if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getvBMax()) > 0) {
            return "超过B相电压最大值";
        }
        if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getvCMax()) > 0) {
            return "超过C相电压最大值";
        }
        if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getiAMin()) < 0) {
            return "小于A相电流最小值";
        }
        if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getiBMin()) < 0) {
            return "小于B相电流最小值";
        }
        if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getiCMin()) < 0) {
            return "小于C相电流最小值";
        }
        if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getvAMin()) < 0) {
            return "小于A相电压最小值";
        }
        if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getvBMin()) < 0) {
            return "小于B相电压最小值";
        }
        if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getvCMin()) < 0) {
            return "小于C相电压最小值";
        }
        return null;
    }

    /**
     * 小时耗量告警定时任务
     */
    public void hourlyConsumptionAlarmsTask() {
        EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
        monitorThreshold.setMonitorType(2L);
        List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);
        for (EmsBaseMonitorThreshold threshold : thresholdList) {
            BigDecimal consumption = threshold.getHourConsumption();
            if (consumption.equals(new BigDecimal(0))){
                continue;
            }
            EmsReportPointDnb reportPointDnb = new EmsReportPointDnb();
            reportPointDnb.setMonitorCode(threshold.getMonitorCode());
            List<EmsReportPointDnb> dnbList = emsReportPointDnbMapper.selectEmsReportPointDnbList(reportPointDnb);

        }
    }

}
