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.entity.Device;
import com.ho.business.entity.ModelDeviceColComp;
import com.ho.business.entity.Station;
import com.ho.business.entity.VirtualDeviceCol;
import com.ho.business.feignclient.TdFeignClient;
import com.ho.business.service.*;
import com.ho.business.vo.req.MonitorQuery;
import com.ho.business.vo.req.batteryStack.CurveReqVo;
import com.ho.business.vo.req.point.PointCurveReq;
import com.ho.business.vo.resp.DeviceColData;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.VirtualDeviceColResp;
import com.ho.business.vo.resp.batteryStack.CurveRespVo;
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.vo.req.PointData;
import com.ho.common.tools.vo.req.StationHomeRespVo;
import com.ho.common.tools.vo.req.StatisticsCurve;
import com.ho.td.api.entity.query.TdBaseTimeQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gyan
 * @desc: 电池堆业务层
 * @DateTime: 2023/5/8 11:11
 */
@Service
@Slf4j
public class BatteryStackServiceImpl implements BatteryStackService {
    @Autowired
    StationService stationService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    StationHomeService stationHomeService;

    @Autowired
    ModelDeviceService modelDeviceService;

    @Autowired
    PointDemoService pointDemoService;

    @Autowired
    VirtualDeviceColService virtualDeviceColService;

    @Autowired
    TdFeignClient tdFeignClient;


