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

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

import com.huatek.busi.entity.*;
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.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.huatek.busi.common.BusiConstant;
import com.huatek.busi.common.BusiConstant.EqType;
import com.huatek.busi.common.BusiConstant.GzType;
import com.huatek.busi.common.BusiConstant.WarningStatus;
import com.huatek.busi.common.CacMonitorTypeCode;
import com.huatek.busi.common.SiteConstants.ExternalTypeEnum;
import com.huatek.busi.common.SiteConstants.GisTreeEnum;
import com.huatek.busi.common.SiteConstants.OtherTreeEnum;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.common.SiteConstants.TransfromerTreeEnum;
import com.huatek.busi.common.util.DateUtil;
import com.huatek.busi.common.util.TimeUtil;
import com.huatek.busi.common.util.Tools;
import com.huatek.busi.dto.EquipmentInfoDto;
import com.huatek.busi.dto.TransformerPdCountDto;
import com.huatek.busi.dto.TransformerPdDto;
import com.huatek.busi.mapper.TransformerPdMapper;
import com.huatek.busi.service.BusiCommonService;
import com.huatek.busi.service.BusiEqmWarningService;
import com.huatek.busi.service.BusiOtherSensorService;
import com.huatek.busi.service.BusiSiteTreeService;
import com.huatek.busi.service.Other.OtherPdCacheService;
import com.huatek.busi.service.gis.BusiGisSensorService;
import com.huatek.busi.service.gis.GisPdCacheService;
import com.huatek.busi.service.impl.cac.AbstractCacEtlService;
import com.huatek.busi.service.transformer.BusiTransformerSensorService;
import com.huatek.busi.service.transformer.TransformerPdCacheService;
import com.huatek.busi.service.transformer.TransformerPdRecordService;
import com.huatek.busi.service.transformer.TransformerPdService;
import com.huatek.busi.vo.BusiSensorVo;
import com.huatek.busi.vo.TransformerPdCountVo;
import com.huatek.busi.vo.datainput.TransformerInputPdVo;
import com.huatek.busi.vo.monitor.TransformerPdVo;
import com.huatek.busi.vo.warning.BusiPdVo;
import com.huatek.torch.frame.exception.OwlException;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;
import com.huatek.torch.util.uuid.Uuid;

/**
 * 变压器/电抗器——局部放电：021001、024001、027001 ServiceImpl
 *
 * @author anker_cheng
 * @date Jun 26, 2019 1:11:48 PM
 */
@Component
@Service(interfaceClass = TransformerPdService.class)
@Transactional(rollbackFor = Exception.class)
public class TransformerPdServiceImpl extends AbstractCacEtlService<TransformerPd> implements TransformerPdService {

    @Autowired
    private TransformerPdMapper transformerPdMapper;
    @Autowired
    private BusiCommonService busiCommonService;
    @Reference(check = false)
    private TransformerPdCacheService transformerPdCacheService;
    @Reference(check = false)
    private GisPdCacheService gisPdCacheService;
    @Reference(check = false)
    private TransformerPdRecordService transformerPdRecordService;
    @Reference(check = false)
    private BusiSiteTreeService busiSiteTreeService;
    @Reference(check = false)
    private BusiEqmWarningService busiEqmWarningService;
    @Reference(check = false)
    private OtherPdCacheService otherPdCacheService;
    
    
    @Reference(check = false)
    private BusiGisSensorService busiGisSensorService;
    
    @Reference(check = false)
    private BusiTransformerSensorService busiTransformerSensorService;
    
    @Reference(check = false)
    private BusiOtherSensorService busiOtherSensorService;
    

