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

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 org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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.google.common.collect.Maps;
import com.huatek.busi.common.BusiConstant.EqType;
import com.huatek.busi.common.BusiConstant.GzType;
import com.huatek.busi.common.SiteConstants.ExternalTypeEnum;
import com.huatek.busi.common.SiteConstants.IcgeType;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.common.SiteConstants.TransfromerTreeEnum;
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.EquipmentInfoDto;
import com.huatek.busi.dto.TransformerIcgeCountDto;
import com.huatek.busi.dto.curve.BaseCurveQueryDto;
import com.huatek.busi.dto.curve.PointItemDto;
import com.huatek.busi.entity.BusiEqmWarning;
import com.huatek.busi.entity.BusiOnlineMonitorData;
import com.huatek.busi.entity.BusiSiteTree;
import com.huatek.busi.entity.TransformerIcge;
import com.huatek.busi.entity.TransformerIcgeThreshold;
import com.huatek.busi.mapper.TransformerIcgeMapper;
import com.huatek.busi.service.BusiEqmWarningService;
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.threshold.TransformerIcgeThresholdService;
import com.huatek.busi.service.transformer.TransformerIcgeCacheService;
import com.huatek.busi.service.transformer.TransformerIcgeService;
import com.huatek.busi.vo.TransformerIcgeCountVo;
import com.huatek.busi.vo.TransformerIcgeVo;
import com.huatek.busi.vo.curve.PointItemVo;
import com.huatek.busi.vo.monitor.BusiOnlineMonitorDataVo;
import com.huatek.busi.vo.stability.IcgeStabilityVo;
import com.huatek.busi.vo.warning.BusiIcgeVo;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;

/**
 * 变压器/电抗器——铁芯接地电流：021004 ServiceImpl
 *
 * @author anker_cheng
 * @date Jun 26, 2019 1:11:48 PM
 */
