package cn.cecep.talroad.util.effective;

import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.domain.effective.SEnvgasAqilevel;
import cn.cecep.talroad.domain.effective.SEnvgasPollutant;
import cn.cecep.talroad.mapper.effective.SEnvgasAqilevelMapper;
import cn.cecep.talroad.mapper.effective.SEnvgasPollutantMapper;
import cn.cecep.talroad.vo.effective.AirQualityConverter;
import cn.cecep.talroad.vo.effective.AirQualityData;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangshiji
 * @date 2022/7/15
 */
@Component
public class AirDataConverseUtil {


    public static AirDataConverseUtil airDataConverseUtil;
    @Autowired
    private SEnvgasPollutantMapper sEnvgasPollutantMapper;
    @Autowired
    private SEnvgasAqilevelMapper sEnvgasAqilevelMapper;

    /**
     * ES 区域小时数据 转公共VO 并附带区域信息
     * 不补全区域和站点信息
     * @param esAreaHour     区域小时数据
     * @param regionInfoList 区域信息集合
     * @return
     */
   /* public static List<AirQualityData> converSupplementData(List<QEnvgasAreaHour> esAreaHour, List<PCodeRegion> regionInfoList, AirParmaVo airParmaVo) {
        HashMap<Integer, String> aqiLevelMap = buildAqiLevelMap();
        //数据类型转换
        List<AirQualityData> airQualityData = new ArrayList<>();
        //if (CollectionUtils.isNotEmpty(esAreaHour)) {
        esAreaHour.forEach(esData -> {
            AirQualityData airData = new AirQualityData();
            //空气质量
            airData.setAqi(esData.getAqi());
            airData.setPmi(esData.getPmi() == null ? null : esData.getPmi().setScale(2, RoundingMode.UP));
            airData.setPm25(esData.getPm25() == null ? null : esData.getPm25().setScale(0,RoundingMode.UP));
            airData.setPm10(esData.getPm10() == null ? null : esData.getPm10().setScale(0,RoundingMode.UP));
            airData.setSo2(esData.getSo2() == null ? null : esData.getSo2().setScale(0,RoundingMode.UP));
            airData.setNo2(esData.getNo2() == null ? null : esData.getNo2().setScale(0,RoundingMode.UP));
            airData.setCo(esData.getCo() == null ? null : esData.getCo().setScale(1,RoundingMode.UP));
            airData.setO3(esData.getO3() == null ? null : esData.getO3().setScale(0,RoundingMode.UP));
            //分指数
            airData.setIaqiPm25(esData.getIaqi_pm25());
            airData.setIaqiPm10(esData.getIaqi_pm10());
            airData.setIaqiSo2(esData.getIaqi_so2());
            airData.setIaqiNo2(esData.getIaqi_no2());
            airData.setIaqiCo(esData.getIaqi_co());
            airData.setIaqiO3(esData.getIaqi_o3());
            //业务值
            airData.setMonitorTime(esData.getData_time());
            airData.setFkAqiLevelId(esData.getFk_aqilevel_id());
            airData.setFkAqiLevelName(aqiLevelMap.get(airData.getFkAqiLevelId()));
            airData.setFkPollutantId(esData.getFk_pollutant_id());
            airData.setRegionCode(esData.getRegion_code());
            airQualityData.add(airData);
        });

        if (regionInfoList != null && regionInfoList.size() > 0) {
            //补全区域和站点信息
            String dateTime = airParmaVo.getDatetime();
            List<String> allRegionCodes = regionInfoList.stream().map(e -> e.getRegionCode()).collect(Collectors.toList());
             //补充单个小时
             List<String> currentRegionCodes = airQualityData.stream().map(e -> e.getRegionCode()).collect(Collectors.toList());
             allRegionCodes.removeAll(currentRegionCodes);
             allRegionCodes.forEach(regionCode -> {
                 AirQualityData fillData = new AirQualityData();
                 fillData.setRegionCode(regionCode);
                 fillData.setMonitorTime(dateTime);
                 airQualityData.add(fillData);
             });
            //绑定区域名称
            regionInfoList.forEach(regionInfo ->
                    airQualityData.forEach(airData -> {
                        if (airData.getRegionCode().equals(regionInfo.getRegionCode())) {
                            airData.setRegionName(regionInfo.getRegionName());
                            airData.setLatitude(regionInfo.getLatitude());
                            airData.setLongitude(regionInfo.getLongitude());
                            airData.setRegionlevel(regionInfo.getRegionLever());
                        }
                    })
            );
        }
        List<AirQualityData> sort = airQualityData;
        if (Objects.nonNull(airParmaVo)) {
            //倒序
            if (airParmaVo.getDescSort() != null && airParmaVo.getDescSort() == 1) {
                sort = sort
                        .stream()
                        .filter(e -> StringUtils.isNotBlank(e.getMonitorTime()))
                        .sorted(Comparator.comparing(e -> DateUtil.stringToDate(e.getMonitorTime(), DateUtil.HOUR_TIME_PATTERN)))
                        .collect(Collectors.toList());
                Collections.reverse(sort);
            }
            //升序
            if (airParmaVo.getAscSort() != null && 1 == airParmaVo.getAscSort()) {
                sort = sort
                        .stream()
                        .filter(e -> StringUtils.isNotBlank(e.getMonitorTime()))
                        .sorted(Comparator.comparing(e -> DateUtil.stringToDate(e.getMonitorTime(), DateUtil.HOUR_TIME_PATTERN)))
                        .collect(Collectors.toList());
            }
        }
        //绑定首要污染物名称
        return parseFirstPollutant(sort);
    }
    
   
*/

