package com.njcn.prepare.harmonic.service.influxdb.impl;

import cn.hutool.core.date.DateTime;
import com.njcn.device.pq.pojo.po.DataV;
import com.njcn.influx.deprecated.InfluxDBPublicParam;
import com.njcn.influx.deprecated.InfluxDBSqlConstant;
import com.njcn.influx.pojo.constant.InfluxDBTableConstant;
import com.njcn.influx.utils.InfluxDbUtils;
import com.njcn.prepare.harmonic.service.influxdb.DataExceptionInfluxService;
import com.njcn.prepare.harmonic.utils.PublicUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 数据是否异常 influxDB业务
 *
 * @author qijian
 * @version 1.0.0
 * @createTime 2022/11/28 - 10:09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DataExceptionInfluxServiceImpl implements DataExceptionInfluxService {

    private final InfluxDbUtils influxDbUtils;

    /**
     * 取前四项指标（相别为A）
     * @author qijian
     * @date 2022/11/28
     */
    @Override
    public DataV getFirstFourItems(String lineId, Date date, Integer type) {
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        String searchSql = "MAX(freq) as freq_max,MIN(freq) as freq_min,MAX(rms) as rms_max,MIN(rms) as rms_min,MAX(rms_lvr) as rms_lvr_max,MIN(rms_lvr) as rms_lvr_min,MAX(v_thd) as v_thd_max,MIN(v_thd) as v_thd_min ";
        String sql = getAppend(lineId, date, type, searchSql, "A");
        QueryResult query = influxDbUtils.query(sql);
        List<DataV> dataVS = resultMapper.toPOJO(query, DataV.class);
        if (dataVS.size() > 0){
            DataV dataV = dataVS.get(0);
            return dataV;
        }
        return null;
    }

    /**
     * 取三相不平衡度（相别为T）
     * @author qijian
     * @date 2022/11/28
     */
    @Override
    public DataV getUnbalance(String lineId, Date date, Integer type) {
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        String searchSql = "MAX(v_unbalance) as v_unbalance_max,MIN(v_unbalance) as v_unbalance_min ";
        String sql = getAppend(lineId, date,type, searchSql, "T");
        QueryResult query = influxDbUtils.query(sql);
        List<DataV> dataVS = resultMapper.toPOJO(query, DataV.class);
        if (dataVS.size() > 0){
            DataV dataV = dataVS.get(0);
            return dataV;
        }
        return null;
    }

    /**
     * 拼装sql
     * @param id,date,searchSql,tableName 参数
     * @return 结果
     */
    private String getAppend(String id, Date date, Integer type, String searchSql, String phase) {
        StringBuilder stringBuilder = new StringBuilder();
        //根据类型获取日期的开始和结束
        Map<String, DateTime> beginAndEndByDate = PublicUtil.getBeginAndEndByDate(type, date);
        //拼接
        stringBuilder.append(InfluxDBSqlConstant.SELECT).append(searchSql)
                .append(InfluxDBSqlConstant.FROM).append(InfluxDBPublicParam.DATA_V)
                .append(InfluxDBSqlConstant.WHERE).append(InfluxDBPublicParam.TIME).append(InfluxDBSqlConstant.GE).append(InfluxDBSqlConstant.QM).append(beginAndEndByDate.get("startTime")).append(InfluxDBSqlConstant.QM)
                .append(InfluxDBSqlConstant.AND).append(InfluxDBPublicParam.TIME).append(InfluxDBSqlConstant.LE).append(InfluxDBSqlConstant.QM).append(beginAndEndByDate.get("endTime")).append(InfluxDBSqlConstant.QM)
                .append(InfluxDBSqlConstant.AND).append(InfluxDBPublicParam.LINE_ID).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(id).append(InfluxDBSqlConstant.QM)
                .append(InfluxDBSqlConstant.AND).append(InfluxDBPublicParam.VALUE_TYPE).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(InfluxDBTableConstant.AVG).append(InfluxDBSqlConstant.QM);
        if (InfluxDBTableConstant.PHASE_TYPE_T.equals(phase)){
            stringBuilder.append(InfluxDBSqlConstant.AND).append(InfluxDBPublicParam.PHASIC_TYPE).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(InfluxDBTableConstant.PHASE_TYPE_T).append(InfluxDBSqlConstant.QM);
        }else{
            stringBuilder.append(InfluxDBSqlConstant.AND).append(InfluxDBPublicParam.PHASIC_TYPE).append(InfluxDBSqlConstant.EQ).append(InfluxDBSqlConstant.QM).append(InfluxDBTableConstant.PHASE_TYPE_A).append(InfluxDBSqlConstant.QM);
        }
        return stringBuilder.toString();
    }
}
