package com.huatek.busi.service.impl.temperature;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

import com.huatek.busi.common.DateUtils;
import com.huatek.busi.dao.BusiGeneratorSubTreeDao;
import com.huatek.busi.dao.BusiOnlineMonitorDataDao;
import com.huatek.busi.dao.BusiTemperPointDao;
import com.huatek.busi.dao.CwgTemperatureDao;
import com.huatek.busi.dto.HomeSearchDto;
import com.huatek.busi.entity.*;
import com.huatek.busi.vo.*;
import com.huatek.torch.sql.beans.WherePrams;
import org.apache.commons.lang3.ObjectUtils;
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.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Maps;
import com.huatek.busi.common.BusiConstant.EqType;
import com.huatek.busi.common.BusiConstant.GzType;
import com.huatek.busi.common.BusiConstant.TemperPointType;
import com.huatek.busi.common.SiteConstants.ExternalTypeEnum;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.common.util.DecimalUtil;
import com.huatek.busi.common.util.TimeUtil;
import com.huatek.busi.common.util.Tools;
import com.huatek.busi.dto.CwgTemperatureStatisticsDto;
import com.huatek.busi.dto.EquipmentInfoDto;
import com.huatek.busi.dto.curve.BaseCurveQueryDto;
import com.huatek.busi.dto.curve.PointItemDto;
import com.huatek.busi.mapper.BusiTemperPointMapper;
import com.huatek.busi.mapper.CwgTemperatureMapper;
import com.huatek.busi.service.BusiSiteTreeService;
import com.huatek.busi.service.IecBydworkParamService;
import com.huatek.busi.service.impl.cac.AbstractCacEtlService;
import com.huatek.busi.service.temperature.CwgTemperatureService;
import com.huatek.busi.service.temperature.RptTemperService;
import com.huatek.busi.service.temperature.RptTermperRecordService;
import com.huatek.busi.vo.curve.PointItemVo;
import com.huatek.busi.vo.monitor.BusiOnlineMonitorDataVo;
import com.huatek.busi.vo.warning.BusiWcgVo;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;
import org.springframework.util.CollectionUtils;

/**
 * 测温柜——测温柜：026002 ServiceImpl
 *
 * @author anker_cheng
 * @date Jun 26, 2019 1:11:48 PM
 */
@Component
@Service(interfaceClass = CwgTemperatureService.class)
@Transactional(rollbackFor = Exception.class)
public class CwgTemperatureServiceImpl extends AbstractCacEtlService<CwgTemperature> implements CwgTemperatureService {
	@Autowired
	private CwgTemperatureMapper cwgTemperatureMapper;
	@Autowired
	private BusiTemperPointMapper busiTemperPointMapper;

	@Autowired
	private RptTermperRecordService rptTermperRecordService;
	@Autowired
	private RptTemperService rptTemperService;
	@Autowired
	private IecBydworkParamService iecBydworkParamService;
	@Autowired
	private BusiSiteTreeService busiSiteTreeService;

	@Autowired
	private BusiTemperPointDao busiTemperPointDao;

	@Autowired
	private BusiOnlineMonitorDataDao busiOnlineMonitorDataDao;

	@Autowired
	private CwgTemperatureDao cwgTemperatureDao;


	@Override
	public void saveHistoryData(CwgTemperature cacEntity, EquipmentInfoDto equipmentInfo) {
		// 设备状态
		String state = iecBydworkParamService.getIecType(cacEntity.getMainTreeId(), cacEntity.getTimeStamp());
		if (StringUtils.isEmpty(state)) {
			logger.warn("IecType is empty! eqmCode: {}, timeStamp: {}", cacEntity.getEquipmentCode(),
					cacEntity.getTimeStamp());
		}
		cacEntity.setRunState(state);
		 //设置rowkey，导入hbase使用
        cacEntity.setHbaseRowkey(Tools.strReverse(TimeUtil.getTimeStr(cacEntity.getTimeStamp())) + "_"
            + cacEntity.getSensorId() + "_" + TimeUtil.getTimeStr(cacEntity.getTimeStamp()) + "_"
            + cacEntity.getCacMonitorTypeCode() + "_" + cacEntity.getMainTreeId());
        super.saveHistoryData(cacEntity, equipmentInfo);
	}

