package com.ho.business.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.Device;
import com.ho.business.entity.DeviceTypeConfig;
import com.ho.business.entity.ModelDeviceColComp;
import com.ho.business.entity.Station;
import com.ho.business.feignclient.TdFeignClient;
import com.ho.business.service.*;
import com.ho.business.vo.req.ColDetailsReqVo;
import com.ho.business.vo.resp.InverterResp.InverterCurveRespVo;
import com.ho.business.vo.resp.InverterResp.InverterPvValueRespVO;
import com.ho.business.vo.resp.point.PointCurveResp;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.entity.PointCurveSrcCol;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.PageResult;
import com.ho.common.tools.vo.req.PointData;
import com.ho.common.tools.vo.req.StationHomeRespVo;
import com.ho.datacollect.api.vo.req.StatisticsRespVO;
import com.ho.datacollect.api.vo.req.add.TdBase;
import com.ho.datacollect.api.vo.req.inverter.InverterCurveListVo;
import com.ho.td.api.entity.query.TdBaseTimeQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author gyan
 * @desc: col字段查询详情
 * @DateTime: 2023/4/20 17:09
 */
@Service
@Slf4j
public class ColDetailsServiceImpl implements ColDetailsService {

    @Autowired
    StationService stationService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    DeviceTypeConfigService deviceTypeConfigService;

    @Autowired
    ModelDeviceService modelDeviceService;

    @Autowired
    DeviceTypeColService deviceTypeColService;

    @Autowired
    PointDemoService pointDemoService;

    @Autowired
    JoinTbSuffixService joinTbSuffixService;

    @Autowired
    RedisService redisService;

    @Autowired
    TdFeignClient feignClient;


    public DataResult<InverterCurveListVo> getColDetails(Integer samlRate, ColDetailsReqVo colDetailsReqVo) {
        //根据电站id查询电站信息
        Station station = stationService.selectById(colDetailsReqVo.getStationId());
        if (station == null) {
            throw new BusinessException(BaseResponseCode.STATION_YC_NOT_EXISTS);
        }

        //查询所要的时序数据的表名
        Map<Integer, String> map = new HashMap<>();
        //返回值
        DataResult<InverterCurveListVo> inverterCurveDataResult = new DataResult<>();

        Device device = deviceService.selectByStationIdAndSrcId(colDetailsReqVo.getStationId(), colDetailsReqVo.getSrcId());
        if(device == null){
            return inverterCurveDataResult;
        }
        String deviceType = device.getDeviceType();
        List<DeviceTypeConfig> deviceTypeConfigs = new ArrayList<>();
        if (device != null && device.getDeviceType() != null) {
            deviceTypeConfigs = deviceTypeConfigService.selectByType(device.getDeviceType(), null);
        }
        if (!deviceTypeConfigs.isEmpty()) {
            for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
                if (deviceTypeConfig.getStationId() == null) {
                    if (deviceTypeConfig.getGroupId().equals(station.getGroupId())) {
                        map.put(colDetailsReqVo.getSrcId(), deviceTypeConfig.getModelName());
                    }
                } else {
                    if (deviceTypeConfig.getStationId().equals(colDetailsReqVo.getStationId())) {
                        map.put(colDetailsReqVo.getSrcId(), deviceTypeConfig.getModelName());
                    }
                }
            }
        }
        //组表名
        TdBase tdAddBase = TdBase.builder()
                .groupId(station.getGroupId())
                .stationId(station.getId())
                .srcId(colDetailsReqVo.getSrcId())
                .build();
        //拼接表名后缀
        String tdStackSuffix = joinTbSuffixService.getTdInverterSuffix(tdAddBase);
        tdAddBase.setTableName(tdStackSuffix);
        tdAddBase.setEndTime(colDetailsReqVo.getEndTime());
        tdAddBase.setBeginTime(colDetailsReqVo.getBeginTime());
        tdAddBase.setBeginNum(colDetailsReqVo.getPageNum());
        tdAddBase.setPageSize(colDetailsReqVo.getPageSize());

