package com.njcn.common.utils;


import com.njcn.common.pojo.enums.common.ServerEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author hongawen
 * @version 1.0.0
 * @date 2021年05月26日 11:44
 */
public class EnumUtils {

    private final static int
            COMMON_ENUM_FLOOR = 0
            ,COMMON_ENUM_CEIL = 99
            ,USER_ENUM_FLOOR = 100
            ,USER_ENUM_CEIL = 199
            ,GATEWAY_ENUM_FLOOR = 200
            ,GATEWAY_ENUM_CEIL = 249
            ,DEVICE_ENUM_FLOOR = 250
            ,DEVICE_ENUM_CEIL = 349
            ,SYSTEM_ENUM_FLOOR = 350
            ,SYSTEM_ENUM_CEIL = 449
            ,HARMONIC_ENUM_CEIL = 450
            ,HARMONIC_ENUM_FLOOR = 549;



    /**
     * 值映射为枚举
     *
     * @param enumClass 枚举类
     * @param value     枚举值
     * @param method    取值方法
     * @param <E>       对应枚举
     */
    public static <E extends Enum<?>> E valueOf(Class<E> enumClass, Object value, Method method) {
        E[] es = enumClass.getEnumConstants();
        for (E enumTemp : es) {
            Object evalue;
            try {
                method.setAccessible(true);
                evalue = method.invoke(enumTemp);
            } catch (IllegalAccessException | InvocationTargetException e1) {
                throw new BusinessException(CommonResponseEnum.ENUM_ERROR);
            }
            if (value instanceof Number && evalue instanceof Number
                    && new BigDecimal(String.valueOf(value)).compareTo(new BigDecimal(String.valueOf(evalue))) == 0) {
                return enumTemp;
            }
            if (Objects.equals(evalue, value)) {
                return enumTemp;
            }
        }
        return null;
    }


    /**
     * 根据枚举code获取CommonResponseEnum实例
     */
    public static CommonResponseEnum getCommonResponseEnumByCode(String code) {
        code = getCode(code);
        CommonResponseEnum commonResponseEnum;
        try {
            commonResponseEnum = valueOf(CommonResponseEnum.class, code, CommonResponseEnum.class.getMethod(BusinessException.GET_CODE_METHOD));
            return Objects.isNull(commonResponseEnum) ? CommonResponseEnum.INTERNAL_ERROR : commonResponseEnum;
        } catch (NoSuchMethodException e) {
            throw new BusinessException(CommonResponseEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 根据枚举message获取CommonResponseEnum实例
     */
    public static CommonResponseEnum getCommonResponseEnumByMessage(String message) {
        CommonResponseEnum commonResponseEnum;
        try {
            commonResponseEnum = valueOf(CommonResponseEnum.class, message, CommonResponseEnum.class.getMethod(BusinessException.GET_MESSAGE_METHOD));
            return Objects.isNull(commonResponseEnum) ? CommonResponseEnum.INTERNAL_ERROR : commonResponseEnum;
        } catch (NoSuchMethodException e) {
            throw new BusinessException(CommonResponseEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 获取UserStatusEnum实例
     */
    public static ServerEnum getServerEnumByName(Object value) {
        ServerEnum serverEnum;
        try {
            serverEnum = EnumUtils.valueOf(ServerEnum.class, value, ServerEnum.class.getMethod("getName"));
            return Objects.isNull(serverEnum) ? ServerEnum.COMMON : serverEnum;
        } catch (NoSuchMethodException e) {
            throw new BusinessException(CommonResponseEnum.INTERNAL_ERROR);
        }
    }


    /**
     * 如何通过枚举code获取响应的枚举类型
     * 比如 A0000 ~ A0099 通用业务枚举
     * 比如 A0100 ~ A0199 用户业务枚举
     * 比如 A0200 ~ A0249 网关业务枚举
     * 比如 A0250 ~ A0349 终端业务枚举
     * 比如 A0350 ~ A0449 系统业务枚举
     */
    private static String  getCode(String originalCode){
        int code = Integer.parseInt(originalCode.substring(1));
        if(PubUtils.rangeInDefined(code,0,99)){
            return originalCode;
        }else if(PubUtils.rangeInDefined(code,100,199)){
            return CommonResponseEnum.USER_RESPONSE_ENUM.getCode();
        }else if(PubUtils.rangeInDefined(code,200,249)){
            return CommonResponseEnum.GATEWAY_RESPONSE_ENUM.getCode();
        }else if(PubUtils.rangeInDefined(code,250,349)){
            return CommonResponseEnum.DEVICE_RESPONSE_ENUM.getCode();
        }else if(PubUtils.rangeInDefined(code,350,449)){
            return CommonResponseEnum.SYSTEM_RESPONSE_ENUM.getCode();
        }else{
            return originalCode;
        }
    }



}