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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.harmonic.pojo.po.LimitRate;
import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.harmonic.pojo.po.day.RStatLimitTargetDPO;
import com.njcn.influxdb.utils.InfluxDbUtils;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatLimitTargetDMapper;
import com.njcn.prepare.harmonic.pojo.param.LineParam;
import com.njcn.prepare.harmonic.service.mysql.day.IRStatLimitRateDService;
import com.njcn.prepare.harmonic.service.mysql.line.LimitTargetService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.Point;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 生成limit_target表
 *
 * @author xiaoyao
 * @version 1.0.0
 * @createTime 2022/10/26 13:41
 */
@Slf4j
@Service
@AllArgsConstructor
public class LimitTargetServiceImpl extends MppServiceImpl<RStatLimitTargetDMapper, RStatLimitTargetDPO> implements LimitTargetService {

    private final InfluxDbUtils influxDbUtils;

    private final IRStatLimitRateDService statLimitRateDService;

    @Override
    @Async("asyncExecutor")
    public void getLimitTargetData(LineParam lineParam) {
        List<String> records;
        Date dateOut = DateUtil.parse(lineParam.getDataDate());
        if (CollUtil.isEmpty(lineParam.getLineIds())){
            List<LimitRate> limitRateData = getLimitRateData(null,lineParam.getDataDate());
            records = processOutData(limitRateData,dateOut);
        }else {
            List<LimitRate> limitRateData = new ArrayList<>();
            for (String lineId : lineParam.getLineIds()){
                List<LimitRate> limitRateOut = getLimitRateData(lineId,lineParam.getDataDate());
                limitRateData.addAll(limitRateOut);
            }
            records = processOutData(limitRateData,dateOut);
        }
        influxDbUtils.batchInsert(influxDbUtils.getDbName(),"", InfluxDB.ConsistencyLevel.ALL, records);
    }

    @Override
    @Async("asyncExecutor")
    public void limitTargetData(LineParam lineParam,String time) {
        log.info(LocalDateTime.now()+"r_stat_limit_target_d开始执行=======》");
        List<RStatLimitTargetDPO> list = new ArrayList<>();
        Date dateOut = DateUtil.parse(time);
        List<RStatLimitRateDPO> limitRateData = new ArrayList<>();
        if (CollUtil.isEmpty(lineParam.getLineIds())){
            limitRateData = getLimitRateDataFromMysql(null,time);
        } else {
            limitRateData = getLimitRateDataFromMysql(lineParam.getLineIds(),time);
        }
        if (!CollectionUtils.isEmpty(limitRateData)){
            for (RStatLimitRateDPO limitRate : limitRateData){
                RStatLimitTargetDPO limitTarget = new RStatLimitTargetDPO();
                limitTarget.setTime(dateOut);
                limitTarget.setLineId(limitRate.getLineId());
                limitTarget.setPhasicType(limitRate.getPhasicType());
                chanelData(limitRate,limitTarget);
                list.add(limitTarget);
            }
        }
        this.saveOrUpdateBatchByMultiId(list,50);
        log.info(LocalDateTime.now()+"r_stat_limit_target_d开始执行=======》");
    }

    private List<LimitRate> getLimitRateData(String lineId,String date){
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT * FROM limit_rate WHERE time >= '").append(date).append(" 00:00:00' and time <= '")
                .append(date).append(" 23:59:59' ").append(" and phasic_type = 'T'");
        if (StrUtil.isNotBlank(lineId)) {
            sql.append(" and line_id = '").append(lineId).append("'");
        }
        sql.append(" tz('Asia/Shanghai')");
        QueryResult sqlResult = influxDbUtils.query(sql.toString());
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        return resultMapper.toPOJO(sqlResult, LimitRate.class);
    }

    private List<RStatLimitRateDPO> getLimitRateDataFromMysql(List<String> lineList, String date){
        return statLimitRateDService.findList(lineList,date);
    }