    @Override
    public List<CurveRespVo> getUniversalCurve(CurveReqVo vo) {
        //创建返回值
        List<CurveRespVo> curveList = new ArrayList<>();
        //查询电站
        //根据电站id查询电站信息
        Station station = stationService.selectById(vo.getStationId());
        if (station == null) {
            throw new BusinessException(BaseResponseCode.STATION_YC_NOT_EXISTS);
        }
        //根据电站和设备Id 确定一个设备
        //根据电站id和srcId查询 拿到col的部分数据
        Device device = deviceService.selectByStationIdAndSrcId(vo.getStationId(), vo.getSrcId());
        List<DeviceRespVO> list = new ArrayList<>();
        //1代表虚拟设备
        if (CommonConstant.ONE.equals(device.getVirtual())) {
            if (device != null) {
                DeviceRespVO deviceRespVO = new DeviceRespVO();
                deviceRespVO.setSrcId(device.getSrcId());
                deviceRespVO.setPid(device.getPid());
                deviceRespVO.setVirtual(device.getVirtual());
                deviceRespVO.setDeviceType(device.getDeviceType());
                deviceRespVO.setStationId(device.getStationId());
                list.add(deviceRespVO);
            }
        } else {
            if (device != null) {
                DeviceRespVO deviceRespVO = new DeviceRespVO();
                deviceRespVO.setSrcId(device.getSrcId());
                deviceRespVO.setDeviceType(device.getDeviceType());
                deviceRespVO.setStationId(device.getStationId());
                list.add(deviceRespVO);
            }
        }

        //根据传入的模型字段查询字段相关信息
        if (!vo.getColName().isEmpty()) {
            DataResult<List<PointData>> colData = new DataResult<>();
            for (String colName : vo.getColName()) {
                List<StationHomeRespVo> staticCurveList = new ArrayList<>();
                DeviceColData colNameData = stationHomeService.getDeviceColData(list, colName);
                //确定时间/是否有抽样频率传入
                MonitorQuery queryTime = new MonitorQuery();
                if (vo.getSampleTime() != null) {
                    //查询开始时间结束时间
                    queryTime = stationHomeService.getStartEndTime(vo.getSampleTime());
                }
                if (vo.getType() != null) {
                    queryTime.setBeginTime(vo.getBeginTime());
                    queryTime.setEndTime(vo.getEndTime());
                    if (vo.getSampleTime() == null) {
                        vo.setSampleTime(1);
                    }
                }
                //获取返回时间
                //通过size拿到循环的个数
                List<DateTime> dateTimes = DateUtil.rangeToList(DateUtil.parse(queryTime.getBeginTime(), CommonConstant.DATE), DateUtil.parse(queryTime.getEndTime(), CommonConstant.DATE), DateField.MINUTE, vo.getSampleTime());

                //查询时间
                List<String> hourList = dateTimes.stream().map(s -> {
                    return DateUtil.format(s, CommonConstant.DATE);
                }).collect(Collectors.toList());

                for (int i = 0; i < hourList.size(); i++) {
                    StationHomeRespVo stationHomeRespVo = new StationHomeRespVo();
                    stationHomeRespVo.setDate(hourList.get(i));
                    staticCurveList.add(stationHomeRespVo);
                }
                //抽样率拼接
                String samlRate = vo.getSampleTime() + "m";
                //直接组查询超级表的入参(组织td查询入参)
                TdBaseTimeQuery tdBaseQuery = new TdBaseTimeQuery();
                tdBaseQuery.setBeginTime(queryTime.getBeginTime());
                tdBaseQuery.setEndTime(queryTime.getEndTime());
                tdBaseQuery.setMap(colNameData.getMap());
                tdBaseQuery.setTime(samlRate);
                if (colNameData != null || !colNameData.getDeviceIdList().isEmpty()) {
                    List<PointCurveSrcCol> deviceIdList = colNameData.getDeviceIdList();
                    if (!deviceIdList.isEmpty()) {
                        tdBaseQuery.setSrcId(deviceIdList.get(0).getSrcId());
                        if (deviceIdList != null || !deviceIdList.isEmpty()) {
                            List<String> cols = deviceIdList.get(0).getCols();
                            if (!cols.isEmpty()) {
                                tdBaseQuery.setCol(cols.get(0));
                            }
                        }
                    }
                }
                tdBaseQuery.setStationId(vo.getStationId());
                tdBaseQuery.setGroupId(station.getGroupId());
                //数据查询
                //1遥信值 sensType 等于1 时不能使用 avg max min 进行查询
                if (!CommonConstant.ONE.equals(colNameData.getSensType()) || colNameData.getSensType() == null) {
                    colData = tdFeignClient.getPointData(tdBaseQuery);
                } else {
                    DataResult<List<PointCurveResp>> result = tdFeignClient.querySignalValue(tdBaseQuery);
                    List<PointData> pointData = new ArrayList<>();
                    if (result.isSuccess() || result.getData() != null) {
                        List<PointCurveResp> data = result.getData();
                        if (!data.isEmpty()) {
                            for (int i = 0; i < data.size(); i++) {
                                PointCurveResp pointCurveResp = data.get(i);
                                for (int j = 0; j < pointCurveResp.getStaticCurveList().size(); j++) {
                                    StatisticsCurve statisticsRespVO = pointCurveResp.getStaticCurveList().get(j);
                                    PointData pointValue = new PointData();
                                    pointValue.setDate(statisticsRespVO.getDate());
                                    pointValue.setDigital(statisticsRespVO.getDigital());
                                    pointData.add(pointValue);
                                }
                            }
                            colData.setData(pointData);
                        }
                    }
                }

                //进行数据组装返回
                if (colData.isSuccess() || colData.getData() != null) {
                    for (int i = 0; i < staticCurveList.size(); i++) {
                        Double digital = new Double("0");
                        if (!colData.getData().isEmpty()) {
                            digital = colData.getData().get(i).getDigital();
                        }
                        if(digital==null){
                            staticCurveList.get(i).setDigital(null);
                        }else{
                            staticCurveList.get(i).setDigital(new BigDecimal(digital));
                        }
                    }
                    CurveRespVo curveRespVo = new CurveRespVo();
                    curveRespVo.setStaticCurveList(staticCurveList);
                    curveList.add(curveRespVo);
                }
            }
        }
        return curveList;
    }

    @Override
    public List<CurveRespVo> getSocCurve(CurveReqVo vo) {
        //创建返回值
        List<CurveRespVo> universalCurve = new ArrayList<>();
        if (vo.getType() != null) {
            //取当前时间
            Date now = new Date();
            Date endDate = null;
            if (CommonConstant.TimeType.HOUR.equals(vo.getType())) {
                //最近一小时
                endDate = DateUtils.addHours(now, -1);
            } else if (CommonConstant.TimeType.DAY.equals(vo.getType())) {
                //最近一天
                endDate = DateUtils.addDays(now, -1);
            } else if (CommonConstant.TimeType.MONTH.equals(vo.getType())) {
                //最近一月
                endDate = DateUtils.addMonths(now, -1);
            } else if (CommonConstant.TimeType.YEAR.equals(vo.getType())) {
                //最近一年
                endDate = DateUtils.addYears(now, -1);
            }
            String endTime = DateUtil.formatDateTime(now);
            String beginTime = DateUtil.formatDateTime(endDate);
            vo.setBeginTime(beginTime);
            vo.setEndTime(endTime);
            universalCurve = getUniversalCurve(vo);
        } else if (vo.getBeginTime() != null && vo.getEndTime() != null) {
            universalCurve = getUniversalCurve(vo);
        }
        return universalCurve;
    }

