package com.njcn.influx.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.influx.bo.po.*;
import com.njcn.influx.mapper.OracleRmpEventDetailPOMapper;
import com.njcn.influx.mapper.RmpEventDetailPOMapper;
import com.njcn.influx.service.OracleEventDetailToMysqlService;
import com.njcn.influx.service.PqLineBakService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * data-migration
 *
 * @author cdf
 * @date 2024/2/19
 */
@RequiredArgsConstructor
@Service
@DS("target")
public class OracleEventDetailToMysqlServiceImpl extends ServiceImpl<RmpEventDetailPOMapper, RmpEventDetailPO> implements OracleEventDetailToMysqlService {

    private final PqLineBakService pqLineBakService;

    private final OracleRmpEventDetailPOMapper oracleRmpEventDetailPOMapper;

    private final RmpEventDetailPOMapper rmpEventDetailPOMapper;

    /**
     * 每小时执行一次该方法
     * 1.读取Oracle中暂态事件表信息(PQS_EVENTDETAIL)
     * 2.读取Mysql中pq_line_bak表获取Oracle和Mysql中监测点关系
     * 3.读取Mysql中r_mp_event_detail
     */
    @Override
    public void eventBatch(LocalDateTime start, LocalDateTime end){
        List<PqLineBak> list = pqLineBakService.list();
        //lineId:Oracle监测点ID id:Mysql监测点ID
        Map<String, String> oracleRelationMysql = list.stream().collect(Collectors.toMap(PqLineBak::getLineId, PqLineBak::getId));
        //获取Oracle字典 暂降类型：12 暂降原因：13
        List<DictData>  oracleReason= oracleRmpEventDetailPOMapper.selectByDicCodeList("暂降原因");
        List<DictData>  oracleType= oracleRmpEventDetailPOMapper.selectByDicCodeList("暂降类型");
        //获取Mysql字典
        List<DictData> eventType = rmpEventDetailPOMapper.selectByDicCodeList("Event_Statis");
        List<DictData> mysqlReason = rmpEventDetailPOMapper.selectByDicCodeList("Event_Reason");
        List<DictData> mysqlType = rmpEventDetailPOMapper.selectByDicCodeList("Event_Type");
        //字典类型
        Map<String, String> mapReason = getRelationList(oracleReason, mysqlReason);
        Map<String, String> mapType = getRelationList(oracleType, mysqlType);

        List<RmpEventDetailPO> poList=new ArrayList<>();
        List<OracleRmpEventDetailPO> oracleRmpEventDetailPOList = oracleRmpEventDetailPOMapper.selectList(new LambdaQueryWrapper<OracleRmpEventDetailPO>().between(OracleRmpEventDetailPO::getStartTime,start,end));
        RmpEventDetailPO po;
        for (OracleRmpEventDetailPO oracleDetail : oracleRmpEventDetailPOList) {
            if(oracleRelationMysql.containsKey(oracleDetail.getMeasurementPointId())){
                String mysqlLineID = oracleRelationMysql.get(oracleDetail.getMeasurementPointId());
                po=new RmpEventDetailPO();
                po.setMeasurementPointId(mysqlLineID);
                po.setEventType(eventTypeId(oracleDetail.getEventType(),eventType));
                po.setAdvanceReason(getDicId(oracleDetail.getAdvanceReason(),mapReason));
                po.setAdvanceType(getDicId(oracleDetail.getAdvanceType(),mapType));
                po.setEventassIndex(oracleDetail.getEventassIndex());
                po.setDqTime(oracleDetail.getDqTime());
                po.setDealTime(oracleDetail.getDealTime());
                po.setNum(oracleDetail.getNum());
                po.setFileFlag(oracleDetail.getFileFlag());
                po.setDealFlag(oracleDetail.getDealFlag());

                if(Objects.nonNull(oracleDetail.getFirstTime())) {
                    po.setFirstTime(oracleDetail.getFirstTime().plus(oracleDetail.getFirstMs().intValue(), ChronoUnit.MILLIS));
                }
                po.setFirstType(oracleDetail.getFirstType());
                po.setFirstMs(oracleDetail.getFirstMs());
                po.setEnergy(oracleDetail.getEnergy());
                po.setSeverity(oracleDetail.getSeverity());
                po.setSagsource(oracleDetail.getSagsource());
                LocalDateTime startTime = oracleDetail.getStartTime();
                LocalDateTime time = startTime.plus(oracleDetail.getMs(), ChronoUnit.MILLIS);
                po.setStartTime(time);
                po.setDuration(oracleDetail.getDuration().divide(BigDecimal.valueOf(1000)));
                po.setFeatureAmplitude(oracleDetail.getFeatureAmplitude());
                po.setPhase(oracleDetail.getPhase());
                po.setEventDescribe(oracleDetail.getEventDescribe());
                po.setWavePath(oracleDetail.getWavePath());
                po.setTransientValue(oracleDetail.getTransientValue());
                poList.add(po);
            }
        }
        if(CollUtil.isNotEmpty(poList)){
            this.remove(new LambdaQueryWrapper<RmpEventDetailPO>().between(RmpEventDetailPO::getStartTime, start, end));
            this.saveBatch(poList,500);
        }

    }


    //获取暂降类型id
    private String eventTypeId(String eventType, List<DictData> eventTypeList){
        String code="";
        //事件类型（0：扰动，1：暂降，2：暂升，3：中断，4：其他，5：录波）
        if("0".equals(eventType)){
            code="Disturbance";
        }
        if("1".equals(eventType)){
            code="Voltage_Dip";
        }
        if("2".equals(eventType)){
            code="Voltage_Rise";
        }
        if("3".equals(eventType)){
            code="Short_Interruptions";
        }
        if("4".equals(eventType)){
            code="Other";
        }
        if("5".equals(eventType)){
            code="Recording_Wave";
        }
        String finalCode = code;
        DictData dictData = eventTypeList.stream().filter(x -> finalCode.equals(x.getCode())).findFirst().get();
        if(ObjectUtil.isNotNull(dictData)){
            return dictData.getId();
        }
        return "";
    }

    //类型匹配
    private Map<String,String> getRelationList(List<DictData> oracleReason,List<DictData> mysqlReason){
        Map<String,String> map=new HashMap<>();
        for (DictData dictData : oracleReason) {
            for (DictData data : mysqlReason) {
                if(dictData.getAlgoDescribe().equals(data.getAlgoDescribe())){
                    map.put(dictData.getId(),data.getId());
                }
            }
        }
        return map;
    }

    private String getDicId(String dicReason,Map<String,String> map){
        if(map.containsKey(dicReason)){
            return map.get(dicReason);
        }
        return "";
    }

}