    private List<String> processOutData(List<LimitRate> limitRateData,Date dateOut){
        List<String> records = new ArrayList<>();
        for (LimitRate limitRate : limitRateData){
            Map<String, String> tags = processTagDate(limitRate);
            Map<String, Object> fields = processFieldsDate(limitRate);
            Point point = influxDbUtils.pointBuilder("limit_target", dateOut.getTime(), TimeUnit.MILLISECONDS,tags, fields);
            BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).tag("line_id", limitRate.getLineId()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
            batchPoints.point(point);
            records.add(batchPoints.lineProtocol());
        }
        return records;
    }

    private Map<String, String> processTagDate(LimitRate limitRate){
        Map<String, String> tags = new HashMap<>();
        tags.put("line_id",limitRate.getLineId());
        tags.put("phasic_type",limitRate.getPhasicType());
        return tags;
    }

    private Map<String, Object> processFieldsDate(LimitRate limitRate){
        Map<String, Object> fields = new HashMap<>();
        fields.put("alltime",limitRate.getAllTime());
        fields.put("flicker_alltime",limitRate.getFlickerAllTime());
        fields.put("freq_dev_overtime",(limitRate.getFreqDevOverTime()>1)?1:0);
        fields.put("voltage_dev_overtime",(limitRate.getVoltageDevOverTime()>1)?1:0);
        fields.put("ubalance_overtime",(limitRate.getUBalanceOverTime()>1)?1:0);
        fields.put("flicker_overtime",(limitRate.getFlickerOverTime()>1)?1:0);
        fields.put("uaberrance_overtime",(limitRate.getUAberranceOverTime()>1)?1:0);
        fields.put("i_neg_overtime",(limitRate.getINegOverTime()>1)?1:0);
        fields.put("uharm_2_overtime",(limitRate.getUHarm2OverTime()>1)?1:0);
        fields.put("uharm_3_overtime",(limitRate.getUHarm3OverTime()>1)?1:0);
        fields.put("uharm_4_overtime",(limitRate.getUHarm4OverTime()>1)?1:0);
        fields.put("uharm_5_overtime",(limitRate.getUHarm5OverTime()>1)?1:0);
        fields.put("uharm_6_overtime",(limitRate.getUHarm6OverTime()>1)?1:0);
        fields.put("uharm_7_overtime",(limitRate.getUHarm7OverTime()>1)?1:0);
        fields.put("uharm_8_overtime",(limitRate.getUHarm8OverTime()>1)?1:0);
        fields.put("uharm_9_overtime",(limitRate.getUHarm9OverTime()>1)?1:0);
        fields.put("uharm_10_overtime",(limitRate.getUHarm10OverTime()>1)?1:0);
        fields.put("uharm_11_overtime",(limitRate.getUHarm11OverTime()>1)?1:0);
        fields.put("uharm_12_overtime",(limitRate.getUHarm12OverTime()>1)?1:0);
        fields.put("uharm_13_overtime",(limitRate.getUHarm13OverTime()>1)?1:0);
        fields.put("uharm_14_overtime",(limitRate.getUHarm14OverTime()>1)?1:0);
        fields.put("uharm_15_overtime",(limitRate.getUHarm15OverTime()>1)?1:0);
        fields.put("uharm_16_overtime",(limitRate.getUHarm16OverTime()>1)?1:0);
        fields.put("uharm_17_overtime",(limitRate.getUHarm17OverTime()>1)?1:0);
        fields.put("uharm_18_overtime",(limitRate.getUHarm18OverTime()>1)?1:0);
        fields.put("uharm_19_overtime",(limitRate.getUHarm19OverTime()>1)?1:0);
        fields.put("uharm_20_overtime",(limitRate.getUHarm20OverTime()>1)?1:0);
        fields.put("uharm_21_overtime",(limitRate.getUHarm21OverTime()>1)?1:0);
        fields.put("uharm_22_overtime",(limitRate.getUHarm22OverTime()>1)?1:0);
        fields.put("uharm_23_overtime",(limitRate.getUHarm23OverTime()>1)?1:0);
        fields.put("uharm_24_overtime",(limitRate.getUHarm24OverTime()>1)?1:0);
        fields.put("uharm_25_overtime",(limitRate.getUHarm25OverTime()>1)?1:0);
        fields.put("iharm_2_overtime",(limitRate.getIHarm2OverTime()>1)?1:0);
        fields.put("iharm_3_overtime",(limitRate.getIHarm3OverTime()>1)?1:0);
        fields.put("iharm_4_overtime",(limitRate.getIHarm4OverTime()>1)?1:0);
        fields.put("iharm_5_overtime",(limitRate.getIHarm5OverTime()>1)?1:0);
        fields.put("iharm_6_overtime",(limitRate.getIHarm6OverTime()>1)?1:0);
        fields.put("iharm_7_overtime",(limitRate.getIHarm7OverTime()>1)?1:0);
        fields.put("iharm_8_overtime",(limitRate.getIHarm8OverTime()>1)?1:0);
        fields.put("iharm_9_overtime",(limitRate.getIHarm9OverTime()>1)?1:0);
        fields.put("iharm_10_overtime",(limitRate.getIHarm10OverTime()>1)?1:0);
        fields.put("iharm_11_overtime",(limitRate.getIHarm11OverTime()>1)?1:0);
        fields.put("iharm_12_overtime",(limitRate.getIHarm12OverTime()>1)?1:0);
        fields.put("iharm_13_overtime",(limitRate.getIHarm13OverTime()>1)?1:0);
        fields.put("iharm_14_overtime",(limitRate.getIHarm14OverTime()>1)?1:0);
        fields.put("iharm_15_overtime",(limitRate.getIHarm15OverTime()>1)?1:0);
        fields.put("iharm_16_overtime",(limitRate.getIHarm16OverTime()>1)?1:0);
        fields.put("iharm_17_overtime",(limitRate.getIHarm17OverTime()>1)?1:0);
        fields.put("iharm_18_overtime",(limitRate.getIHarm18OverTime()>1)?1:0);
        fields.put("iharm_19_overtime",(limitRate.getIHarm19OverTime()>1)?1:0);
        fields.put("iharm_20_overtime",(limitRate.getIHarm20OverTime()>1)?1:0);
        fields.put("iharm_21_overtime",(limitRate.getIHarm21OverTime()>1)?1:0);
        fields.put("iharm_22_overtime",(limitRate.getIHarm22OverTime()>1)?1:0);
        fields.put("iharm_23_overtime",(limitRate.getIHarm23OverTime()>1)?1:0);
        fields.put("iharm_24_overtime",(limitRate.getIHarm24OverTime()>1)?1:0);
        fields.put("iharm_25_overtime",(limitRate.getIHarm25OverTime()>1)?1:0);
        fields.put("inuharm_1_overtime",(limitRate.getInuHarm1OverTime()>1)?1:0);
        fields.put("inuharm_2_overtime",(limitRate.getInuHarm2OverTime()>1)?1:0);
        fields.put("inuharm_3_overtime",(limitRate.getInuHarm3OverTime()>1)?1:0);
        fields.put("inuharm_4_overtime",(limitRate.getInuHarm4OverTime()>1)?1:0);
        fields.put("inuharm_5_overtime",(limitRate.getInuHarm5OverTime()>1)?1:0);
        fields.put("inuharm_6_overtime",(limitRate.getInuHarm6OverTime()>1)?1:0);
        fields.put("inuharm_7_overtime",(limitRate.getInuHarm7OverTime()>1)?1:0);
        fields.put("inuharm_8_overtime",(limitRate.getInuHarm8OverTime()>1)?1:0);
        fields.put("inuharm_9_overtime",(limitRate.getInuHarm9OverTime()>1)?1:0);
        fields.put("inuharm_10_overtime",(limitRate.getInuHarm10OverTime()>1)?1:0);
        fields.put("inuharm_11_overtime",(limitRate.getInuHarm11OverTime()>1)?1:0);
        fields.put("inuharm_12_overtime",(limitRate.getInuHarm12OverTime()>1)?1:0);
        fields.put("inuharm_13_overtime",(limitRate.getInuHarm13OverTime()>1)?1:0);
        fields.put("inuharm_14_overtime",(limitRate.getInuHarm14OverTime()>1)?1:0);
        fields.put("inuharm_15_overtime",(limitRate.getInuHarm15OverTime()>1)?1:0);
        fields.put("inuharm_16_overtime",(limitRate.getInuHarm16OverTime()>1)?1:0);
        return fields;
    }

