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

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.huatek.busi.common.BusiConstant.EqType;
import com.huatek.busi.common.BusiConstant.GzType;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.common.util.DecimalUtil;
import com.huatek.busi.common.util.Tools;
import com.huatek.busi.dao.GisSf6IncreaseRateCacheDao;
import com.huatek.busi.dto.EquipmentInfoDto;
import com.huatek.busi.entity.BusiEqmWarning;
import com.huatek.busi.entity.BusiGisSensor;
import com.huatek.busi.entity.GisSf6IncreaseRateCache;
import com.huatek.busi.mapper.GisSf6IncreaseRateCacheMapper;
import com.huatek.busi.mapper.GisSf6PressureMapper;
import com.huatek.busi.service.BusiEqmWarningService;
import com.huatek.busi.service.BusiSubTreeService;
import com.huatek.busi.service.gis.BusiGisSensorService;
import com.huatek.busi.service.gis.GisSF6ThresholdService;
import com.huatek.busi.service.gis.GisSf6IncreaseRateCacheService;
import com.huatek.busi.util.CalcUtil;
import com.huatek.busi.vo.GisSf6PressureStatisticsVo;
import com.huatek.busi.vo.GisSf6ThresholdVo;
import com.huatek.busi.vo.warning.BusiGisSf6ItemVo;
import com.huatek.busi.vo.warning.BusiGisSf6ItemVo.BusiGisSf6ItemVoBuilder;
import com.huatek.busi.vo.warning.BusiGisSf6Vo;

import lombok.extern.slf4j.Slf4j;

/**
 * sf6温度、微水、压力增长率暂存表 ServiceImpl
 *
 * @author anker_cheng
 * @date Oct 23, 2019 8:55:28 PM
 */
@Slf4j
@Component
@Service(interfaceClass = GisSf6IncreaseRateCacheService.class)
@Transactional(rollbackFor = Exception.class)
public class GisSf6IncreaseRateCacheServiceImpl implements GisSf6IncreaseRateCacheService {

	@Autowired
	private GisSf6IncreaseRateCacheMapper gisSf6IncreaseRateCacheMapper;
	@Autowired
	private GisSf6IncreaseRateCacheDao gisSf6IncreaseRateCacheDao;
	@Autowired
	private GisSf6PressureMapper gisSf6PressureMapper;
	@Autowired
	private GisSF6ThresholdService gisSF6ThresholdService;
	@Autowired
	private BusiSubTreeService busiSubTreeService;
	@Autowired
	private BusiEqmWarningService busiEqmWarningService;
	@Autowired
	private BusiGisSensorService busiGisSensorService;

