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.collections4.CollectionUtils;
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.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.huatek.busi.common.CacMonitorTypeCode;
import com.huatek.busi.common.SiteConstants.ArresterTreeEnum;
import com.huatek.busi.common.SiteConstants.ExternalTypeEnum;
import com.huatek.busi.common.SiteConstants.GisTreeEnum;
import com.huatek.busi.common.SiteConstants.SiteTreeEnum;
import com.huatek.busi.common.SiteConstants.TransfromerTreeEnum;
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.MeteorologicalStatisticsDto;
import com.huatek.busi.dto.curve.BaseCurveQueryDto;
import com.huatek.busi.dto.curve.PointItemDto;
import com.huatek.busi.entity.BusiOnlineMonitorData;
import com.huatek.busi.entity.BusiSiteTree;
import com.huatek.busi.entity.TransformerMeteorological;
import com.huatek.busi.mapper.TransformerMeteorologicalMapper;
import com.huatek.busi.service.BusiSiteTreeService;
import com.huatek.busi.service.arrester.ArresterMeteorologicalCacheService;
import com.huatek.busi.service.gis.SubstationMicGisNowService;
import com.huatek.busi.service.impl.cac.AbstractCacEtlService;
import com.huatek.busi.service.substation.SubstationMicCacheService;
import com.huatek.busi.service.transformer.TransformerMeteorologicalCacheService;
import com.huatek.busi.service.transformer.TransformerMeteorologicalService;
import com.huatek.busi.vo.MeteorologicalStatisticsVo;
import com.huatek.busi.vo.TransformerMeteorologicalVo;
import com.huatek.busi.vo.curve.PointItemVo;
import com.huatek.torch.frame.exception.OwlException;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;

/**
 * 变压器/电抗器——气象：021011、023003、024008、025001 ServiceImpl
 *
 * @author anker_cheng
 * @date Jun 26, 2019 1:11:48 PM
 */
@Component
@Service(interfaceClass = TransformerMeteorologicalService.class)
@Transactional(rollbackFor = Exception.class)
public class TransformerMeteorologicalServiceImpl extends AbstractCacEtlService<TransformerMeteorological>
    implements TransformerMeteorologicalService {

    @Autowired
    private TransformerMeteorologicalMapper transformerMeteorologicalMapper;
    @Autowired
    private TransformerMeteorologicalCacheService transformerMeteorologicalCacheService;
    @Autowired
    private ArresterMeteorologicalCacheService arresterMeteorologicalCacheService;
    @Autowired
    private SubstationMicGisNowService substationMicGisNowService;
    @Autowired
    private SubstationMicCacheService substationMicCacheService;
    @Autowired
    private BusiSiteTreeService busiSiteTreeService;

    @Override
    public void updateCurrentData(TransformerMeteorological cacEntity, EquipmentInfoDto equipmentInfo) {
        if (CacMonitorTypeCode.TRANSFORMER_MIC.isThis(cacEntity.getCacMonitorTypeCode())) {
            transformerMeteorologicalCacheService.saveTransformerMeteorologicalCache(cacEntity);
            return;
        }
        if (CacMonitorTypeCode.LIGHTNINGROD_MIC.isThis(cacEntity.getCacMonitorTypeCode())) {
            arresterMeteorologicalCacheService.saveArresterMeteorologicalCache(cacEntity);
            return;
        }
        if (CacMonitorTypeCode.GIS_METEOROLOGICAL.isThis(cacEntity.getCacMonitorTypeCode())) {
            substationMicGisNowService.saveSubstationMicGisNow(cacEntity);
            return;
        }
        if (CacMonitorTypeCode.SubstationMic.isThis(cacEntity.getCacMonitorTypeCode())) {
            substationMicCacheService.saveSubstationMicCache(cacEntity);
            return;
        }
    }

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

    @Override
    protected void saveHistoryData(TransformerMeteorological 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);
    }

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

    @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 = transformerMeteorologicalMapper.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<TransformerMeteorologicalVo> transformerMeteorologicalList =
                transformerMeteorologicalMapper.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 (transformerMeteorologicalList.isEmpty()) {
                transformerMeteorologicalList = new ArrayList<>();
                transformerMeteorologicalList.add(new TransformerMeteorologicalVo());
            }
            returnMap.put("data", transformerMeteorologicalList);
        } else {
            throw new RuntimeException("主设备编码不正确");
        }
        return returnMap;
    }

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

    // *****************************趋势图部分********************************\\
    @Override
    public List<BaseCurveQueryDto> findSensorCodeList(LocalDate day) {
        return transformerMeteorologicalMapper.findSensorCodeList(day.atStartOfDay(), day.plusDays(1).atStartOfDay());
    }

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

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