package com.huatek.busi.service.impl.cable;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.huatek.busi.common.BusiConstant;
import com.huatek.busi.common.CacMonitorTypeCode;
import com.huatek.busi.common.SiteConstants;
import com.huatek.busi.dao.BusiCableCirculationtemperIncreaseRateCacheDao;
import com.huatek.busi.dao.BusiCableCirculationtemperIncreaseRateDao;
import com.huatek.busi.dto.BusiSensorQueryParamDto;
import com.huatek.busi.dto.EquipmentInfoDto;
import com.huatek.busi.entity.*;
import com.huatek.busi.mapper.cable.CableCirculationtemperIncreaseRateCacheMapper;
import com.huatek.busi.service.*;
import com.huatek.busi.service.cable.BusiOtherThresholdService;
import com.huatek.busi.service.cable.CableCirculationStatisticsService;
import com.huatek.busi.service.cable.CableCirculationtemperIncreaseRateService;
import com.huatek.busi.util.CalcUtil;
import com.huatek.busi.vo.BusiSensorVo;
import com.huatek.busi.vo.cable.BusiCableCirculationIncreaseRateVo;
import com.huatek.busi.vo.cable.BusiOtherThresholdVo;
import com.huatek.frame.base.util.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@Service(interfaceClass = CableCirculationtemperIncreaseRateService.class)
@Transactional(rollbackFor = Exception.class)
public class CableCirculationtemperIncreaseRateServiceImpl implements CableCirculationtemperIncreaseRateService {

    @Autowired
    private BusiOtherSensorService busiOtherSensorService;
    @Autowired
    private IBusiCableSensorService busiCableSensorService;

    @Autowired
    private CableCirculationStatisticsService cableCirculationStatisticsService;

    @Autowired
    private BusiCableCirculationtemperIncreaseRateCacheDao busiCableCirculationtemperIncreaseRateCacheDao;

    @Autowired
    private BusiCableCirculationtemperIncreaseRateDao busiCableCirculationtemperIncreaseRateDao;

    @Autowired
    CableCirculationtemperIncreaseRateCacheMapper cableCirculationtemperIncreaseRateCacheMapper;

    @Autowired
    private BusiOtherThresholdService busiOtherThresholdService;

    @Autowired
    private IBusiCableThresholdService busiCableThresholdService;

    @Autowired
    private BusiSubTreeService busiSubTreeService;

    @Autowired
    private BusiEqmWarningService busiEqmWarningService;

    @Override
    public void saveCableCirculationIncreaseRate(LocalDate day) {
        BusiSensorQueryParamDto busiSensorQueryParamDto = new BusiSensorQueryParamDto();
        // 其他电缆环流
        busiSensorQueryParamDto.setEquipmentType(SiteConstants.OtherTreeEnum.DLHL_EQM.getValue());
        List<BusiSensorVo> listOther = busiOtherSensorService.findSensorList(busiSensorQueryParamDto);
        if (!CollectionUtils.isEmpty(listOther)) {
            for (BusiSensorVo busiSensorVo : listOther) {
                //循环取得 busi_cable_circulation_statistics 数据进行计算
                saveCableIncreaseRate(busiSensorVo, day);
            }
        }
        // 电缆电缆环流
        busiSensorQueryParamDto.setEquipmentType(SiteConstants.CableTreeEnum.DLHL_EQM.getValue());
        List<BusiSensorVo> listCable = busiCableSensorService.findSensorList(busiSensorQueryParamDto);
        if (!CollectionUtils.isEmpty(listCable)) {
            for (BusiSensorVo busiSensorVo : listCable) {
                //循环取得 busi_cable_circulation_statistics 数据进行计算
                saveCableIncreaseRate(busiSensorVo, day);
            }
        }

    }

    @Override
    public String getMonthlyGrowThRate(String sensorCode, LocalDate day) {
        Map<String, Object> param = Maps.newLinkedHashMapWithExpectedSize(2);
        param.put("sensorCode", sensorCode);
        param.put("d_time", day);
        return getMonthlyGrowThRateBySensorCode(param);
    }

    private String getMonthlyGrowThRateBySensorCode(Map<String, Object> param) {
        Map<String, Object> MonthlyGrowthRate = cableCirculationtemperIncreaseRateCacheMapper.getMonthlyGrowThRateBySensorCode(param);
        if (CollectionUtils.isEmpty(MonthlyGrowthRate)) {
            return null;
        }
        Object GrowthRateObj = MonthlyGrowthRate.get("GrowthRate");
        String GrowthRate = (String) GrowthRateObj;
        return GrowthRate;
    }

