package com.njcn.influx.service.impl;

import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.api.CsLineFeignClient;
import com.njcn.csdevice.enums.AlgorithmResponseEnum;
import com.njcn.influx.imapper.CommonMapper;
import com.njcn.influx.pojo.constant.InfluxDBTableConstant;
import com.njcn.influx.pojo.dto.StatisticalDataDTO;
import com.njcn.influx.query.InfluxQueryWrapper;
import com.njcn.influx.service.CommonService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Description:
 * Date: 2023/6/2  16:04【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class CommonServiceImpl implements CommonService {

    private final CommonMapper commonMapper;

    private final DicDataFeignClient dicDataFeignClient;

    private final CsLineFeignClient csLineFeignClient;
    @Override
    public StatisticalDataDTO getLineRtData(String lineId, String tableName, String columnName, String phasic, String dataType, String clDid) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(getTableNameByClassId(tableName),StatisticalDataDTO.class);
        influxQueryWrapper.select(StatisticalDataDTO::getLineId)
                .select(StatisticalDataDTO::getPhaseType)
                .select(StatisticalDataDTO::getValueType)
                .last(columnName)
                .eq(InfluxDBTableConstant.LINE_ID,lineId)
                .eq(InfluxDBTableConstant.PHASIC_TYPE,phasic)
                .eq(InfluxDBTableConstant.VALUE_TYPE,dataType)
                .eq(InfluxDBTableConstant.CL_DID,clDid);
        return commonMapper.getLineRtData(influxQueryWrapper);
    }

    @Override
    public List<StatisticalDataDTO> getDeviceRtData(List<String> lineIds, String tableName, String columnName, String phasic, String dataType,String process) {
        List<StatisticalDataDTO> resultList = new ArrayList<>();
        for (String lineId: lineIds) {
            String clDidByLineId = getClDidByLineId(lineId);
            InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(getTableNameByClassId(tableName),StatisticalDataDTO.class);
            influxQueryWrapper.select(StatisticalDataDTO::getLineId)
                    .select(StatisticalDataDTO::getPhaseType)
                    .select(StatisticalDataDTO::getValueType)
                    .last(columnName,InfluxDBTableConstant.VALUE)
                    .eq(InfluxDBTableConstant.LINE_ID,lineId)
                    .eq(InfluxDBTableConstant.PROCESS,process)
                    .eq(InfluxDBTableConstant.PHASIC_TYPE,phasic)
                    .eq(InfluxDBTableConstant.VALUE_TYPE,dataType).eq(InfluxDBTableConstant.CL_DID,clDidByLineId);
            List<StatisticalDataDTO> deviceRtData = commonMapper.getDeviceRtData(influxQueryWrapper);
            resultList.addAll(deviceRtData);
        }

        return resultList;
    }

    @Override
    public List<StatisticalDataDTO> getDeviceRtDataByTime(List<String> lineIds, String tableName, String columnName, String phasic, String dataType, String startTime, String endTime,String process) {
        List<StatisticalDataDTO> resultList = new ArrayList<>();
        for (String lineId: lineIds) {
            String clDidByLineId = getClDidByLineId(lineId);
            InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(getTableNameByClassId(tableName),StatisticalDataDTO.class);
            influxQueryWrapper.select(StatisticalDataDTO::getLineId)
                    .select(StatisticalDataDTO::getPhaseType)
                    .select(StatisticalDataDTO::getValueType)
                    .select(columnName,InfluxDBTableConstant.VALUE)
                    .eq(InfluxDBTableConstant.LINE_ID,lineId)
                    .eq(InfluxDBTableConstant.PHASIC_TYPE,phasic)
                    .eq(InfluxDBTableConstant.PROCESS,process)
                    .between(InfluxDBTableConstant.TIME, startTime, endTime)
                    .eq(InfluxDBTableConstant.VALUE_TYPE,dataType).eq(InfluxDBTableConstant.CL_DID,clDidByLineId);
            List<StatisticalDataDTO> deviceRtData = commonMapper.getDeviceRtDataByTime(influxQueryWrapper);
            resultList.addAll(deviceRtData);
        }

        return resultList;
    }

    @Override
    public StatisticalDataDTO getLineHistoryData(String lineId, String tableName, String columnName, String startTime, String endTime, String clDid) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(getTableNameByClassId(tableName),StatisticalDataDTO.class);
        influxQueryWrapper.max(columnName,InfluxDBTableConstant.MAX_VALUE)
                .min(columnName,InfluxDBTableConstant.MIN_VALUE)
                .mean(columnName,InfluxDBTableConstant.AVG_VALUE)
                .eq(InfluxDBTableConstant.LINE_ID,lineId)
                .eq(InfluxDBTableConstant.CL_DID,clDid)
                .between(InfluxDBTableConstant.TIME, startTime, endTime);
        return commonMapper.getLineHistoryData(influxQueryWrapper);
    }

    @Override
    public StatisticalDataDTO selectBySql(StringBuilder sql) {
        return commonMapper.selectBySql(sql);
    }

    @Override
    public List<StatisticalDataDTO> getTopTemperature(String lineId, String tableName, String columnName,String process) {
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(tableName,StatisticalDataDTO.class);
        influxQueryWrapper.select(StatisticalDataDTO::getLineId)
                .select(StatisticalDataDTO::getClDid)
                .last(columnName,InfluxDBTableConstant.VALUE)
                .eq(InfluxDBTableConstant.LINE_ID,lineId)
                .eq(InfluxDBTableConstant.PROCESS,process)
                .groupBy(InfluxDBTableConstant.CL_DID);
        return commonMapper.getTopTemperature(influxQueryWrapper);
    }

    /*表名换成了id本方法做转换*/
    private String getTableNameByClassId(String classId){
        DictData data = dicDataFeignClient.getDicDataById(classId).getData();
        if(Objects.isNull(data)){
            throw new BusinessException("数据缺失");
        }
        return data.getCode();
    }
    private  String getClDidByLineId(String lineId){
        String position = csLineFeignClient.getPositionById(lineId).getData();
        if (Objects.isNull(position)){
            throw new BusinessException(AlgorithmResponseEnum.POSITION_ERROR);
        }
        String clDid = null;
        String areaCode =  dicDataFeignClient.getDicDataById(position).getData().getCode();
        if (Objects.equals(areaCode, DicDataEnum.OUTPUT_SIDE.getCode())){
            clDid = "0";
        } else if (Objects.equals(areaCode, DicDataEnum.GRID_SIDE.getCode())){
            clDid = "1";
        } else if (Objects.equals(areaCode, DicDataEnum.LOAD_SIDE.getCode())){
            clDid = "2";
        }
        return clDid;
    }
}
