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

import cn.hutool.core.date.DateUtil;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.pq.constant.Param;
import com.njcn.device.pq.pojo.po.PmsAbnormalRules;
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
import com.njcn.prepare.harmonic.mapper.mysql.line.PmsAbnormalRulesMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.RMpMonitorEvaluateDMapper;
import com.njcn.prepare.harmonic.pojo.dto.DataVFiveItemDTO;
import com.njcn.prepare.harmonic.pojo.mysql.RMpMonitorEvaluateDPO;
import com.njcn.prepare.harmonic.pojo.po.DataFlicker;
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 com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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, RMpMonitorEvaluateDPO> implements RMpMonitorEvaluateDService {

    private final LineFeignClient lineFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final DataVInfluxdbService dataVInfluxdbService;
    private final PmsAbnormalRulesMapper pmsAbnormalRulesMapper;
    private final DataIntegrityRateInfluxService dataIntegrityRateInfluxService;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    @Async("asyncExecutor")
    @SneakyThrows
    public void dayDataJobHandler(List<String> indexLists, String dataDate) {

        //1、取出规则
        List<PmsAbnormalRules> pmsAbnormalRules = pmsAbnormalRulesMapper.selectList (null);

        List<DictData> dictDataList = dicDataFeignClient.getDicDataByTypeName (DicDataTypeEnum.DEV_VOLTAGE.getName ( )).getData ( );

        List<RMpMonitorEvaluateDPO> rMpMonitorEvaluateDPOS = new ArrayList<> ();

        indexLists.forEach (temp -> {
            LineDetailDataVO data = lineFeignClient.getLineDetailData (temp).getData ( );
            String devid = lineFeignClient.getLineIdByDevId(temp).getData();


            /*todo 统计间隔，电压等级取值方式后期提供融合版本接口获取不然pms，pqs系统取值方式不一样*/
            /*统计间隔*/
            Integer statisticalInterval = data.getTimeInterval ();
            /*电压等级*/
//            Double voltage = PublicUtil.getVoltage (temp, dictDataList);
            Double voltage =Double.parseDouble (data.getScale ().substring (0, data.getScale ().length ()-2));

            List<DataVFiveItemDTO> fiveItems = dataVInfluxdbService.getFiveItems (temp, dataDate, statisticalInterval);
            RMpMonitorEvaluateDPO rMpMonitorEvaluateDPO = new RMpMonitorEvaluateDPO();


             rMpMonitorEvaluateDPO = calculateRMpMonitorEvaluateDPO (rMpMonitorEvaluateDPO,fiveItems, pmsAbnormalRules, voltage,data);
            Date date = DateUtil.parse(dataDate);

            DataFlicker twoFlickerData = dataIntegrityRateInfluxService.getTwoFlickerData (temp, date, 5);

            if(Objects.isNull (twoFlickerData)){
                rMpMonitorEvaluateDPO.setPltCount (0);
                rMpMonitorEvaluateDPO.setPstCount (0);
            }else {
                rMpMonitorEvaluateDPO.setPltCount (twoFlickerData.getPltCount ());
                rMpMonitorEvaluateDPO.setPstCount (twoFlickerData.getPstCount ());
            }
            rMpMonitorEvaluateDPO.setAllMinuteCount (fiveItems.size ());
            rMpMonitorEvaluateDPO.setDeviceId(devid);
            rMpMonitorEvaluateDPO.setDataDate (date);
            rMpMonitorEvaluateDPO.setMeasurementPointId (temp);

            rMpMonitorEvaluateDPOS.add (rMpMonitorEvaluateDPO);

        });
        this.saveOrUpdateBatchByMultiId (rMpMonitorEvaluateDPOS,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.1%，20%】之间；
     * 7、负序电压不平衡度在【0，20%】。满足以上条件则是一条有效数据
     * @Param: [fiveItems, pmsAbnormalRules, voltage]
     * @return: java.lang.Integer
     * @Author: clam
     * @Date: 2023/2/23
     */
    private RMpMonitorEvaluateDPO calculateRMpMonitorEvaluateDPO(RMpMonitorEvaluateDPO rMpMonitorEvaluateDPO,List<DataVFiveItemDTO> fiveItems, List<PmsAbnormalRules> pmsAbnormalRules, Double voltage,LineDetailDataVO 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;

               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++;
               }
           }
       }

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