    int saveCableIncreaseRate(BusiSensorVo busiSensorVo, LocalDate day) {
        cableCirculationtemperIncreaseRateCacheMapper.deleteItem(busiSensorVo.getSensorCode(), day);
        BusiCableCirculationIncreaseRateCache busiCableCirculationIncreaseRateCache = new BusiCableCirculationIncreaseRateCache();
        busiCableCirculationIncreaseRateCache.setSiteId(busiSensorVo.getSiteId());
        busiCableCirculationIncreaseRateCache.setSensorId(busiSensorVo.getSensorCode());
        busiCableCirculationIncreaseRateCache.setMainTreeId(busiSensorVo.getMainTreeId());
        busiCableCirculationIncreaseRateCache.setCreateTime(LocalDateTime.now());
        busiCableCirculationIncreaseRateCache.setDTime(day);
        busiCableCirculationIncreaseRateCache.setSubTreeId(busiSensorVo.getSubTreeId());

        //查询一天前的数据
        LocalDateTime startTime = day.atStartOfDay();
        LocalDateTime endTime = day.plusDays(1).atStartOfDay();
        Map<String, Object> obj = cableCirculationStatisticsService.getRecordBySensorCode(busiSensorVo.getSensorCode(),
                startTime, endTime);

        //查询二天前的数据
        BigDecimal prePression1 = new BigDecimal(0);
        LocalDate localday = day.minusDays(1);
        Map<String, Object> obj1 = cableCirculationStatisticsService.getRecordBySensorCode(busiSensorVo.getSensorCode(),
                localday.atStartOfDay(), localday.plusDays(1).atStartOfDay());

        if (obj != null && obj1 != null) {
            //日增长率
            BigDecimal rate = CalcUtil.calcRateEight(new BigDecimal(obj.get("totalCoreCurrent").toString()).subtract(new BigDecimal(obj1.get("totalCoreCurrent").toString())), (new BigDecimal(obj1.get("totalCoreCurrent").toString())));
            busiCableCirculationIncreaseRateCache.setDailyGrowthRate(rate.abs().toString());
            //月增长率
            busiCableCirculationIncreaseRateCache.setMonthlyGrowthRate(getMonthlyGrowthRate(busiSensorVo.getSensorCode(), day).toString());
        }

        BusiCableCirculationIncreaseRate busiCableCirculationIncreaseRate = new BusiCableCirculationIncreaseRate();
        BeanUtils.copyPropertiesWithIgnoreNull(busiCableCirculationIncreaseRateCache, busiCableCirculationIncreaseRate);
        //保存增长率
        busiCableCirculationtemperIncreaseRateDao.saveOrUpdate(busiCableCirculationIncreaseRate);
        //保存增长率到缓存表
        busiCableCirculationtemperIncreaseRateCacheDao.saveOrUpdate(busiCableCirculationIncreaseRateCache);
        //保存告警
        saveCableIncreaseRateWarning(busiCableCirculationIncreaseRate, day);

        return 0;
    }