	@Override
	public synchronized void saveGisSf6PressureGrowthRate(LocalDate day, GisSf6PressureStatisticsVo item) {
		// 删除当天的
		gisSf6IncreaseRateCacheMapper.deleteItem(item.getSensorCode(), day);
		// 保存新记录
		GisSf6IncreaseRateCache entity = new GisSf6IncreaseRateCache();
		entity.setSiteId(item.getSiteId());
		entity.setSensorId(item.getSensorCode());
		entity.setMainTreeId(item.getMainTreeId());
		entity.setSubTreeId(item.getSubTreeId());
		entity.setDTime(day);
		entity.setCreateTime(LocalDateTime.now());
		entity.setAvgTemperature(DecimalUtil.toStr(item.getAvgTemperature()));
		entity.setAvgAbsolutePressure(DecimalUtil.toStr(item.getAvgAbsolutePressure()));
		entity.setAvgDensity(DecimalUtil.toStr(item.getAvgDensity()));
		entity.setAvgMoisture(DecimalUtil.toStr(item.getAvgMoisture()));
		entity.setAvgPressure20C(DecimalUtil.toStr(item.getAvgPressure20C()));
		entity.setIncreaseTemperature("0");
		entity.setIncreaseAbsolutePressure("0");
		entity.setIncreaseDensity("0");
		entity.setIncreaseMoisture("0");
		// 日泄露率
		entity.setIncreasePressure20C("0");
		entity.setMonthIncreasePressure20C("0");

		GisSf6IncreaseRateCache previous = gisSf6IncreaseRateCacheMapper.getItem(item.getSensorCode(),
				day.minusDays(1));
		if (previous != null) {

			// 获取前一天的
			BigDecimal prePression = new BigDecimal(0);
			LocalDateTime startTime = day.atStartOfDay();
			LocalDateTime endTime = day.plusDays(1).atStartOfDay();
			List<Map<String, Object>> listObj = gisSf6PressureMapper.getRecordBySensorCode(item.getSensorCode(),
					startTime, endTime);
			if (listObj == null) {
				entity.setIncreasePressure20C("0");
			} else {
				List<BigDecimal> listRes = new ArrayList<BigDecimal>();
				for (Map<String, Object> mapObj : listObj) {
					if(mapObj.get("pressure") != null)
					{
						listRes.add(new BigDecimal(mapObj.get("pressure").toString()));
					}
				}
				if(!listRes.isEmpty())
				{
					prePression = CalcUtil.avgInfo(listRes);
				}
			}

			// 获取前两天数据
			BigDecimal prePression1 = new BigDecimal(0);
			LocalDate localday = day.minusDays(1);
			List<Map<String, Object>> listObj1 = gisSf6PressureMapper.getRecordBySensorCode(item.getSensorCode(),
					localday.atStartOfDay(), localday.plusDays(1).atStartOfDay());
			List<BigDecimal> listRes1 = new ArrayList<BigDecimal>();
			if (listObj1 == null) {
				entity.setIncreasePressure20C("0");
			} else {
				for (Map<String, Object> mapObj1 : listObj1) {
					if(mapObj1.get("pressure") != null)
					{
						listRes1.add(new BigDecimal(mapObj1.get("pressure").toString()));
					}
				}
				if(!listRes1.isEmpty())
				{
					prePression1 = CalcUtil.avgInfo(listRes1);
				}
			}

			if (prePression1.compareTo(BigDecimal.ZERO) == 0) {
				entity.setIncreasePressure20C("0");
			} else {
				BigDecimal rate = CalcUtil.calcRateEight(prePression.subtract(prePression1), prePression1);		
				entity.setIncreasePressure20C(rate.abs().toString());
			}

			entity.setIncreaseTemperature(
					DecimalUtil.calIncrease(item.getAvgTemperature(), previous.getAvgTemperature()));
			entity.setIncreaseAbsolutePressure(
					DecimalUtil.calIncrease(item.getAvgAbsolutePressure(), previous.getAvgAbsolutePressure()));
			entity.setIncreaseDensity(DecimalUtil.calIncrease(item.getAvgDensity(), previous.getAvgDensity()));
			entity.setIncreaseMoisture(DecimalUtil.calIncrease(item.getAvgMoisture(), previous.getAvgMoisture()));
		}

		// 获取当月的的月泄露率（当月的日泄露率取平均）
		BigDecimal monthAvgLeakRate = getCurrentAvgIncreasePressure(item.getSensorCode(),day);
		entity.setMonthIncreasePressure20C(monthAvgLeakRate.toString());

		gisSf6IncreaseRateCacheDao.saveOrUpdate(entity);
		// 保存告警
		saveGisSf6Warning(day, item, entity);
	}