    @Override
    public List<PointCurveResp> getStackHisData(CurveReqVo vo) {
        //组装历史数据入参
        PointCurveReq pointCurveReq = new PointCurveReq();
        //开始时间
        pointCurveReq.setBeginTime(vo.getBeginTime());
        //结束时间
        pointCurveReq.setEndTime(vo.getEndTime());
        //电站Id
        pointCurveReq.setStationId(vo.getStationId());
        //创建设备和点表字段的集合
        List<PointCurveSrcCol> deviceIdList = new ArrayList<>();
        //把规定的key转换为设备col
        //根据电站和设备Id 确定一个设备
        //根据电站id和srcId查询 拿到col的部分数据
        Device device = deviceService.selectByStationIdAndSrcId(vo.getStationId(), vo.getSrcId());
        String deviceType = device.getDeviceType();
        Map<String,BigDecimal> map = new HashMap<>();
        if (!vo.getColName().isEmpty()) {
            List<String> cols = new ArrayList<>();
            PointCurveSrcCol pointCurveSrcCol = new PointCurveSrcCol();
            for (String col : vo.getColName()) {
                List<VirtualDeviceColResp> virList = new ArrayList<>();
                List<ModelDeviceColComp> colCompList = new ArrayList<>();
                if (CommonConstant.ONE.equals(device.getVirtual())) {
                    VirtualDeviceCol virtualDeviceCol = new VirtualDeviceCol();
                    virtualDeviceCol.setSrcId(device.getSrcId());
                    virtualDeviceCol.setStationId(device.getStationId());
                    virtualDeviceCol.setType(col);
                    pointCurveSrcCol.setSrcId(device.getPid());
                    virList = virtualDeviceColService.getList(virtualDeviceCol);
                } else {
                    colCompList = modelDeviceService.getCompListByType("device", deviceType, col);
                }
                if (!colCompList.isEmpty()) {
                    ModelDeviceColComp colModelDeviceCol = colCompList.get(0);
                    String deviceCol = colModelDeviceCol.getDeviceCol();
                    cols.add(deviceCol);
                }
                if (!virList.isEmpty()) {
                    VirtualDeviceColResp virtualDeviceColResp = virList.get(0);
                    String deviceCol = virtualDeviceColResp.getCol();
                    if(null != virtualDeviceColResp.getFactor()){
                        map.put(deviceCol,virtualDeviceColResp.getFactor());
                    }
                    cols.add(deviceCol);
                }
            }
            pointCurveSrcCol.setMap(map);
            pointCurveSrcCol.setCols(cols);
            if (pointCurveSrcCol.getSrcId() == null) {
                pointCurveSrcCol.setSrcId(vo.getSrcId());
            }
            deviceIdList.add(pointCurveSrcCol);
        }
        //set设备和点表字段的集合
        pointCurveReq.setDeviceIdList(deviceIdList);
        //调用查询历史数据的接口 http://192.168.1.183:8000/api/business/point/pointCurve （拼接入参PointCurveReq pointCurveReq）
        List<PointCurveResp> pointCurveRespList = pointDemoService.pointCurve(pointCurveReq);
        BigDecimal factor;
        for (PointCurveResp p:pointCurveRespList) {
            factor = map.get(p.getCol());
            if(null != factor){
                List<StatisticsCurve> staticCurveList = p.getStaticCurveList();
                for (StatisticsCurve curve:staticCurveList) {
                    log.info("曲线值：{},{}",curve.getDigital(),curve.getDigital()==null);
                    if(curve.getDigital()!=null){
                        curve.setDigital(new BigDecimal(curve.getDigital()).multiply(factor).doubleValue());
                    }
                }
            }
        }
        return pointCurveRespList;
    }
}