    @Override
    protected void saveBusiWarning(TransformerPd cacEntity, String cacMonitorTypeCode, String sensorId,
        EquipmentInfoDto equipmentInfo) {

    	 String eqType = "";
         String eqTypeInfo = "";
         String pdWarning = null ;
		 if (CacMonitorTypeCode.TRANSFORMER_PD.isThis(cacMonitorTypeCode)) {
                eqType = EqType.EQ_TYPE1;
                eqTypeInfo = "变压器";
                pdWarning =  this.getPdWarning("1", sensorId);
		 } else if (CacMonitorTypeCode.GIS_PD.isThis(cacMonitorTypeCode)) {
            eqType = EqType.EQ_TYPE2;
            eqTypeInfo = "GIS";
            pdWarning = this.getPdWarning("2", sensorId);
		 } else if (CacMonitorTypeCode.ELE_PD.isThis(cacMonitorTypeCode)) {
            // 电缆局放，nothing to do
			  pdWarning = this.getPdWarning("3", sensorId);
		 }
		 String dischargeCapacity = cacEntity.getDischargeCapacity();


		 //局放告警阈值
		 boolean flag = StringUtils.isNoneBlank(dischargeCapacity) 
	        		&& StringUtils.isNoneBlank(pdWarning)
	        		&& new BigDecimal(dischargeCapacity).compareTo(new BigDecimal(pdWarning)) > 0;
	        		
    	if(WarningStatus.WARN.equals(cacEntity.getPaDschAlm()) || (WarningStatus.NORMAL.equals(cacEntity.getPaDschAlm()) && flag))
    	{
//	        if (StringUtils.isNoneBlank(dischargeCapacity) 
//	        		&& StringUtils.isNoneBlank(pdWarning)
//	        		&& new BigDecimal(dischargeCapacity).compareTo(new BigDecimal(pdWarning)) > 0) {
	            BusiEqmWarning busiEqmWarning =
	                newEw(eqType, GzType.GZ_TYPE2, this.formateJfWarningMsg(cacEntity, eqTypeInfo), cacMonitorTypeCode,"1");
	            busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
	            busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);

	            // 保存告警详情
	            BusiPdVo busiPdVo = new BusiPdVo();
	            busiPdVo.setEquipmentName(equipmentInfo.getSubEquipmentName());
	            busiPdVo.setDischargeCapacity(dischargeCapacity);
	            //busiPdVo.setDischargeCount(getDischargeCount(sensorId, eqType).toString());
	            busiPdVo.setDischargeCount(cacEntity.getPulseCount());
	            busiPdVo.setDischargePosition(cacEntity.getDischargePosition());
//	            busiPdVo.setDischargeType(BusiConstant.getDschTypeDescribe(cacEntity.getDschType()));
	            busiPdVo.setDischargeType(cacEntity.getDschType());
	            busiPdVo.setPhase(cacEntity.getPhase());
	            busiPdVo.setCollectDate(cacEntity.getTimeStamp());
	            busiPdVo.setPdWarning(pdWarning);
	            this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(busiPdVo));