    /**
     * 计算均值
     *
     * @param airDataList 区域小时数据
     * @return AirQualityData
     */
    public static AirQualityData calcAvgData(List<AirQualityData> airDataList) {
        //空气质量数据 均值计算
        BigDecimal pm25AvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getPm25() == null ? BigDecimal.ZERO : e.getPm25()).collect(Collectors.toList()));
        BigDecimal pm10AvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getPm10() == null ? BigDecimal.ZERO : e.getPm10()).collect(Collectors.toList()));
        BigDecimal so2AvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getSo2() == null ? BigDecimal.ZERO : e.getSo2()).collect(Collectors.toList()));
        BigDecimal no2AvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getNo2() == null ? BigDecimal.ZERO : e.getNo2()).collect(Collectors.toList()));
        BigDecimal coAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getCo() == null ? BigDecimal.ZERO : e.getCo()).collect(Collectors.toList()));
        BigDecimal o3AvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getO3() == null ? BigDecimal.ZERO : e.getO3()).collect(Collectors.toList()));
        BigDecimal aqiAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getAqi() == null ? BigDecimal.ZERO : new BigDecimal(e.getAqi())).collect(Collectors.toList()));
        BigDecimal pmiAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getPmi() == null ? BigDecimal.ZERO : e.getPmi()).collect(Collectors.toList()));

        //气象数据 均值计算
        BigDecimal windsAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getWinds() == null ? BigDecimal.ZERO : e.getWinds()).collect(Collectors.toList()));
        BigDecimal presAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getPres() == null ? BigDecimal.ZERO : e.getPres()).collect(Collectors.toList()));
        BigDecimal humiAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getHumi() == null ? BigDecimal.ZERO : e.getHumi()).collect(Collectors.toList()));
        BigDecimal tempAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getTemp() == null ? BigDecimal.ZERO : e.getTemp()).collect(Collectors.toList()));
        BigDecimal winddAvgValue = decimalAvgValue(airDataList.stream().map(e -> e.getWindd() == null ? BigDecimal.ZERO : e.getWindd()).collect(Collectors.toList()));
        //赋值
        AirQualityData avgAirData = airDataList.get(0) == null ? new AirQualityData() : airDataList.get(0);
        avgAirData.setAqi(aqiAvgValue.intValue());
        avgAirData.setFkAqiLevelId(AirQualityConverter.airQualityLevelNumber("aqi", new BigDecimal(aqiAvgValue.intValue()), false));
        avgAirData.setFkAqiLevelName(AirQualityConverter.airQualityLevel("aqi", new BigDecimal(aqiAvgValue.intValue()), 2, false));
        avgAirData.setPmi(pmiAvgValue.setScale(2, RoundingMode.HALF_EVEN));
        avgAirData.setPm25(pm25AvgValue.setScale(0, RoundingMode.HALF_EVEN));
        avgAirData.setPm10(pm10AvgValue.setScale(0, RoundingMode.HALF_EVEN));
        avgAirData.setSo2(so2AvgValue.setScale(0, RoundingMode.HALF_EVEN));
        avgAirData.setNo2(no2AvgValue.setScale(0, RoundingMode.HALF_EVEN));
        avgAirData.setCo(coAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        avgAirData.setO3(o3AvgValue.setScale(0, RoundingMode.HALF_EVEN));
        avgAirData.setWinds(windsAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        avgAirData.setPres(presAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        avgAirData.setHumi(humiAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        avgAirData.setTemp(tempAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        avgAirData.setWindd(winddAvgValue.setScale(1, RoundingMode.HALF_EVEN));
        return avgAirData;
    }

    /**
     * 通过list计算均值
     *
     * @return BigDecimal
     */
    public static BigDecimal decimalAvgValue(List<BigDecimal> valueList) {
        if (valueList != null && valueList.size() > 0) {
            return valueList
                    .stream()
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(valueList.size()), RoundingMode.HALF_EVEN);
        }
        return null;
    }


    /**
     * 通过list计算总和
     * @param valueList 集合
     * @return BigDecimal
     */
    public static BigDecimal decimalSumValue(List<BigDecimal> valueList) {
        //可能有空值，不可使用流计算
        if (valueList != null && valueList.size() > 0) {
            BigDecimal reduce = new BigDecimal(0);
            for (BigDecimal bigDecimal : valueList) {
                if (bigDecimal != null) {
                    reduce = reduce.add(bigDecimal);
                }
            }
//            BigDecimal reduce = valueList
//                    .stream()
//                    .reduce(null, BigDecimal::add);
            return reduce == null ? null : reduce.setScale(0,BigDecimal.ROUND_UP);
        }
        return null;
    }

    /**
     * 解析首要污染物
     *
     * @return List
     */
    public static List<AirQualityData> parseFirstPollutant(List<AirQualityData> airData) {
        //获取首要污染物Map
        HashMap<Integer, String> pollutantMap = buildPollutantMap();
        if (CollectionUtils.isNotEmpty(airData)) {
            for (AirQualityData airDatum : airData) {
                List<String> pollutantName = new ArrayList<>();
                if (airDatum != null) {
                    String fkPollutantId = airDatum.getFkPollutantId();
                    if (StringUtils.isNotBlank(fkPollutantId)) {
                        String[] pollutantId = fkPollutantId.split(",");
                        for (String id : pollutantId) {
                            pollutantName.add(pollutantMap.get(Integer.parseInt(id)));
                        }
                        String collect = pollutantName.stream().collect(Collectors.joining(","));
                        if(StringUtils.isNotBlank(collect) && collect.equals("null")){
                            collect = "--";
                        }
                        airDatum.setFkPollutantName(collect);
                    }
                }
            }
        }
        return airData;
    }

    /**
     * 首要污染物list转map     1 : PM25 ...
     *
     * @return HashMap
     */
    public static HashMap<Integer, String> buildPollutantMap() {
        HashMap<Integer, String> poMap = new HashMap<>(27);
        List<SEnvgasPollutant> pollutants = airDataConverseUtil.sEnvgasPollutantMapper.selectList(new QueryWrapper<SEnvgasPollutant>());
        pollutants.forEach(po -> {
            poMap.put(po.getPkId(), po.getPollutantName());
        });
        return poMap;
    }



    /**
     * aqi污染等级list 转 map 1:优 2:良 ...
     *
     * @return HashMap
     */
    public static HashMap<Integer, String> buildAqiLevelMap() {
        HashMap<Integer, String> aqiLevelMap = new HashMap<>(27);
        List<SEnvgasAqilevel> aqilevelList = airDataConverseUtil.sEnvgasAqilevelMapper.selectList(new QueryWrapper<>());
        aqilevelList.forEach(level -> aqiLevelMap.put(level.getPkId(), level.getAqiType()));
        return aqiLevelMap;
    }

    @PostConstruct
    public void init() {
        airDataConverseUtil = this;
    }

}