        if (samlRate != null) {
            tdAddBase.setTime(samlRate + "m");
        }
        tdAddBase.setDeviceType(deviceType);
        boolean pv = colDetailsReqVo.getCol().contains("pv");
        if (pv) {
            if (DeviceTypeConstant.INVERTER_HW.equals(deviceType)) {
                //禾望
                inverterCurveDataResult = getInverterHWPV(deviceType, map, colDetailsReqVo, tdAddBase);
            } else if (DeviceTypeConstant.INVERTER_YG.equals(deviceType)) {
                //阳光
                inverterCurveDataResult = getInverterYGPV(deviceType, map, colDetailsReqVo, tdAddBase);
            } else if (DeviceTypeConstant.INVERTER_HUAWEI.equals(deviceType)) {
                //华为
                inverterCurveDataResult = getInverterHuaWeiPV(deviceType, map, colDetailsReqVo, tdAddBase);
            } else if (DeviceTypeConstant.INVERTER_GDW.equals(deviceType)) {
                //固德威
                inverterCurveDataResult = getInverterGdwPV(deviceType, map, colDetailsReqVo, tdAddBase);
            }
        } else {
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colDetailsReqVo.getCol());
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }

            }
        }

        return inverterCurveDataResult;
    }

    @Override
    public List<PointData> getColCurve(ColDetailsReqVo colDetailsReqVo) {
        List<PointData> list = new ArrayList<>();
        //字段历史数据曲线
        //计算(采样率)出开始时间与结束时间的差 （大于1440 采样率是 时间/60）
        Integer samlRate = null;
        int timeDifference = pointDemoService.getTimeDifference(colDetailsReqVo.getBeginTime(), colDetailsReqVo.getEndTime());
        if (timeDifference <= 1440) {
            samlRate = 1;
        } else {
            double divisor = 1440;
            double flag = Math.ceil(timeDifference / divisor);        //向上取整计算
            samlRate = (int) flag;
        }
        //开始时间
        Date BeginDate = DateUtil.parse(colDetailsReqVo.getBeginTime(), CommonConstant.DATE);
        //结束时间
        Date EndDate = DateUtil.parse(colDetailsReqVo.getEndTime(), CommonConstant.DATE);
        //通过size拿到循环的个数
        List<DateTime> dateTimes = DateUtil.rangeToList(BeginDate, EndDate, DateField.MINUTE, samlRate);
        int endHours = dateTimes.size();
        DataResult<InverterCurveListVo> inverterCurveDataResult = getColDetails(samlRate, colDetailsReqVo);
        InverterCurveListVo data = inverterCurveDataResult.getData();
        if (!inverterCurveDataResult.isSuccess() || data == null || data.getStatistics() == null) {
            for (int i = 0; i < endHours; i++) {
                PointData pointData = new PointData();
                String dateString = dateTimes.get(i).toString(CommonConstant.DATE) + "";
                String sub = dateString.substring(0, 16);
                pointData.setDate(sub);
                pointData.setDigital(new Double("0"));
                list.add(pointData);
            }
        } else if (data.getStatistics().size() == CommonConstant.ONE) {
            List<StatisticsRespVO> statistics = data.getStatistics();
            //时间在第一条数据之前的全部为0
            if (data.getFirstTime() != null) {
                //创建返回list
                List<PointData> newLastList = new ArrayList<>();
                for (int i = 0; i < endHours; i++) {
                    PointData pointData = new PointData();
                    if (statistics.get(0).getDigital() != null) {
                        pointData.setDigital(statistics.get(0).getDigital().doubleValue());
                    } else {
                        pointData.setDigital(new Double("0"));
                    }
                    pointData.setDate(dateTimes.get(i).toString());
                    newLastList.add(pointData);
                }
                for (PointData pointData : newLastList) {
                    String time = pointData.getDate().substring(0, 16);
                    pointData.setDate(time);
                }
                list = newLastList;
            } else {
                for (int i = 0; i < endHours; i++) {
                    PointData pointData = new PointData();
                    String dateString = dateTimes.get(i).toString(CommonConstant.DATE) + "";
                    String string = dateString.substring(0, 16);
                    pointData.setDate(string);
                    pointData.setDigital(new Double("0"));
                    list.add(pointData);
                }
            }
        } else {
            //有多条数据
            //时间在第一条数据之前的全部为0
            //之后的依次填充
            if (data.getFirstTime() != null) {
                Date firstTime = data.getFirstTime();
                for (int i = 0; i < endHours; i++) {
                    String dateString = dateTimes.get(i).toString(CommonConstant.DATE) + "";
                    PointData pointData = new PointData();
                    //如果时间小于第一条时序记录的时间, 并且不在第一条数据的时间段（小时） 这个值就塞0
                    DateTime theTime = DateUtil.parse(dateString, CommonConstant.DATE);
                    String date = dateString.substring(0, 16);
                    String sub = dateString.substring(11, 13);
                    pointData.setDate(date);
                    String tdSubstring = DateUtil.format(firstTime, CommonConstant.DATE).substring(11, 13);
                    if (DateUtil.compare(theTime, firstTime) < 0) {
                        pointData.setDigital(new Double("0"));
                    } else {
                        if(data.getStatistics().get(i).getDigital() != null){
                            pointData.setDigital(data.getStatistics().get(i).getDigital().doubleValue());
                        }
                    }
                    list.add(pointData);
                }
            } else {
                for (int i = 0; i < endHours; i++) {
                    PointData pointData = new PointData();
                    String dateString = dateTimes.get(i).toString(CommonConstant.DATE) + "";
                    String spitTime = dateString.substring(0, 16);
                    pointData.setDate(spitTime);
                    pointData.setDigital(new Double("0"));
                    list.add(pointData);
                }
            }
        }
        return list;
    }

    @Override
    public PageResult<StationHomeRespVo> getColList(ColDetailsReqVo colDetailsReqVo) {
        Integer samlRate = null;
        PageResult<StationHomeRespVo> list = new PageResult<>();
        DataResult<InverterCurveListVo> inverterCurveDataResult = getColDetails(samlRate, colDetailsReqVo);
        if (inverterCurveDataResult.getData() == null || inverterCurveDataResult.getData().getList() == null) {
            return list;
        }
        return inverterCurveDataResult.getData().getList();
    }

    private DataResult<InverterCurveListVo> getInverterHWPV(String deviceType, Map<Integer, String> map, ColDetailsReqVo colDetailsReqVo, TdBase tdAddBase) {
        DataResult<InverterCurveListVo> inverterCurveListVoDataResult = new DataResult<>();
        if (CommonConstant.ONE.equals(colDetailsReqVo.getMark())) {
            //电压
            if (colDetailsReqVo.getCol() != null) {
                if (colDetailsReqVo.getCol().length() >= 3) {
                    String substring = colDetailsReqVo.getCol().substring(2, colDetailsReqVo.getCol().length());
                    Integer integer = Integer.valueOf(substring);
                    double divisor = 5;
                    double flag = Math.ceil(integer / divisor);        //向上取整计算
                    int samlRate = (int) flag;
                    //对col字段进行拼接后进行查询
                    String colNew = colDetailsReqVo.getCol().substring(0, 2) + samlRate + "U";
                    List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
                    if (!cIaCompList.isEmpty()) {
                        for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                            if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                                tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                                break;
                            }
                        }
                        if (tdAddBase.getTime() == null) {
                            inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                        } else {
                            inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                        }

                    }
                }
            }
        } else if (CommonConstant.TWO.equals(colDetailsReqVo.getMark())) {
            //电流2
            //对col字段进行拼接后进行查询
            String colNew = colDetailsReqVo.getCol() + "I";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        }
        return inverterCurveListVoDataResult;
    }

    private DataResult<InverterCurveListVo> getInverterYGPV(String deviceType, Map<Integer, String> map, ColDetailsReqVo colDetailsReqVo, TdBase tdAddBase) {
        DataResult<InverterCurveListVo> inverterCurveListVoDataResult = new DataResult<>();
        if (CommonConstant.ONE.equals(colDetailsReqVo.getMark())) {
            //电压
            String colNew = colDetailsReqVo.getCol() + "U";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        } else if (CommonConstant.TWO.equals(colDetailsReqVo.getMark())) {
            //电流
            String colNew = colDetailsReqVo.getCol() + "I";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        }
        return inverterCurveListVoDataResult;
    }

    private DataResult<InverterCurveListVo> getInverterGdwPV(String deviceType, Map<Integer, String> map, ColDetailsReqVo colDetailsReqVo, TdBase tdAddBase) {
        DataResult<InverterCurveListVo> inverterCurveListVoDataResult = new DataResult<>();
        if (CommonConstant.ONE.equals(colDetailsReqVo.getMark())) {
            //电压
            String colNew = colDetailsReqVo.getCol() + "U";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        } else if (CommonConstant.TWO.equals(colDetailsReqVo.getMark())) {
            //电流
            String colNew = colDetailsReqVo.getCol() + "I";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        }
        return inverterCurveListVoDataResult;
    }

    private DataResult<InverterCurveListVo> getInverterHuaWeiPV(String deviceType, Map<Integer, String> map, ColDetailsReqVo colDetailsReqVo, TdBase tdAddBase) {
        DataResult<InverterCurveListVo> inverterCurveListVoDataResult = new DataResult<>();
        if (CommonConstant.ONE.equals(colDetailsReqVo.getMark())) {
            //电压
            String colNew = colDetailsReqVo.getCol() + "U";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        } else if (CommonConstant.TWO.equals(colDetailsReqVo.getMark())) {
            //电流
            String colNew = colDetailsReqVo.getCol() + "I";
            List<ModelDeviceColComp> cIaCompList = modelDeviceService.getCompListByType("model", map.get(colDetailsReqVo.getSrcId()), colNew);
            if (!cIaCompList.isEmpty()) {
                for (ModelDeviceColComp modelDeviceColComp : cIaCompList) {
                    if (deviceType.equals(modelDeviceColComp.getDeviceType())) {
                        tdAddBase.setColName(modelDeviceColComp.getDeviceCol());
                        break;
                    }
                }
                if (tdAddBase.getTime() == null) {
                    inverterCurveListVoDataResult = feignClient.queryColList(tdAddBase);
                } else {
                    inverterCurveListVoDataResult = feignClient.queryHistoryInterval(tdAddBase);
                }
            }
        }
        return inverterCurveListVoDataResult;
    }


}