@Component
@Service(interfaceClass = TransformerIcgeService.class)
@Transactional(rollbackFor = Exception.class)
public class TransformerIcgeServiceImpl extends AbstractCacEtlService<TransformerIcge>
    implements TransformerIcgeService {
    @Autowired
    private TransformerIcgeMapper transformerIcgeMapper;

    @Reference(check = false)
    private BusiEqmWarningService busiEqmWarningService;
    @Reference(check = false)
    private TransformerIcgeCacheService transformerIcgeCacheService;
    @Reference(check = false)
    private TransformerIcgeThresholdService transformerIcgeThresholdService;
    @Reference(check = false)
    private IecBydworkParamService iecBydworkParamService;

    @Reference(check = false)
    private BusiSiteTreeService busiSiteTreeService;

    @Override
    public void saveHistoryData(TransformerIcge cacEntity, EquipmentInfoDto equipmentInfo) {
        // 铁芯or夹件
        if (equipmentInfo != null) {
            if (TransfromerTreeEnum.TX_EQM.getValue().equals(equipmentInfo.getEquipmentType())) {
                cacEntity.setType(IcgeType.TX.getValue());
            } else if (TransfromerTreeEnum.JJ_EQM.getValue().equals(equipmentInfo.getEquipmentType())) {
                cacEntity.setType(IcgeType.JJ.getValue());
            }
        }
        // 设备状态
        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
    public void saveBusiWarning(TransformerIcge cacEntity, String cacMonitorTypeCode, String sensorId,
        EquipmentInfoDto equipmentInfo) {
        // 阈值
        TransformerIcgeThreshold transformerIcgeThreshold = transformerIcgeThresholdService
            .getTransformerIcgeThreshold(cacEntity.getMainTreeId(), cacEntity.getRunState(), cacEntity.getSensorId());
        if (transformerIcgeThreshold == null) {
            logger.warn("transformerIcgeThreshold not exists! mainTreeId: {}, runState: {}, sensorCode: {}",
                cacEntity.getMainTreeId(), cacEntity.getRunState(), cacEntity.getSensorId());
            return;
        }
        Map<String, Object> stabilityMap =
            busiStabilityService.getStabilityBySensorCodeAndStatus(sensorId, cacEntity.getRunState());
        // 铁芯告警
       String txWarning = isTxWarning(cacEntity, transformerIcgeThreshold);
       if("1".equals(txWarning))
       {
    	   // 保存告警
           BusiEqmWarning busiEqmWarning =
               newEw(EqType.EQ_TYPE1, GzType.GZ_TYPE3, formateTxWarningMsg(cacEntity), cacMonitorTypeCode,"1");
           busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
           busiEqmWarning.setWarningFlag("1");
           busiEqmWarning.setRunState(cacEntity.getRunState());
           busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
           // 保存告警详情
           BusiIcgeVo busiIcgeVo = new BusiIcgeVo();
           busiIcgeVo.setCollectValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setAlarmValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setPhase(cacEntity.getPhase());
           busiIcgeVo.setEquipmentName(equipmentInfo.getSubEquipmentName());
           // 稳定性指标
           busiIcgeVo.setStabilityIndex(getString(stabilityMap, "totalCurrent", "--"));
           busiIcgeVo.setThresholdValue(transformerIcgeThreshold.getTxDl());
           busiIcgeVo.setWarningValue(transformerIcgeThreshold.getTxWarningVal());
           busiIcgeVo.setEquipmentStatus(cacEntity.getRunState());
           busiIcgeVo.setCollectDate(cacEntity.getTimeStamp());
           this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(busiIcgeVo));
       }else  if("2".equals(txWarning))
       {
    	// 保存告警
           BusiEqmWarning busiEqmWarning =
               newEw(EqType.EQ_TYPE1, GzType.GZ_TYPE3, formateTxWarningMsg(cacEntity), cacMonitorTypeCode,"2");
           busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
           busiEqmWarning.setWarningFlag("2");
           busiEqmWarning.setRunState(cacEntity.getRunState());
           busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
           // 保存告警详情
           BusiIcgeVo busiIcgeVo = new BusiIcgeVo();
           busiIcgeVo.setCollectValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setAlarmValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setPhase(cacEntity.getPhase());
           busiIcgeVo.setEquipmentName(equipmentInfo.getSubEquipmentName());
           // 稳定性指标
           busiIcgeVo.setStabilityIndex(getString(stabilityMap, "totalCurrent", "--"));
           busiIcgeVo.setThresholdValue(transformerIcgeThreshold.getTxDl());
           busiIcgeVo.setWarningValue(transformerIcgeThreshold.getTxWarningVal());
           busiIcgeVo.setEquipmentStatus(cacEntity.getRunState());
           busiIcgeVo.setCollectDate(cacEntity.getTimeStamp());
           this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(busiIcgeVo));
       }
       
       String jjWarning = isJjWarning(cacEntity, transformerIcgeThreshold);
       if("1".equals(jjWarning))
       { // 保存告警
           BusiEqmWarning busiEqmWarning =
                   newEw(EqType.EQ_TYPE1, GzType.GZ_TYPE8, formateJjWarningMsg(cacEntity), cacMonitorTypeCode,"1");
               busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
               busiEqmWarning.setRunState(cacEntity.getRunState());
               busiEqmWarning.setWarningFlag("1");
               busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
               // 保存告警详情
               BusiIcgeVo busiIcgeVo = new BusiIcgeVo();
               busiIcgeVo.setCollectValue(cacEntity.getTotalCoreCurrent());
               busiIcgeVo.setAlarmValue(cacEntity.getTotalCoreCurrent());
               busiIcgeVo.setPhase(cacEntity.getPhase());
               busiIcgeVo.setEquipmentName(equipmentInfo.getSubEquipmentName());
               // 稳定性指标
               busiIcgeVo.setStabilityIndex(getString(stabilityMap, "totalCurrent", "--"));
               busiIcgeVo.setThresholdValue(transformerIcgeThreshold.getJjDl());
               busiIcgeVo.setWarningValue(transformerIcgeThreshold.getJjWarningVal());
               busiIcgeVo.setEquipmentStatus(cacEntity.getRunState());
               busiIcgeVo.setCollectDate(cacEntity.getTimeStamp());
               this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(busiIcgeVo));
       }
       else if("2".equals(jjWarning))
       {
    	   // 保存告警
           BusiEqmWarning busiEqmWarning =
               newEw(EqType.EQ_TYPE1, GzType.GZ_TYPE8, formateJjWarningMsg(cacEntity), cacMonitorTypeCode,"2");
           busiEqmWarning.setWarningTime(cacEntity.getTimeStamp());
           busiEqmWarning.setRunState(cacEntity.getRunState());
           busiEqmWarning.setWarningFlag("2");
           busiEqmWarning = this.buildWarning(busiEqmWarning, equipmentInfo);
           // 保存告警详情
           BusiIcgeVo busiIcgeVo = new BusiIcgeVo();
           busiIcgeVo.setCollectValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setAlarmValue(cacEntity.getTotalCoreCurrent());
           busiIcgeVo.setPhase(cacEntity.getPhase());
           busiIcgeVo.setEquipmentName(equipmentInfo.getSubEquipmentName());
           // 稳定性指标
           busiIcgeVo.setStabilityIndex(getString(stabilityMap, "totalCurrent", "--"));
           busiIcgeVo.setThresholdValue(transformerIcgeThreshold.getJjDl());
           busiIcgeVo.setWarningValue(transformerIcgeThreshold.getJjWarningVal());
           busiIcgeVo.setEquipmentStatus(cacEntity.getRunState());
           busiIcgeVo.setCollectDate(cacEntity.getTimeStamp());
           this.buildWarningInfo(busiEqmWarning, JSON.toJSONString(busiIcgeVo));
       }
    }

    private String isTxWarning(TransformerIcge cacEntity, TransformerIcgeThreshold transformerIcgeThreshold) {
//        return IcgeType.TX.getValue().equals(cacEntity.getType()) && DecimalUtil.getVal(cacEntity.getTotalCoreCurrent())
//            .compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getTxDl())) > 0;
    	String flag = "0";
    	if(IcgeType.TX.getValue().equals(cacEntity.getType()))
    	{
    		if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getTxDl())) > 0)
    		{
    			if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getTxWarningVal())) < 0)
    			{
    				 flag = "2";
    			}
    		}
    		
    		if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getTxWarningVal())) > 0)
    		{
    			 flag = "1";
    		}
    	}
    	return flag;
    }

    private String isJjWarning(TransformerIcge cacEntity, TransformerIcgeThreshold transformerIcgeThreshold) {
//        return IcgeType.JJ.getValue().equals(cacEntity.getType()) && DecimalUtil.getVal(cacEntity.getTotalCoreCurrent())
//            .compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getJjDl())) > 0;
    	String flag = "0";
    	if(IcgeType.JJ.getValue().equals(cacEntity.getType()))
    	{
    		if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getJjDl())) > 0)
    		{
    			if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getJjWarningVal())) < 0)
    			{
    				 flag = "2";
    			}
    		}
    		
    		if(DecimalUtil.getVal(cacEntity.getTotalCoreCurrent()).compareTo(DecimalUtil.getVal(transformerIcgeThreshold.getJjWarningVal())) > 0)
    		{
    			 flag = "1";
    		}
    	}
    	return flag;
    }

    private String formateTxWarningMsg(TransformerIcge cacEntity) {
        return format("铁芯接地电流:{}(mA)超标", cacEntity.getTotalCoreCurrent());
    }

    private String formateJjWarningMsg(TransformerIcge cacEntity) {
        return format("夹件接地电流:{}(mA)超标", cacEntity.getTotalCoreCurrent());
    }

    @Override
    public void updateCurrentData(TransformerIcge cacEntity) {
        transformerIcgeCacheService.saveTransformerIcgeCache(cacEntity);
    }

    @Override
    public TransformerIcgeCountVo getListEquInfo(LocalDate day, String cacMonitorTypeCode, String sensorCode) {
        TransformerIcgeCountDto param = new TransformerIcgeCountDto();
        param.setCacMonitorTypeCode(cacMonitorTypeCode);
        param.setStartTime(day.atStartOfDay());
        param.setEndTime(day.plusDays(1).atStartOfDay());
        param.setSensorCode(sensorCode);
        List<TransformerIcgeCountVo> list = transformerIcgeMapper.getListEquInfo(param);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @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 = transformerIcgeMapper.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<TransformerIcgeVo> transformerIcgeList = transformerIcgeMapper.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 (transformerIcgeList.isEmpty()) {
                transformerIcgeList = new ArrayList<>();
                transformerIcgeList.add(new TransformerIcgeVo());
            } else {
                transformerIcgeList.stream().forEach(transformerIcge -> {
                    transformerIcge.setType(IcgeType.getName(transformerIcge.getType()));
                });
            }
            returnMap.put("data", transformerIcgeList);
        } else {
            throw new RuntimeException("主设备编码不正确");
        }
        return returnMap;
    }

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

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

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

    @Override
    public List<IcgeStabilityVo> getByStatus(String sensorCode, String status, String type, LocalDateTime beginTime,
        LocalDateTime endTime) {
        return transformerIcgeMapper.selectByStatus(sensorCode, status, type, beginTime, endTime);
    }

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

    @Override
    protected void saveBusiOnlineMonitorData(BusiOnlineMonitorData busiOnlineMonitorData, Map<String, Object> item) {
        String type = popString(item, "type");
        if (IcgeType.TX.getValue().equals(type)) {
            busiOnlineMonitorData.setSubEquipmentType(TransfromerTreeEnum.TX_EQM.getValue());
        } else if (IcgeType.JJ.getValue().equals(type)) {
            busiOnlineMonitorData.setSubEquipmentType(TransfromerTreeEnum.JJ_EQM.getValue());
        }
        busiOnlineMonitorData.setExtType(ExternalTypeEnum.BYQ.getValue());
        busiOnlineMonitorData.setEquipmentType(SiteTreeEnum.BYQ_EQM.getValue());
        // 这里将保存的任务交给父类方法完成，子类只需要修改指定几个字段就可以了
        super.saveBusiOnlineMonitorData(busiOnlineMonitorData, item);
    }

    @Override
    protected Map<String, Object> thresholdDataMap(BusiOnlineMonitorDataVo vo) {
        TransformerIcgeThreshold thresholdVo = transformerIcgeThresholdService
            .getTransformerIcgeThreshold(vo.getMainTreeId(), vo.getRunState(), vo.getSensorCode());
        Map<String, Object> resultMap = Maps.newLinkedHashMapWithExpectedSize(3);
        if (thresholdVo != null) {
            if (TransfromerTreeEnum.TX_EQM.getValue().equals(vo.getSubEquipmentType())) {
                resultMap.put("totalCoreCurrentWarningValue", thresholdVo.getTxWarningVal());
                resultMap.put("totalCoreCurrentThresholdValue", thresholdVo.getTxDl());
            } else if (TransfromerTreeEnum.JJ_EQM.getValue().equals(vo.getSubEquipmentType())) {
                resultMap.put("totalCoreCurrentWarningValue", thresholdVo.getJjWarningVal());
                resultMap.put("totalCoreCurrentThresholdValue", thresholdVo.getJjDl());
            }
        }
        return resultMap;
    }

	@Override
	public List<Map<String, Object>> queryHistory(String sensorCode, LocalDateTime begin, LocalDateTime end) {
		return transformerIcgeMapper.queryHistory( sensorCode,  begin,  end);
	}
}