    private void chanelData(RStatLimitRateDPO limitRate, RStatLimitTargetDPO limitTarget){
        limitTarget.setAllTime((limitRate.getAllTime()>1)?1:0);
        limitTarget.setFlickerAllTime((limitRate.getFlickerAllTime()>1)?1:0);
        limitTarget.setFreqDevOvertime((limitRate.getFreqDevOvertime()>1)?1:0);
        limitTarget.setVoltageDevOvertime((limitRate.getVoltageDevOvertime()>1)?1:0);
        limitTarget.setUbalanceOvertime((limitRate.getUbalanceOvertime()>1)?1:0);
        limitTarget.setFlickerOvertime((limitRate.getFlickerOvertime()>1)?1:0);
        limitTarget.setUaberranceOvertime((limitRate.getUaberranceOvertime()>1)?1:0);
        limitTarget.setINegOvertime((limitRate.getINegOvertime()>1)?1:0);

        limitTarget.setUharm2Overtime((limitRate.getUharm2Overtime()>1)?1:0);
        limitTarget.setUharm2Overtime((limitRate.getUharm2Overtime()>1)?1:0);
        limitTarget.setUharm3Overtime((limitRate.getUharm3Overtime()>1)?1:0);
        limitTarget.setUharm4Overtime((limitRate.getUharm4Overtime()>1)?1:0);
        limitTarget.setUharm5Overtime((limitRate.getUharm5Overtime()>1)?1:0);
        limitTarget.setUharm6Overtime((limitRate.getUharm6Overtime()>1)?1:0);
        limitTarget.setUharm7Overtime((limitRate.getUharm7Overtime()>1)?1:0);
        limitTarget.setUharm8Overtime((limitRate.getUharm8Overtime()>1)?1:0);
        limitTarget.setUharm9Overtime((limitRate.getUharm9Overtime()>1)?1:0);
        limitTarget.setUharm10Overtime((limitRate.getUharm10Overtime()>1)?1:0);
        limitTarget.setUharm11Overtime((limitRate.getUharm11Overtime()>1)?1:0);
        limitTarget.setUharm12Overtime((limitRate.getUharm12Overtime()>1)?1:0);
        limitTarget.setUharm13Overtime((limitRate.getUharm13Overtime()>1)?1:0);
        limitTarget.setUharm14Overtime((limitRate.getUharm14Overtime()>1)?1:0);
        limitTarget.setUharm15Overtime((limitRate.getUharm15Overtime()>1)?1:0);
        limitTarget.setUharm16Overtime((limitRate.getUharm16Overtime()>1)?1:0);
        limitTarget.setUharm17Overtime((limitRate.getUharm17Overtime()>1)?1:0);
        limitTarget.setUharm18Overtime((limitRate.getUharm18Overtime()>1)?1:0);
        limitTarget.setUharm19Overtime((limitRate.getUharm19Overtime()>1)?1:0);
        limitTarget.setUharm20Overtime((limitRate.getUharm20Overtime()>1)?1:0);
        limitTarget.setUharm21Overtime((limitRate.getUharm21Overtime()>1)?1:0);
        limitTarget.setUharm22Overtime((limitRate.getUharm22Overtime()>1)?1:0);
        limitTarget.setUharm23Overtime((limitRate.getUharm23Overtime()>1)?1:0);
        limitTarget.setUharm24Overtime((limitRate.getUharm24Overtime()>1)?1:0);
        limitTarget.setUharm25Overtime((limitRate.getUharm25Overtime()>1)?1:0);

        limitTarget.setIharm2Overtime((limitRate.getIharm2Overtime()>1)?1:0);
        limitTarget.setIharm3Overtime((limitRate.getIharm3Overtime()>1)?1:0);
        limitTarget.setIharm4Overtime((limitRate.getIharm4Overtime()>1)?1:0);
        limitTarget.setIharm5Overtime((limitRate.getIharm5Overtime()>1)?1:0);
        limitTarget.setIharm6Overtime((limitRate.getIharm6Overtime()>1)?1:0);
        limitTarget.setIharm7Overtime((limitRate.getIharm7Overtime()>1)?1:0);
        limitTarget.setIharm8Overtime((limitRate.getIharm8Overtime()>1)?1:0);
        limitTarget.setIharm9Overtime((limitRate.getIharm9Overtime()>1)?1:0);
        limitTarget.setIharm10Overtime((limitRate.getIharm10Overtime()>1)?1:0);
        limitTarget.setIharm11Overtime((limitRate.getIharm11Overtime()>1)?1:0);
        limitTarget.setIharm12Overtime((limitRate.getIharm12Overtime()>1)?1:0);
        limitTarget.setIharm13Overtime((limitRate.getIharm13Overtime()>1)?1:0);
        limitTarget.setIharm14Overtime((limitRate.getIharm14Overtime()>1)?1:0);
        limitTarget.setIharm15Overtime((limitRate.getIharm15Overtime()>1)?1:0);
        limitTarget.setIharm16Overtime((limitRate.getIharm16Overtime()>1)?1:0);
        limitTarget.setIharm17Overtime((limitRate.getIharm17Overtime()>1)?1:0);
        limitTarget.setIharm18Overtime((limitRate.getIharm18Overtime()>1)?1:0);
        limitTarget.setIharm19Overtime((limitRate.getIharm19Overtime()>1)?1:0);
        limitTarget.setIharm20Overtime((limitRate.getIharm20Overtime()>1)?1:0);
        limitTarget.setIharm21Overtime((limitRate.getIharm21Overtime()>1)?1:0);
        limitTarget.setIharm22Overtime((limitRate.getIharm22Overtime()>1)?1:0);
        limitTarget.setIharm23Overtime((limitRate.getIharm23Overtime()>1)?1:0);
        limitTarget.setIharm24Overtime((limitRate.getIharm24Overtime()>1)?1:0);
        limitTarget.setIharm25Overtime((limitRate.getIharm25Overtime()>1)?1:0);

        limitTarget.setInuharm1Overtime((limitRate.getInuharm1Overtime()>1)?1:0);
        limitTarget.setInuharm2Overtime((limitRate.getInuharm2Overtime()>1)?1:0);
        limitTarget.setInuharm3Overtime((limitRate.getInuharm3Overtime()>1)?1:0);
        limitTarget.setInuharm4Overtime((limitRate.getInuharm4Overtime()>1)?1:0);
        limitTarget.setInuharm5Overtime((limitRate.getInuharm5Overtime()>1)?1:0);
        limitTarget.setInuharm6Overtime((limitRate.getInuharm6Overtime()>1)?1:0);
        limitTarget.setInuharm7Overtime((limitRate.getInuharm7Overtime()>1)?1:0);
        limitTarget.setInuharm8Overtime((limitRate.getInuharm8Overtime()>1)?1:0);
        limitTarget.setInuharm9Overtime((limitRate.getInuharm9Overtime()>1)?1:0);
        limitTarget.setInuharm10Overtime((limitRate.getInuharm10Overtime()>1)?1:0);
        limitTarget.setInuharm11Overtime((limitRate.getInuharm11Overtime()>1)?1:0);
        limitTarget.setInuharm12Overtime((limitRate.getInuharm12Overtime()>1)?1:0);
        limitTarget.setInuharm13Overtime((limitRate.getInuharm13Overtime()>1)?1:0);
        limitTarget.setInuharm14Overtime((limitRate.getInuharm14Overtime()>1)?1:0);
        limitTarget.setInuharm15Overtime((limitRate.getInuharm15Overtime()>1)?1:0);
        limitTarget.setInuharm16Overtime((limitRate.getInuharm16Overtime()>1)?1:0);
    }
}