    /**
     * 保存告警
     *
     * @param busiCableCirculationIncreaseRate
     */
    void saveCableIncreaseRateWarning(BusiCableCirculationIncreaseRate busiCableCirculationIncreaseRate, LocalDate day) {
        String sensorCode = busiCableCirculationIncreaseRate.getSensorId();
        BusiCableThreshold busiCableThreshold = busiCableThresholdService.getCableBySensorCodeThreshold(sensorCode);
        if (!ObjectUtils.isEmpty(busiCableThreshold)) {
            EquipmentInfoDto equipmentInfoCable = busiSubTreeService.findEquipmentInfo(sensorCode,
                    SiteConstants.SiteTreeEnum.DL.getValue());
            BusiCableSensor busiCableSensor = busiCableSensorService.findSensorBySensorCode(sensorCode);
            String eqType = BusiConstant.EqType.EQ_TYPE7;
            String gzType = BusiConstant.GzType.GZ_TYPE18;
            String cacMonitorTypeCode = CacMonitorTypeCode.DL_DLHL.getCode();
            if (!StringUtils.isEmpty(busiCableCirculationIncreaseRate.getDailyGrowthRate()) && !StringUtils.isEmpty(busiCableThreshold.getRelativeGrowthDayVal())) {
                if (isWarning(new BigDecimal(busiCableCirculationIncreaseRate.getDailyGrowthRate()), new BigDecimal(busiCableThreshold.getRelativeGrowthDayVal()))) {
                    // 保存告警
                    BusiEqmWarning busiEqmWarning =
                            busiEqmWarningService.saveBusiEqmWarning(equipmentInfoCable, eqType, gzType,
                                    cacMonitorTypeCode, day.atStartOfDay(), formateCableWarningMsg(busiCableSensor.getSensorName(), busiCableCirculationIncreaseRate.getDailyGrowthRate()), "1");
                    // 保存告警详情
                    BusiCableCirculationIncreaseRateVo vo = new BusiCableCirculationIncreaseRateVo();
                    vo.setMainTreeId(busiCableThreshold.getMainTreeId());
                    vo.setDailyGrowthRate(busiCableCirculationIncreaseRate.getDailyGrowthRate());
                    vo.setDTime(day);
                    vo.setRelativeGrowthDayVal(busiCableThreshold.getRelativeGrowthDayVal());
                    vo.setRelativeGrowthMonthVal(busiCableThreshold.getRelativeGrowthMonthVal());
                    vo.setRelativeGrowthPrewarningDayVal(busiCableThreshold.getRelativeGrowthPrewarningDayVal());
                    vo.setRelativeGrowthPrewarningMonthVal(busiCableThreshold.getRelativeGrowthPrewarningMonthVal());
                    busiEqmWarningService.saveBusiEqmWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
                }
            }

            if (!StringUtils.isEmpty(busiCableCirculationIncreaseRate.getMonthlyGrowthRate()) && !StringUtils.isEmpty(busiCableThreshold.getRelativeGrowthMonthVal())) {
                if (isWarning(new BigDecimal(busiCableCirculationIncreaseRate.getMonthlyGrowthRate()), new BigDecimal(busiCableThreshold.getRelativeGrowthMonthVal()))) {
                    // 保存告警
                    BusiEqmWarning busiEqmWarning =
                            busiEqmWarningService.saveBusiEqmWarning(equipmentInfoCable, eqType, gzType,
                                    cacMonitorTypeCode, day.atStartOfDay(), formateCableWarningMsg(busiCableSensor.getSensorName(), busiCableCirculationIncreaseRate.getMonthlyGrowthRate()), "1");
                    // 保存告警详情
                    BusiCableCirculationIncreaseRateVo vo = new BusiCableCirculationIncreaseRateVo();
                    vo.setMainTreeId(busiCableThreshold.getMainTreeId());
                    vo.setMonthlyGrowthRate(busiCableCirculationIncreaseRate.getMonthlyGrowthRate());
                    vo.setDTime(day);
                    vo.setRelativeGrowthDayVal(busiCableThreshold.getRelativeGrowthDayVal());
                    vo.setRelativeGrowthMonthVal(busiCableThreshold.getRelativeGrowthMonthVal());
                    vo.setRelativeGrowthPrewarningDayVal(busiCableThreshold.getRelativeGrowthPrewarningDayVal());
                    vo.setRelativeGrowthPrewarningMonthVal(busiCableThreshold.getRelativeGrowthPrewarningMonthVal());
                    busiEqmWarningService.saveBusiEqmWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
                }
            }
        }

        BusiOtherThreshold busiOtherThreshold = busiOtherThresholdService.getCableThreshold(sensorCode);
        if (!ObjectUtils.isEmpty(busiOtherThreshold)) {

            EquipmentInfoDto equipmentInfo = busiSubTreeService.findEquipmentInfo(sensorCode,
                    SiteConstants.SiteTreeEnum.OTHER.getValue());
            BusiOtherSensor busiOtherSensor = busiOtherSensorService.findSensorBySensorCode(sensorCode);

            String eqType = BusiConstant.EqType.EQ_TYPE5;
            String gzType = BusiConstant.GzType.GZ_TYPE18;
            String cacMonitorTypeCode = CacMonitorTypeCode.OTHER_DLHL.getCode();
            if (!StringUtils.isEmpty(busiCableCirculationIncreaseRate.getDailyGrowthRate()) && !StringUtils.isEmpty(busiOtherThreshold.getRelativeGrowthDayVal())) {
                if (isWarning(new BigDecimal(busiCableCirculationIncreaseRate.getDailyGrowthRate()), new BigDecimal(busiOtherThreshold.getRelativeGrowthDayVal()))) {
                    // 保存告警
                    BusiEqmWarning busiEqmWarning =
                            busiEqmWarningService.saveBusiEqmWarning(equipmentInfo, eqType, gzType,
                                    cacMonitorTypeCode, day.atStartOfDay(), formateCableWarningMsg(busiOtherSensor.getSensorName(), busiCableCirculationIncreaseRate.getDailyGrowthRate()), "1");
                    // 保存告警详情
                    BusiCableCirculationIncreaseRateVo vo = new BusiCableCirculationIncreaseRateVo();
                    vo.setMainTreeId(busiOtherThreshold.getMainTreeId());
                    vo.setDailyGrowthRate(busiCableCirculationIncreaseRate.getDailyGrowthRate());
                    vo.setDTime(day);
                    vo.setRelativeGrowthDayVal(busiOtherThreshold.getRelativeGrowthDayVal());
                    vo.setRelativeGrowthMonthVal(busiOtherThreshold.getRelativeGrowthMonthVal());
                    vo.setRelativeGrowthPrewarningDayVal(busiOtherThreshold.getRelativeGrowthPrewarningDayVal());
                    vo.setRelativeGrowthPrewarningMonthVal(busiOtherThreshold.getRelativeGrowthPrewarningMonthVal());
                    busiEqmWarningService.saveBusiEqmWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
                }
            }

            if (!StringUtils.isEmpty(busiCableCirculationIncreaseRate.getMonthlyGrowthRate()) && !StringUtils.isEmpty(busiOtherThreshold.getRelativeGrowthMonthVal())) {
                if (isWarning(new BigDecimal(busiCableCirculationIncreaseRate.getMonthlyGrowthRate()), new BigDecimal(busiOtherThreshold.getRelativeGrowthMonthVal()))) {
                    // 保存告警
                    BusiEqmWarning busiEqmWarning =
                            busiEqmWarningService.saveBusiEqmWarning(equipmentInfo, eqType, gzType,
                                    cacMonitorTypeCode, day.atStartOfDay(), formateCableWarningMsg(busiOtherSensor.getSensorName(), busiCableCirculationIncreaseRate.getMonthlyGrowthRate()), "1");
                    // 保存告警详情
                    BusiCableCirculationIncreaseRateVo vo = new BusiCableCirculationIncreaseRateVo();
                    vo.setMainTreeId(busiOtherThreshold.getMainTreeId());
                    vo.setMonthlyGrowthRate(busiCableCirculationIncreaseRate.getMonthlyGrowthRate());
                    vo.setDTime(day);
                    vo.setRelativeGrowthDayVal(busiOtherThreshold.getRelativeGrowthDayVal());
                    vo.setRelativeGrowthMonthVal(busiOtherThreshold.getRelativeGrowthMonthVal());
                    vo.setRelativeGrowthPrewarningDayVal(busiOtherThreshold.getRelativeGrowthPrewarningDayVal());
                    vo.setRelativeGrowthPrewarningMonthVal(busiOtherThreshold.getRelativeGrowthPrewarningMonthVal());
                    busiEqmWarningService.saveBusiEqmWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
                }
            }
        }
    }

    private static boolean isWarning(BigDecimal growthRate, BigDecimal thresholdValue) {
        return growthRate.compareTo(thresholdValue) > 0;
    }

    private String formateCableWarningMsg(String phase, String tmp) {
        return String.format("%s电缆环流：%s%%增长率告警", phase, tmp);
    }

    // 获取月增长率
    public BigDecimal getMonthlyGrowthRate(String sensorCode, LocalDate day) {
        // 获取月初的泄露率
        //获取当前时间泄露率
        Map<String, Object> current = cableCirculationStatisticsService.getItem(sensorCode, day);
        //获取当前时间前30天泄露率
        Map<String, Object> before = cableCirculationStatisticsService.getItem(sensorCode, day.minusDays(30));
        if (current != null && before != null) {
            String rate1 = current.get("totalCoreCurrent").toString();
            // 获取月末泄露率
            String rate2 = before.get("totalCoreCurrent").toString();
            BigDecimal b1 = new BigDecimal(rate1);
            BigDecimal b2 = new BigDecimal(rate2);
            BigDecimal rate = CalcUtil.calcRate(b2.subtract(b1), b1);
            return rate;
        } else {
            return BigDecimal.ZERO;
        }
    }
}
