package com.njcn.mysql.util;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.njcn.oracle.bo.po.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

public class PubUtils {


    /**
     * 根据传递的时间范围获取每天时间集合
     * @param timeBegin
     * @param timeEnd
     * @return
     */
    public static List<String> getTimeList(String timeBegin, String timeEnd) {
        List<String> timeStringList=new ArrayList<>();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DatePattern.NORM_DATE_PATTERN);
            Date begin = sdf.parse(timeBegin);
            Date end = sdf.parse(timeEnd);
            List<Date> lDate = new ArrayList<>();
            lDate.add(begin);
            Calendar calBegin = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calBegin.setTime(begin);
            Calendar calEnd = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calEnd.setTime(end);
            // 测试此日期是否在指定日期之后
            while (end.after(calBegin.getTime()))
            {
                // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                lDate.add(calBegin.getTime());
            }

            for (Date datePes :lDate){
                String format = sdf.format(datePes);
                timeStringList.add(format);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return timeStringList;
    }

    /**
     * 判断数据是否异常 0:正常 1:异常
     * code: 指标名称
     * object: 数据实体
     */
    public static int judgeData(Integer code, Object object, String type) {
        int result = 0;
        switch (code) {
            case 0:
                DayV data  = new ObjectMapper().convertValue(object, DayV.class);
                try {
                    String methodName1 = "getFreq" + (Objects.isNull(type)?"":type);
                    Method method1 = data.getClass().getMethod(methodName1);
                    float value1 = (Float) method1.invoke(data);

                    String methodName2 = "getVuDev" + (Objects.isNull(type)?"":type);
                    Method method2 = data.getClass().getMethod(methodName2);
                    float value2 = (Float) method2.invoke(data);

                    String methodName3 = "getVlDev" + (Objects.isNull(type)?"":type);
                    Method method3 = data.getClass().getMethod(methodName3);
                    float value3 = (Float) method3.invoke(data);

                    String methodName4 = "getFreqDev" + (Objects.isNull(type)?"":type);
                    Method method4 = data.getClass().getMethod(methodName4);
                    float value4 = (Float) method4.invoke(data);

                    String methodName5 = "getVUnbalance" + (Objects.isNull(type)?"":type);
                    Method method5 = data.getClass().getMethod(methodName5);
                    float value5 = (Float) method5.invoke(data);

                    String methodName6 = "getVThd" + (Objects.isNull(type)?"":type);
                    Method method6 = data.getClass().getMethod(methodName6);
                    float value6 = (Float) method6.invoke(data);

                    List<String> phase = Arrays.asList("A","B","C");
                    //频率异常判断
                    if (Objects.equals(data.getPhasicType(),"T") && (value1 > 57.5|| value1 < 42.5)){
                        result = 1;
                    }
                    //电压偏差异常判断
                    if (phase.contains(data.getPhasicType()) && (Math.abs(value2) >20.0|| Math.abs(value3) >20.0)){
                        result = 1;
                    }
                    //频率偏差异常判断
                    if (Objects.equals(data.getPhasicType(),"T") && Math.abs(value4) >7.5){
                        result = 1;
                    }
                    //三相电压不平衡度异常判断
                    if (Objects.equals(data.getPhasicType(),"T") && (value5 <0.0|| value5 > 40.0)){
                        result = 1;
                    }
                    //电压总谐波畸变率异常判断
                    if (phase.contains(data.getPhasicType()) && (value6 < 0.0 || value6 > 30.0)){
                        result = 1;
                    }
                } catch (Exception e) {
                    e.getMessage();
                }
                return result;
            case 2:
                try {
                    DayFlicker data2  = new ObjectMapper().convertValue(object, DayFlicker.class);
                    String methodName1 = "getFluc" + (Objects.isNull(type)?"":type);
                    Method method1=data2.getClass().getMethod(methodName1);
                    float value = (Float) method1.invoke(data2);

                    String methodName2 = "getPlt" + (Objects.isNull(type)?"":type);
                    Method method2=data2.getClass().getMethod(methodName2);
                    float value2 = (Float) method2.invoke(data2);

                    String methodName3 = "getPst" + (Objects.isNull(type)?"":type);
                    Method method3=data2.getClass().getMethod(methodName3);
                    float value3 = (Float) method3.invoke(data2);

                    //电压波动值判断
                    if ( (value > 40.0|| value < 0)){
                        result = 1;
                    }
                    //短时闪变值判断
                    if ( (value2 > 20.0|| value2 < 0)){
                        result = 1;
                    }
                    //长时闪变值判断
                    if ( (value3 > 20.0|| value3 < 0)){
                        result = 1;
                    }
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.getMessage();
                }
                return result;
            case 3:
                //长时闪变
                DayPlt data3  = new ObjectMapper().convertValue(object, DayPlt.class);
                String methodName1 = "getPlt" + (Objects.isNull(type)?"":type);
                Method method1 = null;
                try {
                    method1 = data3.getClass().getMethod(methodName1);
                    float value = (Float) method1.invoke(data3);
                    //长时闪变值判断
                    if ( (value > 20.0|| value < 0)){
                        result = 1;
                    }
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    e.getMessage();
                }
                return result;
            case 4:
                DayHarmrateV data4  = new ObjectMapper().convertValue(object, DayHarmrateV.class);
                List<Float> avgData4 = getData(data4);
                boolean quality4 = avgData4.stream().anyMatch(o->o>30.0 || o<0.0);
                if (quality4) {
                    result = 1;
                }
                return result;
            default:
                return result;
        }
    }

    /**
     * 2-50次谐波数据赋值
     * @param po1
     * @param data
     * @param judge
     * @param getString
     * @param setString
     * @param getEndString
     */
    public static void setValuesUsingReflection(Object po1, Object data, boolean judge, String getString, String setString, String getEndString) {
        try {
            for (int i = 1; i <= 50; i++) {
                String methodNameGet;
                if (judge) {
                    methodNameGet = getString + i + getEndString;
                } else {
                    methodNameGet = getString + i;
                }
                String methodNameSet = setString + i;
                Method getMethod = data.getClass().getMethod(methodNameGet);
                Object value = getMethod.invoke(data);
                if (value != null) {
                    BigDecimal bigDecimalValue = new BigDecimal(value.toString());
                    //防止数据异常大，超过数据库字段设置的大小
                    float floatValue = Math.min(bigDecimalValue.floatValue(), 999999.0f);
                    Method setMethod = po1.getClass().getMethod(methodNameSet, Float.class);
                    setMethod.invoke(po1, floatValue);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取谐波2-50次数据
     * @param data
     * @return
     */
    public static List<Float> getData(Object data) {
        List<Float> avgData = new ArrayList<>();
        try {
            for (int i = 1; i <= 50; i++) {
                String methodName = "getV" + i;
                Method method = data.getClass().getMethod(methodName);
                Float value = (Float) method.invoke(data);
                avgData.add(value);

                String methodName2 = "getV" + i + "Max";
                Method method2 = data.getClass().getMethod(methodName2);
                Float value2 = (Float) method2.invoke(data);
                avgData.add(value2);

                String methodName3 = "getV" + i + "Min";
                Method method3 = data.getClass().getMethod(methodName3);
                Float value3 = (Float) method3.invoke(data);
                avgData.add(value3);

                String methodName4 = "getV" + i + "Cp95";
                Method method4 = data.getClass().getMethod(methodName4);
                Float value4 = (Float) method4.invoke(data);
                avgData.add(value4);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return avgData;
    }


}