	private void saveGisSf6Warning(LocalDate day, GisSf6PressureStatisticsVo item, GisSf6IncreaseRateCache entity) {
		GisSf6ThresholdVo sf6Threshold = gisSF6ThresholdService.queryGisSF6Threshold(item.getSensorCode());
		if (sf6Threshold == null) {
			log.debug("传感器编码：{} 的阈值不存在，无法保存告警");
			return;
		}
		EquipmentInfoDto equipmentInfo = busiSubTreeService.findEquipmentInfo(item.getSensorCode(),
				SiteTreeEnum.GIS.getValue());
		BusiGisSensor gisSensor = busiGisSensorService.findSensorBySensorCode(item.getSensorCode());
		String eqType = EqType.EQ_TYPE2, gzType = GzType.GZ_TYPE5, cacMonitorTypeCode = item.getCacMonitorTypeCode();
		final StringBuilder warningMsg = new StringBuilder();
		// 压力日泄漏率超标
		BusiGisSf6ItemVoBuilder builder3 = BusiGisSf6ItemVo.builder().phase(gisSensor.getPosition()).name("压力（MPa）")
				.collectValue(entity.getAvgPressure20C()).thresholdValue(sf6Threshold.getSf6rxll())
				.warningValue(sf6Threshold.getSf6rxllWarn()).equipmentSensitivity("--");
		if (isWarning(entity.getIncreasePressure20C(), sf6Threshold.getSf6rxll())) {
			Tools.append(warningMsg, "日变化率超标：" +  new BigDecimal(entity.getIncreasePressure20C()).multiply(BigDecimal.valueOf(100)));
		}
		// 压力月泄漏率超标
		if (isWarning(entity.getMonthIncreasePressure20C(), sf6Threshold.getSf6yxll())) {
			Tools.append(warningMsg, "月变化率超标：" + new BigDecimal(entity.getMonthIncreasePressure20C()).multiply(BigDecimal.valueOf(100)));
		}
		if (warningMsg.length() > 0) {
			BusiEqmWarning busiEqmWarning = busiEqmWarningService.saveBusiEqmWarning(equipmentInfo, eqType, gzType,
					cacMonitorTypeCode, day.atStartOfDay(), warningMsg.toString(),"1");
			// 告警详情
			BusiGisSf6Vo busiGisSf6Vo = new BusiGisSf6Vo();
			busiGisSf6Vo.setEquipmentName(equipmentInfo.getSubEquipmentName());
			busiGisSf6Vo.setList(Arrays.asList( builder3.build()));
			busiGisSf6Vo.setCollectDate(busiEqmWarning.getWarningTime());
			busiEqmWarningService.saveBusiEqmWarningInfo(busiEqmWarning, JSON.toJSONString(busiGisSf6Vo));
		}
	}

	private static boolean isWarning(String val, String thresholdVal) {
		if(StringUtils.isBlank(thresholdVal) || DecimalUtil.getVal(val).compareTo(BigDecimal.ZERO) == 0){
			return false ;
		}
		BigDecimal bgVal = DecimalUtil.getVal(val).multiply(BigDecimal.valueOf(100));
		BigDecimal bdThresholdVal = DecimalUtil.getVal(thresholdVal);
		return bgVal.compareTo(bdThresholdVal) > 0;
	}

	// 获取月泄露率
	public BigDecimal getCurrentAvgIncreasePressure(String sensorCode,LocalDate day) {
		// 获取月初的泄露率
		GisSf6IncreaseRateCache sf61 = gisSf6IncreaseRateCacheMapper.getItem(sensorCode, day);
		GisSf6IncreaseRateCache sf62 = gisSf6IncreaseRateCacheMapper.getItem(sensorCode, day.minusDays(30));
		if (sf61 != null && sf62 != null) {
			String rate1 = sf61.getIncreasePressure20C();
			// 获取月末泄露率
			String rate2 = sf62.getIncreasePressure20C();
			BigDecimal b1 = new BigDecimal(rate1);
			BigDecimal b2 = new BigDecimal(rate2);

			BigDecimal rate = CalcUtil.calcRate(b2.subtract(b1), b1);
			//return b2.subtract(b1).setScale(4, RoundingMode.HALF_UP); //小数位 直接舍去
			return rate;
		} else {
			return BigDecimal.ZERO;
		}

	}

	public static LocalDate currentMonthFirstDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		String yearStr = calendar.get(Calendar.YEAR) + "";// 获取年份
		int month = calendar.get(Calendar.MONTH) + 1;// 获取月份
		return LocalDate.of(Integer.parseInt(yearStr), month, 01);
	}

	public LocalDate getLastMontFirstDay() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar cal_1 = Calendar.getInstance();// 获取当前日期
		cal_1.add(Calendar.MONTH, -1);
		cal_1.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
		LocalDate parseDate = LocalDate.parse(format.format(cal_1.getTime()));
		return parseDate;

	}

	public LocalDate getLastMontFinishDay() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的最后一天
		Calendar cale = Calendar.getInstance();
		cale.set(Calendar.DAY_OF_MONTH, 0);// 设置为1号,当前日期既为本月第一天
		LocalDate parseDate = LocalDate.parse(format.format(cale.getTime()));
		return parseDate;
	}
}