package com.gyee.runeconomy.dto.speed;

import java.text.DecimalFormat;
import java.util.*;

/**
 * 风向玫瑰图
 * 风向频次玫瑰图
 */
public class WindDirectionALG {

    /**
     * 风速风向玫瑰图
     * 风速：[0,2.5) [2.5,5) [5,7.5) [7.5,10) [10,12.5) [12.5,15) [15,17.5) [17.5,20) [20,22.5) [22.5,25) [25,inf)  11
     *
     * @param list
     */
    public static Object fxRoses(List<PowerPointData> list) {
        int[][] count = new int[11][16];

        list.stream().forEach(item -> {
            int fx = windFXAngle(item.getFx());
            int speed = windSpeed(item.getSpeed());
            if (speed < 11 && fx < 16)
                count[speed][fx] = 1;
        });

        return count;
    }


    /**
     * 风向频次玫瑰图
     * 风速：[0,2.5) [2.5,5) [5,7.5) [7.5,10) [10,12.5) [12.5,15) [15,17.5) [17.5,20) [20,22.5) [22.5,25) [25,inf)  11
     *
     * @param list
     */
    public static int[][] fxCountRoses(List<PowerPointData> list) {
        int[][] count = new int[11][16];
        list.stream().sorted(Comparator.comparing(PowerPointData::getSpeed)).forEach(item -> {
            int fx = windFXAngle(item.getFx());
            int speed = windSpeed(item.getSpeed());
            if (speed < 11 && fx < 16)
                count[speed][fx]++;
        });

        return count;
    }


