package com.jiayue.ipp.idp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiayue.ipp.common.data.entity.WeatherStationStatusData;
import com.jiayue.ipp.idp.mapper.WeatherStationStatusDataMapper;
import com.jiayue.ipp.idp.service.WeatherStationStatusDataService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 气象站数据业务层实现类
 *
 * @author tl
 * @date 2022-05-11 18:07:03
 */
@Service
public class WeatherStationStatusDataServiceImpl extends ServiceImpl<WeatherStationStatusDataMapper, WeatherStationStatusData> implements WeatherStationStatusDataService {

    public QueryWrapper<WeatherStationStatusData> getPageByStationCodeAndeTimeBetweenAndEquipmentId(String stationCode, Date startTime, Date endTime, String equipmentId) {
        QueryWrapper<WeatherStationStatusData> wrapper = new QueryWrapper<>();

        if (stationCode != null && !stationCode.equals("")) {
            wrapper.eq("station_code", stationCode);
        }
        if (startTime != null && !startTime.equals("") && endTime != null && !endTime.equals("")) {
            wrapper.between("time", startTime, endTime);
        }
        if (equipmentId != null && !equipmentId.equals("")) {
            wrapper.eq("equipment_id", equipmentId);
        }
        return wrapper;
    }

    public List<WeatherStationStatusData> getByStationCodeAndTimeAndEndTimeAndEquipmentId(String stationCode, Date startTime, Date endTime, String equipmentId) {
        QueryWrapper<WeatherStationStatusData> wrapper = new QueryWrapper<>();
        if (stationCode != null && !stationCode.equals("")) {
            wrapper.eq("station_code", stationCode);
        }
        if (startTime != null && !startTime.equals("") && endTime != null && !endTime.equals("")) {
            wrapper.between("time", startTime, endTime);
        }
        if (equipmentId != null && !equipmentId.equals("")) {
            wrapper.eq("equipment_id", equipmentId);
        }
        return baseMapper.selectList(wrapper);
    }

    public Map<String, Object> findByStationCodeAndeTimeBetweenAndEquipmentId(String stationCode, Date startTime, Date endTime, String id) {
        Map<String, Object> map = new HashMap<>();
        List<WeatherStationStatusData> list = new ArrayList<>();
        List<WeatherStationStatusData> checkList = new ArrayList<>();
        list = getByStationCodeAndTimeAndEndTimeAndEquipmentId(stationCode, startTime, endTime, id);
        list.sort(Comparator.comparing(WeatherStationStatusData::getTime));
        long startTimeLong = startTime.getTime();
        long endTimeLong = endTime.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> times = new ArrayList<>();
        long timeStep = 300000L;
        if (startTimeLong % timeStep != 0) {
            startTimeLong = startTimeLong - (startTimeLong % timeStep) + timeStep;
        }

        for (long i = startTimeLong; i < endTimeLong; i = i + 300000L) {
            long finalI = i;
            List<WeatherStationStatusData> w = list.stream().filter(t -> t.getTime().getTime() == finalI).collect(Collectors.toList());
            if (w != null && w.size() > 0) {
                checkList.add(w.get(0));
            } else {
                //数据没有默认值 会空指针
                checkList.add(new WeatherStationStatusData());
            }
            String timeFormat = sdf.format(new Date(i));
            times.add(timeFormat);
        }

        List<Float> globalRDatas = new ArrayList<>();
        List<Float> directRDatas = new ArrayList<>();
        List<Float> diffuseRDatas = new ArrayList<>();
        List<Float> obliqueRDatas = new ArrayList<>();
        Map<String, Object> radiationMap = new HashMap<>();


        List<Float> wsDatas = new ArrayList<>();
        List<Float> wdDatas = new ArrayList<>();
        Map<String, Object> otherMap = new HashMap<>();

        BigDecimal nullValue = new BigDecimal(-99);
        //总辐射
        List<BigDecimal> globalRs = checkList.stream().map(WeatherStationStatusData::getGlobalR).collect(Collectors.toList());
        for (BigDecimal b : globalRs) {
            if (b.compareTo(nullValue) == 0) {
                globalRDatas.add(null);
            } else {
                globalRDatas.add(b.floatValue());
            }
        }
        //直辐射
        List<BigDecimal> directRs = checkList.stream().map(WeatherStationStatusData::getDirectR).collect(Collectors.toList());
        for (BigDecimal b : directRs) {
            if (b.compareTo(nullValue) == 0) {
                directRDatas.add(null);
            } else {
                directRDatas.add(b.floatValue());
            }
        }
        //散辐射
        List<BigDecimal> diffuseRs = checkList.stream().map(WeatherStationStatusData::getDiffuseR).collect(Collectors.toList());
        for (BigDecimal b : diffuseRs) {
            if (b.compareTo(nullValue) == 0) {
                diffuseRDatas.add(null);
            } else {
                diffuseRDatas.add(b.floatValue());
            }
        }
        //斜面辐射
        List<BigDecimal> obliqueRs = checkList.stream().map(WeatherStationStatusData::getObliqueR).collect(Collectors.toList());
        for (BigDecimal b : obliqueRs) {
            if (b.compareTo(nullValue) == 0) {
                obliqueRDatas.add(null);
            } else {
                obliqueRDatas.add(b.floatValue());
            }
        }


        List<BigDecimal> wss = checkList.stream().map(WeatherStationStatusData::getWs).collect(Collectors.toList());
        for (BigDecimal b : wss) {
            if (b.compareTo(nullValue) == 0) {
                wsDatas.add(null);
            } else {
                wsDatas.add(b.floatValue());
            }
        }

        List<BigDecimal> wds = checkList.stream().map(WeatherStationStatusData::getWd).collect(Collectors.toList());
        for (BigDecimal b : wds) {
            if (b.compareTo(nullValue) == 0) {
                wdDatas.add(null);
            } else {
                wdDatas.add(b.floatValue());
            }
        }

        radiationMap.put("globalRs", globalRDatas);
        radiationMap.put("directRs", directRDatas);
        radiationMap.put("diffuseRs", diffuseRDatas);
        radiationMap.put("obliqueRs", obliqueRDatas);

        otherMap.put("wss", wsDatas);
        otherMap.put("wds", wdDatas);

        map.put("times", times);
        map.put("radiationMap", radiationMap);
        map.put("otherMap", otherMap);
        return map;
    }
}
