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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.commApi.CommLineClient;
import com.njcn.device.biz.pojo.dto.LineDTO;
import com.njcn.device.pq.constant.Param;
import com.njcn.device.pq.pojo.po.PmsAbnormalRules;
import com.njcn.influx.pojo.po.DataFlicker;
import com.njcn.prepare.harmonic.mapper.mysql.line.PmsAbnormalRulesMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.RMpMonitorEvaluateDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.pojo.dto.DataVFiveItemDTO;
import com.njcn.harmonic.pojo.po.algorithm.line.RMpMonitorEvaluateD;
import com.njcn.prepare.harmonic.service.influxdb.DataIntegrityRateInfluxService;
import com.njcn.prepare.harmonic.service.influxdb.DataVInfluxdbService;
import com.njcn.prepare.harmonic.service.mysql.line.RMpMonitorEvaluateDService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Description:
 * 接口文档访问地址：http://serverIP:port/swagger-ui.html
 * Date: 2023/4/19  15:42【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class RMpMonitorEvaluateDServiceImpl extends MppServiceImpl<RMpMonitorEvaluateDMapper, RMpMonitorEvaluateD> implements RMpMonitorEvaluateDService {

    private final CommLineClient commLineClient;
    private final DataVInfluxdbService dataVInfluxdbService;
    private final PmsAbnormalRulesMapper pmsAbnormalRulesMapper;
    private final DataIntegrityRateInfluxService dataIntegrityRateInfluxService;

    /***
     * 监测点报表--日统计
     * @author hongawen
     * @date 2023/11/3 14:48
     * @param calculatedParam 查询条件
     */
    @Override
    public void handleDay(CalculatedParam calculatedParam) {
        //1、取出规则
        List<PmsAbnormalRules> pmsAbnormalRules = pmsAbnormalRulesMapper.selectList(null);
        String  beginDay =LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        String endDay = LocalDateTimeUtil.format(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        //以尺寸1000分片
        List<List<String>> pendingIds = ListUtils.partition(calculatedParam.getIdList(), 100);
        for (List<String> pendingId : pendingIds) {
            List<LineDTO> lineDTOList = commLineClient.getLineDetailBatch(pendingId).getData();
            List<RMpMonitorEvaluateD> rMpMonitorEvaluateDS = new ArrayList<>();
            for (LineDTO lineDTO : lineDTOList) {
                if (ObjectUtil.isNotNull(lineDTO)) {
                    /*todo 统计间隔，电压等级取值方式后期提供融合版本接口获取不然pms，pqs系统取值方式不一样*/
                    /*统计间隔*/
                    Integer statisticalInterval = lineDTO.getTimeInterval();
                    /*电压等级*/
                    Double voltage = Double.parseDouble(lineDTO.getVoltageLevel());
                    List<DataVFiveItemDTO> fiveItems = dataVInfluxdbService.getFiveItems(lineDTO.getLineId(), beginDay, endDay, statisticalInterval);
                    RMpMonitorEvaluateD rMpMonitorEvaluateD = new RMpMonitorEvaluateD();
                    rMpMonitorEvaluateD = calculateRMpMonitorEvaluateDPO(rMpMonitorEvaluateD, fiveItems, pmsAbnormalRules, voltage, lineDTO);
                    Date date = DateUtil.parse(beginDay);
                    DataFlicker twoFlickerData = dataIntegrityRateInfluxService.getTwoFlickerData(lineDTO.getLineId(), date, 5);
                    LocalDate localDate = LocalDateTimeUtil.parseDate(beginDay, DatePattern.NORM_DATETIME_PATTERN);

                    if (Objects.isNull(twoFlickerData)) {
                        rMpMonitorEvaluateD.setPltCount(0);
                        rMpMonitorEvaluateD.setPstCount(0);
                    } else {
                        rMpMonitorEvaluateD.setPltCount(twoFlickerData.getPltCount());
                        rMpMonitorEvaluateD.setPstCount(twoFlickerData.getPstCount());
                    }
                    rMpMonitorEvaluateD.setAllMinuteCount(fiveItems.size());
                    rMpMonitorEvaluateD.setDeviceId(lineDTO.getDevId());
                    rMpMonitorEvaluateD.setDataDate(localDate);
                    rMpMonitorEvaluateD.setMeasurementPointId(lineDTO.getLineId());
                    rMpMonitorEvaluateDS.add(rMpMonitorEvaluateD);
                }
            }
            if (CollUtil.isNotEmpty(rMpMonitorEvaluateDS)) {
                this.saveOrUpdateBatchByMultiId(rMpMonitorEvaluateDS, 500);
            }
        }
    }


    /**
     * @Description: 3、频率在【45，55】之间；
     * 4、相电压有效值在【0.85p.u.，1.2p.u.】之间；p.u=电压等级/1.732
     * 5、线电压有效值在【0.85p.u.，1.2p.u.】之间；p.u=电压等级
     * 6、电压总谐波畸变率在【0%，20%】之间；
     * 7、负序电压不平衡度在【0，20%】。满足以上条件则是一条有效数据
     * @Param: [fiveItems, pmsAbnormalRules, voltage]
     * @return: java.lang.Integer
     * @Author: clam
     * @Date: 2023/2/23
     */
    private RMpMonitorEvaluateD calculateRMpMonitorEvaluateDPO(RMpMonitorEvaluateD rMpMonitorEvaluateD, List<DataVFiveItemDTO> fiveItems, List<PmsAbnormalRules> pmsAbnormalRules, Double voltage, LineDTO data) {

        Integer freqCount = 0;
        Integer unbalanceCount = 0;
        Integer phaseVoltageCount = 0;
        Integer lineVoltageCount = 0;
        Integer vThdCount = 0;
        Integer effectiveMinuteCount = 0;

        PmsAbnormalRules freqLimit = pmsAbnormalRules.stream().filter(temp -> Objects.equals(temp.getTarget(), Param.TARGET_FREQ)).collect(Collectors.toList()).get(0);
        PmsAbnormalRules rmsLimit = pmsAbnormalRules.stream().filter(temp -> Objects.equals(temp.getTarget(), Param.TARGET_RMS)).collect(Collectors.toList()).get(0);
        PmsAbnormalRules rms_lvrLimit = pmsAbnormalRules.stream().filter(temp -> Objects.equals(temp.getTarget(), Param.TARGET_RMS_LVR)).collect(Collectors.toList()).get(0);
        PmsAbnormalRules v_thdLimit = pmsAbnormalRules.stream().filter(temp -> Objects.equals(temp.getTarget(), Param.TARGET_V_THD)).collect(Collectors.toList()).get(0);
        PmsAbnormalRules v_unbalanceLimit = pmsAbnormalRules.stream().filter(temp -> Objects.equals(temp.getTarget(), Param.TARGET_V_UNBALANCE)).collect(Collectors.toList()).get(0);
        if (!CollectionUtils.isEmpty(fiveItems)) {
            for (DataVFiveItemDTO fiveItem : fiveItems) {
                Double freqMax = fiveItem.getFreqMax();
                Double freqMin = fiveItem.getFreqMin();

                Double rmsMax = fiveItem.getRmsMax();
                Double rmsMin = fiveItem.getRmsMin();
                Double vThdMax = fiveItem.getVThdMax();
                Double vThdMin = fiveItem.getVThdMin();

                Double vUnbalanceMax = fiveItem.getVUnbalanceMax();
                Double vUnbalanceMin = fiveItem.getVUnbalanceMin();
                Double rmsLvrMax = fiveItem.getRmsLvrMax();
                Double rmsLvrMin = fiveItem.getRmsLvrMin();

                Boolean rmsflag = false;
                Boolean rmsLvrflag = false;
                Boolean vUnbalanceflag = false;

//                freqCount++;
//                unbalanceCount++;
//                phaseVoltageCount++;
//                lineVoltageCount++;
//                vThdCount++;
//                effectiveMinuteCount++;
                // 先注释掉 校验跑出监测点
                if (freqLimit.getLowerLimit() <= freqMin && freqMax <= freqLimit.getUpperLimit()) {
                    freqCount++;
                }
                /*，监测点的接线方式，如果是星形接线这个指标要判断，角形界面则不判断，默认它是正常的*/
                //河北没有线电压修改成先改成全部都是有效的线电压

                if (Objects.equals("0", data.getPtType())) {
                    if (rmsLimit.getLowerLimit() * (voltage / 1.732) <= rmsMin && rmsMax <= rmsLimit.getUpperLimit() * (voltage / 1.732)) {
                        phaseVoltageCount++;
                        rmsflag = true;
                    }
                } else {
                    rmsflag = true;
                    phaseVoltageCount++;
                }
//                if (Objects.equals("1", data.getPtPhaseType())) {
//                    if (rms_lvrLimit.getLowerLimit() * voltage <= rmsLvrMin && rmsLvrMax <= rms_lvrLimit.getUpperLimit() * voltage) {
//                        lineVoltageCount++;
//                        rmsLvrflag = true;
//                    }
//
//                } else {
                    rmsLvrflag = true;
                    lineVoltageCount++;

//                }
                if (Objects.equals("1", data.getPtPhaseType()) && Objects.equals("0", data.getPtType())) {
                    if (v_unbalanceLimit.getLowerLimit() <= vUnbalanceMin && vUnbalanceMax <= v_unbalanceLimit.getUpperLimit()
                    ) {
                        unbalanceCount++;
                        vUnbalanceflag = true;
                    }
                } else {
                    unbalanceCount++;
                    vUnbalanceflag = true;
                }


                if (v_thdLimit.getLowerLimit() <= vThdMin && vThdMax <= v_thdLimit.getUpperLimit()) {
                    vThdCount++;
                }


                if (freqLimit.getLowerLimit() <= freqMin && freqMax <= freqLimit.getUpperLimit() &&
                        rmsflag &&
                        rmsLvrflag &&
                        v_thdLimit.getLowerLimit() <= vThdMin && vThdMax <= v_thdLimit.getUpperLimit() &&
                        vUnbalanceflag

                ) {
                    effectiveMinuteCount++;
                }
            }
        }

        rMpMonitorEvaluateD.setEffectiveMinuteCount(effectiveMinuteCount);
        rMpMonitorEvaluateD.setFreqCount(freqCount);
        rMpMonitorEvaluateD.setPhaseVoltageCount(phaseVoltageCount);
        rMpMonitorEvaluateD.setLineVoltageCount(lineVoltageCount);
        rMpMonitorEvaluateD.setVThdCount(vThdCount);
        rMpMonitorEvaluateD.setUnbalanceCount(unbalanceCount);
        return rMpMonitorEvaluateD;
    }
}