	            TransformerPdRecord record = new TransformerPdRecord();
	            record.setId(Uuid.getUUID());
	            record.setSensorCode(sensorId);
	            record.setPdType(eqType);
	            transformerPdRecordService.insert(record);
//	        }
    	}
    }

    @Override
    protected void saveHistoryData(TransformerPd cacEntity, EquipmentInfoDto equipmentInfo) {
        // 设置rowkey，导入hbase使用
        cacEntity.setHbaseRowkey(Tools.strReverse(TimeUtil.getTimeStr(cacEntity.getTimeStamp())) + "_"
            + cacEntity.getSensorId() + "_" + TimeUtil.getTimeStr(cacEntity.getTimeStamp()) + "_"
            + cacEntity.getCacMonitorTypeCode() + "_" + cacEntity.getMainTreeId());
        
        super.saveHistoryData(cacEntity, equipmentInfo);
        
    }

    /**
     * @Title: getDischargeCount
     * @Description: 获取放电次数
     * @createDate: Aug 12, 2019 7:20:14 PM
     * @param sensorCode
     * @param type
     * @return Integer
     */
    private Long getDischargeCount(String sensorCode, String type) {
        Long count = this.transformerPdRecordService.getCountBySensorCode(sensorCode);
        if (null != count) {
            return count + 1;
        }
        return 1L;
    }

    /**
     * @Title: formateJfWarningMsg
     * @Description: 告警信息
     * @createDate: Aug 12, 2019 7:18:43 PM
     * @param
     * @return String
     */
    private String formateJfWarningMsg(TransformerPd cacEntity, String eqTypeInfo) {
        return format("{}局放电量:{}超标", eqTypeInfo, cacEntity.getDischargeCapacity());
    }

    @Override
    public void updateCurrentData(TransformerPd cacEntity, EquipmentInfoDto equipmentInfo) {
        // 变压器局放实时数据
        if (CacMonitorTypeCode.TRANSFORMER_PD.isThis(cacEntity.getCacMonitorTypeCode())) {
            transformerPdCacheService.saveTransformerPdCache(cacEntity);
            return;
        }
        // GIS局放实时数据
        if (CacMonitorTypeCode.GIS_PD.isThis(cacEntity.getCacMonitorTypeCode())) {
            gisPdCacheService.saveGisPdCache(cacEntity);
            return;
        }
        // 电缆局放实时数据
        if (CacMonitorTypeCode.ELE_PD.isThis(cacEntity.getCacMonitorTypeCode())) {
        	otherPdCacheService.saveOtherPdCache(cacEntity);
            return;
        }
    }

    @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>> pageInfo = transformerPdMapper.findCACPageData(params);
        return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, pageInfo.getTotal(), "", pageInfo.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<TransformerInputPdVo> transformerPdList = transformerPdMapper.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 (transformerPdList.isEmpty()) {
                transformerPdList = new ArrayList<>();
                transformerPdList.add(new TransformerInputPdVo());
            }
            returnMap.put("data", transformerPdList);
        } else {
            throw new RuntimeException("主设备编码不正确");
        }
        return returnMap;
    }

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

    @Override
    protected void saveBusiOnlineMonitorData(BusiOnlineMonitorData busiOnlineMonitorData, Map<String, Object> item) {
        String cacMonitorTypeCode = popString(item, "cacMonitorTypeCode");
        if (CacMonitorTypeCode.TRANSFORMER_PD.isThis(cacMonitorTypeCode)) {
            busiOnlineMonitorData.setSubEquipmentType(TransfromerTreeEnum.JF_EQM.getValue());
            busiOnlineMonitorData.setExtType(ExternalTypeEnum.BYQ.getValue());
            busiOnlineMonitorData.setEquipmentType(SiteTreeEnum.BYQ_EQM.getValue());
        } else if (CacMonitorTypeCode.GIS_PD.isThis(cacMonitorTypeCode)) {
            busiOnlineMonitorData.setSubEquipmentType(GisTreeEnum.JF_EQM.getValue());
            busiOnlineMonitorData.setExtType(ExternalTypeEnum.GIS.getValue());
            busiOnlineMonitorData.setEquipmentType(SiteTreeEnum.GIS_HL_EQM.getValue());
        } else if (CacMonitorTypeCode.ELE_PD.isThis(cacMonitorTypeCode)) {
            busiOnlineMonitorData.setSubEquipmentType(OtherTreeEnum.DL_EQM.getValue());
            busiOnlineMonitorData.setExtType(ExternalTypeEnum.OTHER.getValue());
            busiOnlineMonitorData.setEquipmentType(SiteTreeEnum.OTHER_EQM.getValue());
        } else {
            throw new OwlException(format("数据错误，sensorCode: {}", busiOnlineMonitorData.getSensorCode()));
        }
        // 这里将保存的任务交给父类方法完成，子类只需要修改指定几个字段就可以了
        super.saveBusiOnlineMonitorData(busiOnlineMonitorData, item);
    }

    @Override
    public List<Map<String, Object>> findReportDataList(String sensorCode, String startTime,
    		String endTime) {
    	return transformerPdMapper.findReportDataList(sensorCode, startTime, endTime);
    }
    

	@Override
	public List<Map<String, Object>> findReportDataListByFirstData(String sensorCode) {
		// TODO Auto-generated method stub
		return transformerPdMapper.findReportDataListByFirstData(sensorCode);
	}

    @Override
    public List<TransformerPdCountVo> getListEquInfo(String cacMonitorTypeCode, LocalDate day) {
        TransformerPdCountDto param = new TransformerPdCountDto();
        param.setCacMonitorTypeCode(cacMonitorTypeCode);
        param.setStartTime(day.atStartOfDay());
        param.setEndTime(day.plusDays(1).atStartOfDay());
        return transformerPdMapper.getListEquInfo(param);
    }

    @Override
    public PageInfo<Map<String, Object>> findTransformerPdPage(TransformerPdDto transformerPdDto) {
        PageInfo<Map<String, Object>> pageInfo =
            PageHelper.startPage(transformerPdDto.getPage(), transformerPdDto.getLimit())
                .doSelectPageInfo(() -> transformerPdMapper.findTransformerPdPage(transformerPdDto));
        pageInfo.getList().stream().forEach(map -> {
            // 维修次数
            map.put("repairCount", busiCommonService.getEquipHalfYearRepairCount(ExternalTypeEnum.BYQ,
                map.get("subEquipmentId").toString()));
            // 误报率
            map.put("falseAlarmRate", busiEqmWarningService.getFalseAlarmRateBySensor(map.get("sensorId").toString(),
                DateUtil.getMonthStartDay(), DateUtil.getMonthLastDay()));
            
//            map.put("dschType",  BusiConstant.getDschTypeDescribe(map.get("dschType").toString()));
            
//            t.dsch_type AS dschType,
//	        t.pa_dsch_alm AS paDschAlm,
            
        });
        return pageInfo;
    }
    
    
    @Override
    public List<Object> exportTransformerPdPage(TransformerPdDto transformerPdDto){
    	List<Object> exportMonitorData = Lists.newArrayList();
    	List<TransformerPdVo> transformerPdList = transformerPdMapper.exportTransformerPdPage(transformerPdDto);
    	transformerPdList.stream().forEach(transformerPd ->{
            // 误报率
    		transformerPd.setFalseAlarmRate(busiEqmWarningService.getFalseAlarmRateBySensor(transformerPd.getSensorId(),
                DateUtil.getMonthStartDay(), DateUtil.getMonthLastDay()));
    		exportMonitorData.add(transformerPd);
    	});
        return exportMonitorData;
    }

    @Override
    public PageInfo<Map<String, Object>> findGisPdPage(TransformerPdDto transformerPdDto) {
        PageInfo<Map<String, Object>> pageInfo =
            PageHelper.startPage(transformerPdDto.getPage(), transformerPdDto.getLimit())
                .doSelectPageInfo(() -> transformerPdMapper.findGisPdPage(transformerPdDto));
        pageInfo.getList().stream().forEach(map -> {
            // 维修次数
            map.put("repairCount", busiCommonService.getEquipHalfYearRepairCount(ExternalTypeEnum.BYQ,
                map.get("subEquipmentId").toString()));
            // 误报率
            map.put("falseAlarmRate", busiEqmWarningService.getFalseAlarmRateBySensor(map.get("sensorId").toString(),
                DateUtil.getMonthStartDay(), DateUtil.getMonthLastDay()));
        });
        return pageInfo;
    }

	@Override
	public List<Object> exportGisPdPage(TransformerPdDto transformerPdDto) {
		// TODO Auto-generated method stub
		List<Object> exportMonitorData = Lists.newArrayList();
		List<TransformerPdVo> gisPdList = transformerPdMapper.exportGisPdPage(transformerPdDto);
		gisPdList.stream().forEach(gisPd ->{
            // 误报率
    		gisPd.setFalseAlarmRate(busiEqmWarningService.getFalseAlarmRateBySensor(gisPd.getSensorId(),
                DateUtil.getMonthStartDay(), DateUtil.getMonthLastDay()));
    		exportMonitorData.add(gisPd);
    	});
        return exportMonitorData;
	}

	
	/** 
	* @Title: getPdWarning 
	* @Description: 获取局放告警值 
	* @createDate: Dec 24, 2019 4:38:18 PM
	* @param    type  1--变压器  2-gis  3-其他
	* @return   String    
	*/ 
	public String getPdWarning(String type, String sensorCode){ 
		BusiSensorVo busiSensorVo = null ;
		if(type.equals("1")){
			 busiSensorVo = this.busiTransformerSensorService.getBusiSensorVo(sensorCode);
		}else if(type.equals("2")){
			 busiSensorVo = this.busiGisSensorService.getBusiSensorVo(sensorCode);
		}else if(type.equals("3")){
			 busiSensorVo = busiOtherSensorService.getBusiSensorVo(sensorCode);
		}
		return  busiSensorVo == null ? null :  busiSensorVo.getPdValue() ;
		
	}
}