    /**
     * 风向频次雷达图
     *
     * @param list
     * @return
     */
    public static int[] fxRadarRoses(List<PowerPointData> list) {

        try {
            int[] count = new int[16];
            list.stream().sorted(Comparator.comparing(PowerPointData::getSpeed)).forEach(item -> {
                int df = windDFAngle(item.getDfwc());
                if (count.length > df && count[df] < 1000) {
                    count[df]++;
                }
            });
            return count;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }


    /**
     * 静风频率计算 、平均风速计算
     *
     * @param list       风速数组
     * @param cutInSpeed 切入风速
     * @return
     */
    public static List<Double> frequency(List<Double> list, double cutInSpeed) {
        List<Double> result = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("0.00");
        int count = 0;
        double speed = 0.0;
        for (Double fs : list) {
            speed += fs;
            if (fs < cutInSpeed)
                count++;
        }
        double frequency = list.size() > 0 ? Double.valueOf(df.format(((double) count / list.size() * 100))) : 0;
        double speedAVG = list.size() > 0 ? Double.valueOf(df.format(speed / list.size())) : 0;
        result.add(frequency);
        result.add(speedAVG);
        return result;
    }


    /**
     * 对风偏差散点过滤  统计-50 到 50的
     * 频次
     * @param list
     *
     *
     * @return
     */
    //    public static List<Point> windDeviationScatter(List<PowerPointData> list){
    //        //正负偏差 [-50,-49,....,0,1,2,.....50]
    //        List<Point> ls = new ArrayList<>();
    //        LinkedHashSet<Double> keys = new LinkedHashSet<>();  //散点太多去重
    //        //次数统计
    //        for (int i = 0; i < list.size(); i++){
    //            PowerPointData item = list.get(i);
    //            int ele = (int)Math.round((item.getFx() + Math.abs(item.getDfwc())));
    //            int index = ele - 180;
    //            if (index >= -50 && index <= 50) {
    //                double key = Math.abs(index) + item.getSpeed();
    //                if (!keys.contains(key))
    //                    ls.add(new Point(index, item.getSpeed()));
    //                keys.add(key);
    //            }
    //        }
    //
    //        return ls;
    //    }


    /**
     * 静态偏航对风分析
     * 对风偏差散点过滤  统计-15 到 15的  正负偏差 [-15,-14,....,0,1,2,.....15]
     * 数据为二维数组 内层数组为3项. 第一项表示Y轴索引（风速）,  第二项代表X轴的索引（正负偏差） 第三项代表value值.
     *
     * @param points
     * @return
     */
    public static Map<String, Object> windDeviationPoint(List<PowerPointData> points) {
        try {
            List<PowerPointData> list = new ArrayList<>();
            List<Object> temp = new ArrayList<>();
            Map<String, Object> result = new HashMap<>();
            Map<Integer, double[]> map = new LinkedHashMap<>();

            //过滤对风偏差
            for (int i = 0; i < points.size(); i++) {
                PowerPointData item = points.get(i);
                if ((item.getSpeed() < 4.5 || item.getSpeed() >= 10.5) && item.getMxzt() != 2)
                    continue;

                list.add(item);
                Integer speed = Math.toIntExact(Math.round(item.getSpeed()));
                if (!map.containsKey(speed))
                    map.put(speed, new double[2]);  //[0]最小值 [1]最大值

                double[] value = map.get(speed);
                double power = item.getPower() < 0 ? 0 : item.getPower();
                value[0] = power < value[0] ? power : value[0]; //最小值
                value[1] = power > value[1] ? power : value[1]; //最大值
            }

            int avg = 0;
            DecimalFormat sf = new DecimalFormat("0.00");
            for (int i = 0; i < list.size(); i++) {
                PowerPointData item = list.get(i);
                Integer speed = Math.toIntExact(Math.round(item.getSpeed()));
                int ele = (int) (Math.abs(item.getFx()) + Math.abs(item.getAngle()));
                int index = ele - 180;
                if (index >= -30 && index <= 30 && item.getPower() > 0) {
                    avg += index;
                    double[] value = map.get(speed);
                    double v = (item.getPower() - value[0]) / (value[1] - value[0]);
                    double s[] = {speed, index, Double.valueOf(sf.format(v)).doubleValue()};
                    temp.add(s);
                }
            }
            result.put("data", temp);
            result.put("avg", temp.size() > 0 ? avg / temp.size() : 0);

            return result;
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 对风偏差频次统计  统计-50 到 50
     *
     * @param list
     * @return
     */
    public static int[] windDeviationRatio(List<PowerPointData> list) {
        int[] pc = new int[101];  //正负偏差 [-50,-49,....,0,1,2,.....50]
        //次数统计
        for (int i = 0; i < list.size(); i++) {
            PowerPointData item = list.get(i);
            int ele = (int) (Math.abs(item.getFx()) + Math.abs(item.getDfwc()));
            int index = ele - 180;
            if (index >= -50 && index <= 50)
                pc[50 - (index > 0 ? -index : Math.abs(index))]++;
        }

        return pc;
    }


    /**
     * 风向划分
     * 0:0-22.5
     * 1:22.5-45
     * 2:90-135
     * .。。。。。。
     *
     * @param fx
     * @return params: 0,1,2。。。。。15
     */
    private static int windFXAngle(double fx) {
        int split = 16;  //风向分为16个角度
        double angle = (double) 360 / split;
        int index = Math.abs((int) (fx / angle));
        return index;
    }

    /**
     * 对风角度计算
     * 0:0-22.5
     * 1:22.5-45
     * 2:90-135
     * .。。。。。。
     *
     * @param
     * @return
     */
    private static int windDFAngle(double angle) {
        int split = 16;  //风向分为8个角度
        double interval = (double) 360 / split;
        angle = angle > 360 ? 720 - 360 : angle;
        int index = (int) (Math.abs(angle) / interval);
        return index;
    }

    /**
     * 风速区域划分
     *
     * @param speed
     * @return
     */
    private static int windSpeed(double speed) {
        if (speed < 2.5)
            return 0;
        else if (speed < 5)
            return 1;
        else if (speed < 7.5)
            return 2;
        else if (speed < 10)
            return 3;
        else if (speed < 12.5)
            return 4;
        else if (speed < 15)
            return 5;
        else if (speed < 17.5)
            return 6;
        else if (speed < 20)
            return 7;
        else if (speed < 22.5)
            return 8;
        else if (speed < 25)
            return 9;
        else
            return 10;
    }


    /**
     * 数据聚合  间隔10
     *
     * @param list
     * @return
     */
    private static Object arrayDistinct(List<List<Double>> list) {
        for (List<Double> item : list) {
            List<Double> lt = new ArrayList<>();
            LinkedHashSet<Integer> ls = new LinkedHashSet<>();
            item.forEach(ele -> {
                if (ele == null)
                    return;
                int v = (int) (ele / 10);
                if (!ls.contains(v))
                    lt.add(ele);

                ls.add(v);
            });
            item.clear();
            item.addAll(lt);
        }

        return list;
    }
}