	@Override
	protected void saveBusiWarning(CwgTemperature cacEntity, String cacMonitorTypeCode, String sensorId,
			EquipmentInfoDto equipmentInfo) {
		BusiTemperPoint busiTemperPoint = busiTemperPointMapper.getBusiTemperPoint(cacEntity.getSiteId(), sensorId);

		if (busiTemperPoint == null) {
			logger.warn("busiTemperPoint not exists!  sensorCode: {}", cacEntity.getSensorId());
			return;
		}
		TemperPointType temperPointType = TemperPointType.from(busiTemperPoint.getPosition());
		if (temperPointType != null) {
			cacEntity.setPhase(temperPointType.getName());
		}

		String warningValue = busiTemperPoint.getWarningValue();
		String tmp = cacEntity.getTmp();

//		String temper = isWarning(tmp,warningValue,busiTemperPoint.getThresholdValue());

		// 判断是否告警
		boolean temper = isWarning(tmp,warningValue);
		if(temper)
		{
			BusiEqmWarning busiEqmWarning = newEw(EqType.EQ_TYPE4, GzType.GZ_TYPE7, formateCwWarningMsg(cacEntity),
					cacMonitorTypeCode,"1");
			busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
			busiEqmWarning.setRunState(cacEntity.getRunState());
			 busiEqmWarning.setWarningFlag("1");
			busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
			// 保存告警详情
			BusiWcgVo vo = new BusiWcgVo();
			vo.setEquipmentName(equipmentInfo.getSubEquipmentName());
			vo.setCollectValue(cacEntity.getTmp());
			vo.setAlarmValue(cacEntity.getTmp());
			vo.setThresholdValue(busiTemperPoint.getWarningValue());
			vo.setEquipmentStatus(cacEntity.getRunState());
			vo.setCollectDate(cacEntity.getTimeStamp());
			vo.setDayIncreaseRate("");
			vo.setMonthIncreaseRate("");
			vo.setPhase(cacEntity.getPhase());
			this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
			return;
        }
		// 判断是否预警
		if(isThreshold(tmp,busiTemperPoint.getThresholdValue(),warningValue))
		{
        	BusiEqmWarning busiEqmWarning = newEw(EqType.EQ_TYPE4, GzType.GZ_TYPE7, formateCwWarningMsg(cacEntity),
    				cacMonitorTypeCode,"2");
    		busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
    		busiEqmWarning.setRunState(cacEntity.getRunState());
    		 busiEqmWarning.setWarningFlag("2");
    		busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
    		// 保存告警详情
    		BusiWcgVo vo = new BusiWcgVo();
    		vo.setEquipmentName(equipmentInfo.getSubEquipmentName());
    		vo.setCollectValue(cacEntity.getTmp());
    		vo.setAlarmValue(cacEntity.getTmp());
    		vo.setThresholdValue(busiTemperPoint.getWarningValue());
    		vo.setEquipmentStatus(cacEntity.getRunState());
    		vo.setCollectDate(cacEntity.getTimeStamp());
    		vo.setDayIncreaseRate("");
    		vo.setMonthIncreaseRate("");
    		vo.setPhase(cacEntity.getPhase());
    		this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(vo));
        }
	}

	private String formateCwWarningMsg(CwgTemperature cacEntity) {
		return format("{}测温柜：{}℃温度超标", cacEntity.getPhase(), cacEntity.getTmp());
	}

	@Override
	public void updateCurrentData(CwgTemperature cacEntity, EquipmentInfoDto equipmentInfo) {
	    //这里相当于每个设备的实时数据
		rptTemperService.saveRptTemper(cacEntity, equipmentInfo);
		//这里相当于每个sensor的实时数据
        rptTermperRecordService.saveRptTermperRecord(cacEntity, equipmentInfo);
	}

	/**
	 * 数据输入-测温原始数据查询
	 */
	@Override
	public Map<String, Object> findCACPageData(Map<String, Object> params) {
		if (params.get("page") != null && params.get("limit") != null) {
			PageHelper.startPage(page(params), limit(params));
		}
		Page<Map<String, Object>> page = cwgTemperatureMapper.findCACPageData(params);
		return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, page.getTotal(), "", page.getResult());
	}

	@Override
	public Map<String, Object> exportCacMonitorData(Map<String, Object> mapParams) {
		Map<String, Object> returnMap = new HashMap<>();
		if (mapParams.containsKey("mainTreeId") && StringUtils.isNotEmpty(mapParams.get("mainTreeId") + "")) {
			BusiSiteTree busiSiteTree = busiSiteTreeService.findByPK(mapParams.get("mainTreeId") + "");
			List<CwgTemperatureVo> cwgTemperatureList = cwgTemperatureMapper.exportCacMonitorData(mapParams);
			String replaceRegex = "[\\\\n`~!@#$%^&*()+=|{}':;',\\\\\\\\[\\\\\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。， 、？]";
            String treeName = busiSiteTree.getName().replaceAll(replaceRegex, "-");
			returnMap.put("fileName", String.format("%s%s", treeName, "测温监测数据"));
			returnMap.put("title", String.format("%s%s", treeName, "测温监测数据"));
			if (cwgTemperatureList.isEmpty()) {
				cwgTemperatureList = new ArrayList<>();
				cwgTemperatureList.add(new CwgTemperatureVo());
			}
			returnMap.put("data", cwgTemperatureList);
		} else {
			throw new RuntimeException("主设备编码不正确");
		}
		return returnMap;
	}


	 /**
     * 判断告警
     * 返回 aVal.compareTo(bVal)>0的结果，判断aVal是否大于bVal
     *
     * @param aVal  报文数据
     * @param bVal  阈值
     */
    private static boolean isWarning(String aVal, String bVal) {
		if (StringUtils.isEmpty(aVal)) {
			return false;
		}
    	if (StringUtils.isEmpty(bVal)) {
    		return false;
    	}
    	return DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(bVal)) > 0;
    }

    /**
     * 判断预警
     * 返回 aVal.compareTo(bVal)>0的结果，判断aVal是否大于bVal
     *
     * @param aVal  报文数据
	 * @param bVal 预警值
	 * @param cVal 告警值
     * @return  true 预警
     */
    private static boolean isThreshold(String aVal, String bVal,String cVal) {
    	boolean flag = false;
		if (StringUtils.isEmpty(aVal)) {
			return false;
		}
    	if (StringUtils.isEmpty(bVal)) {
    		return false;
    	}
    	//预警
    	if(DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(bVal)) > 0 && DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(cVal)) < 0)
    	{
    		flag = true;
    	}
    	return flag;
    }

	@Override
	public List<BaseCurveQueryDto> findSensorCodeList(LocalDate day) {
		return cwgTemperatureMapper.findSensorCodeList(day.atStartOfDay(), day.plusDays(1).atStartOfDay());
	}

	@Override
	public List<PointItemVo> findDaylyPointList(BaseCurveQueryDto sensorCode, LocalDate day, String subType) {
		return cwgTemperatureMapper.findDaylyPointList(sensorCode, subType, day.atStartOfDay(),
				day.plusDays(1).atStartOfDay());
	}

    @Override
    public PointItemDto getDaylyPointStatistics(BaseCurveQueryDto param) {
        return cwgTemperatureMapper.getDaylyPointStatistics(param);
    }

	@Override
    protected List<Map<String, Object>> queryMonitorDataList(LocalDateTime startTime, LocalDateTime endTime) {
        return cwgTemperatureMapper.queryMonitorDataList(startTime, endTime);
    }

    @Override
    protected void saveBusiOnlineMonitorData(BusiOnlineMonitorData busiOnlineMonitorData, Map<String, Object> item) {
        busiOnlineMonitorData.setEquipmentType(SiteTreeEnum.CW_HL_EQM.getValue());
        busiOnlineMonitorData.setSubEquipmentType("000");
        busiOnlineMonitorData.setExtType(ExternalTypeEnum.CW.getValue());
        // 这里将保存的任务交给父类方法完成，子类只需要修改指定几个字段就可以了
        super.saveBusiOnlineMonitorData(busiOnlineMonitorData, item);
    }

    @Override
    protected Map<String, Object> thresholdDataMap(BusiOnlineMonitorDataVo vo) {
        Map<String, Object> map = Maps.newHashMapWithExpectedSize(2);
        // 阈值
        BusiTemperPoint busiTemperPoint = busiTemperPointMapper.getBusiTemperPoint(vo.getSiteId(), vo.getSensorCode());
        if(busiTemperPoint != null) {
            map.put("warningValue", busiTemperPoint.getWarningValue());
            map.put("thresholdValue", busiTemperPoint.getThresholdValue());
        }
        return map;
    }

    @Override
    public List<CwgTemperatureStatisticsVo> getListEquInfo(CwgTemperatureStatisticsDto param) {
        return cwgTemperatureMapper.getListEquInfo(param);
    }
	public  HomeActualInfoVo build(HomeActualInfoVo homeActualInfoVo,BusiTemperPoint busiTemperPoint,String mainTreeId){
		homeActualInfoVo.setEquipmentBrand(busiTemperPoint.getSensorBrand());
		homeActualInfoVo.setEquipmentName(busiTemperPoint.getSensorName());
		homeActualInfoVo.setInstallLocation(busiTemperPoint.getPositionDes());
		homeActualInfoVo.setEqmId(busiTemperPoint.getEquipmentId());
		homeActualInfoVo.setPhase(busiTemperPoint.getPosition());
		homeActualInfoVo.setManufactor(busiTemperPoint.getManufactor());
		homeActualInfoVo.setSensorBrand(busiTemperPoint.getSensorBrand());
		homeActualInfoVo.setUseDate(busiTemperPoint.getUseDate());
		homeActualInfoVo.setSensorId(busiTemperPoint.getSensorCode());
		homeActualInfoVo.setSensorName(busiTemperPoint.getSensorName());
		homeActualInfoVo.setMainTreeId(mainTreeId);
		return homeActualInfoVo;
	}
	@Override
	public HomeActualVo queryActual(HomeSearchDto param) {
		HomeActualVo homeActualVo=new HomeActualVo();
		BusiTemperPoint  busiTemperPoint = busiTemperPointDao.get(new WherePrams()
				.where("sensor_code", param.getSensorCode()));
		if(ObjectUtils.isEmpty(busiTemperPoint)){
			return homeActualVo;
		}
		HomeActualInfoVo homeActualInfoVo =new HomeActualInfoVo();
		String mainTreeId=busiTemperPoint.getEquipmentId();
		homeActualInfoVo = build(homeActualInfoVo, busiTemperPoint,mainTreeId);
		String date = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(new Date(), -1));
		List<BusiOnlineMonitorData> busiOnlineMonitorDatas = busiOnlineMonitorDataDao.list(new WherePrams()
				.where("sensor_code", param.getSensorCode())
				.and("day","like",date));
		//组装各种率
		if(!ObjectUtils.isEmpty(busiOnlineMonitorDatas)){
			BusiOnlineMonitorData busiOnlineMonitorData = busiOnlineMonitorDatas.get(0);
			homeActualInfoVo.setRunState(busiOnlineMonitorData.getRunState());
			homeActualInfoVo.setFalseAlarmRate(busiOnlineMonitorData.getFalseAlarmRate());
			homeActualInfoVo.setLossRate(busiOnlineMonitorData.getLossRate());
			homeActualInfoVo.setRepairCount(busiOnlineMonitorData.getRepairCount());
			homeActualInfoVo.setDTime(busiOnlineMonitorData.getCreatedTime());
		}
		homeActualVo.setHomeActualInfoVo(homeActualInfoVo);
		List<CwgTemperature> list = cwgTemperatureDao.list(new WherePrams()
				.where("sensor_id", param.getSensorCode())
				.orderBy("time_stamp desc limit 1"));
		HomeActualDataVo homeActualDataVo=new HomeActualDataVo();
		List<HomeActualDataVo> homeActualDataVos=new ArrayList<>();
		if(CollectionUtils.isEmpty(list)){

			return homeActualVo;
		}

		CwgTemperature cwgTemperature = list.get(0);
		homeActualDataVo.setDTime(cwgTemperature.getTimeStamp());
		homeActualDataVo.setName("温度(℃)");
		homeActualDataVo.setValue(cwgTemperature.getTmp());

		String thresholdValue="";
		if(!ObjectUtils.isEmpty(busiTemperPoint.getWarningValue())){
			thresholdValue=busiTemperPoint.getWarningValue();
		}
		homeActualDataVo.setThresholdValue(thresholdValue);
		homeActualDataVos.add(homeActualDataVo);
		homeActualVo.setHomeActualDataVos(homeActualDataVos);
		return homeActualVo;
	}

	/**
     * 返回 aVal.compareTo(bVal)>0的结果，判断aVal是否大于bVal
     *
     * @param aVal  报文数据
     * @param bVal  阈值
     * @param cVal  预警值
     * @return  0,正常；1预警；2告警
     */
//    private static String gt(String aVal, String bVal,String cVal) {
//    	//return DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(bVal)) > 0;
//    	String flag = "0";
//
//    	if (StringUtils.isEmpty(bVal)) {
//    		return "0";
//    	}
//    	//预警
//    	if( DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(bVal)) > 0)
//    	{
//    		if( DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(cVal)) < 0)
//    		{
//    			flag = "2";
//    		}
//    	}
//    	//告警
//    	if(DecimalUtil.getVal(aVal).compareTo(DecimalUtil.getVal(cVal)) > 0)
//    	{
//    		flag = "1";
//    	}
//    	return flag;
//    }
}
