package com.njcn.prepare.harmonic.service.mysql.Impl.line;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.harmonic.pojo.po.RMpVThd;
import com.njcn.influx.pojo.po.DataV;
import com.njcn.influx.utils.InfluxDbUtils;
import com.njcn.prepare.harmonic.constant.AlgorithmParam;
import com.njcn.prepare.harmonic.mapper.mysql.line.RMpVThdMapper;
import com.njcn.prepare.harmonic.pojo.oracle.PqLinedetailPO;
import com.njcn.prepare.harmonic.pojo.param.LineParam;
import com.njcn.prepare.harmonic.service.mysql.line.DistortionRateService;
import com.njcn.prepare.harmonic.service.oracle.DataVOraclePOService;
import com.njcn.prepare.harmonic.service.oracle.PqLinedetailPOService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiaoyao
 * @version 1.0.0
 * @createTime 2022/11/7 9:19
 */
@Slf4j
@Service
@AllArgsConstructor
public class DistortionRateServiceImpl implements DistortionRateService {

    private final InfluxDbUtils influxDbUtils;

    private final LineFeignClient lineFeignClient;

    private final RMpVThdMapper rMpVThdMapper;

    private final
    PqLinedetailPOService pqLinedetailPOService;
    private  final
    DataVOraclePOService dataVOraclePOService;
    @Override
    @Async("asyncExecutor")
    public void distortionRate(LineParam lineParam) {
        List<String> lineIdOutList;
        if (CollUtil.isEmpty (lineParam.getLineIds ( ))) {
            List<Overlimit> overLimitList = getAllLineOutData ( );
            lineIdOutList = overLimitList.stream ( ).map (Overlimit::getId).collect (Collectors.toList ( ));
        } else {
            lineIdOutList = new ArrayList<> (lineParam.getLineIds ( ));
        }
        LocalDateTime local = LocalDateTimeUtil.parse (lineParam.getDataDate () + "T00:00:00");
        for (String lineId : lineIdOutList) {
            List<DataV> rateOut = getDistortionRateInfluxDb (lineId, lineParam.getDataDate());
            if (rateOut.size ( ) > 0) {
                Map<String, Object> inMap = new HashMap<> ( );
                inMap.put ("lineId", lineId);
                inMap.put ("dataType", "0");
                inMap.put ("dataDate", local);
                inMap.put ("vThd", rateOut.get (0).getVThd ( ));
                rMpVThdMapper.insertRate (inMap);
            }
        }
    }


    private List<DataV> getDistortionRateInfluxDb(String lineId, String date) {
        String processParam = " and line_id = '" + lineId + "' and time >= '" + date + " 00:00:00' and time <= '" + date + " 23:59:59' tz('Asia/Shanghai')";
        QueryResult result = influxDbUtils.query ("SELECT line_id, max(v_thd) as v_thd FROM data_v WHERE phasic_type != 'T' and value_type = 'CP95'" + processParam);
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper ( );
        return resultMapper.toPOJO (result, DataV.class);
    }

    private List<Overlimit> getAllLineOutData() {
        return lineFeignClient.getAllLineOverLimit ("harmonic-boot", "").getData ( );
    }

    @Override
    public void distortionRateBySource(LineParam lineParam) {

        if (Objects.equals (lineParam.getDataSource ( ), AlgorithmParam.ORACLE_DATA)) {
            hanlderOracleData (lineParam);
        } else if (Objects.equals (lineParam.getDataSource ( ), AlgorithmParam.INFLUX_DATA)) {
            distortionRate (lineParam);
        }

    }

    private void hanlderOracleData(LineParam lineParam) {
        Integer type = lineParam.getType ( );
        switch (type) {
//            case 1:
//                this.hanlderOracleYear (lineParam);
//                break;
//            case 2:
//                this.hanlderOracleQtr (lineParam);
//                break;
//            case 3:
//                this.hanlderOracleMonth (lineParam);
//                break;
            case 5:
                this.hanlderOracleDay (lineParam);
                break;
            default:
                break;
        }
    }

    @SneakyThrows
    private void hanlderOracleDay(LineParam lineParam) {
        List<String> lineIds = lineParam.getLineIds ( );
        String dataDate = lineParam.getDataDate ( );
        final Date tempDate = new SimpleDateFormat ("yyyy-MM-dd").parse (dataDate);
        List<RMpVThd> rMpVThdList = new ArrayList<> ( );


        lineIds.forEach (lineId -> {
            RMpVThd rMpVThd = new RMpVThd();
            /*获取mysql与Oracle监测点id对应关系*/

            PqLinedetailPO oracleIndexIdByMonitorId = pqLinedetailPOService.getOracleIndexIdByMonitorId (lineId);
            Double vThdMAx  = dataVOraclePOService.queryVThdMax(oracleIndexIdByMonitorId.getLineIndex(),dataDate);

            Map<String, Object> inMap = new HashMap<> ( );
            inMap.put ("lineId", lineId);
            inMap.put ("dataType", lineParam.getType ()+"");
            inMap.put ("dataDate", tempDate);
            inMap.put ("vThd", vThdMAx);
            rMpVThdMapper.insertRate (inMap);
//            rMpVThd.setMeasurementPointId (lineId);
//            rMpVThd.setDataType (lineParam.getType ()+"");
//            rMpVThd.setDataDate (tempDate);
//            rMpVThd.setVThd (vThdMAx);
        });
    }
}
