package com.app.framework.core.support.enums;

import com.app.framework.core.support.enums.data.EnumItem;
import com.app.framework.core.support.enums.data.EnumItemPool;
import org.apache.commons.lang.StringUtils;

import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * 枚举基类，提供枚举常用的方法
 * 提供实例方法：getValue、getText、equalValue、isNotEquals
 * 提供静态方法：getByValue、getByText、getTextByValue
 *
 * @param <K> value数据类型
 */
public interface BaseEnum<K extends Serializable> {

    default void putEnumItem(K value, String text) {
        EnumItemPool.putEnumItem(this, value, text);
    }

    default EnumItem getEnumItem() {
        return EnumItemPool.getEnumItem(this);
    }

    default K getValue() {
        return (K) getEnumItem().getValue();
    }

    default String getText() {
        return getEnumItem().getText();
    }

    /**
     * 当前对象的 value 是否 和参数中的 value 相等
     *
     * @param value
     * @return
     */
    default boolean equalValue(K value) {
        return this.getValue().equals(value);
    }

    /**
     * 当前对象是否和已知对象不等
     *
     * @param item
     * @return
     */
    default boolean isNotEquals(BaseEnum item) {
        return this != item;
    }

    /**
     * 通过 value 获取指定 枚举类型中的 枚举对象
     *
     * @param enumClass
     * @param value
     * @param <T>
     * @return
     */
    static <T extends BaseEnum> T getByValue(Class<T> enumClass, Serializable value) {
        if (Objects.isNull(value)) {
            return null;
        }
        return Stream.of(enumClass.getEnumConstants()).filter(x -> x.getValue().equals(value)).findAny().orElse(null);
    }

    /**
     * 通过 text 获取指定 枚举类型中的 枚举对象
     *
     * @param enumClass 枚举类
     * @param text
     * @param <T>
     * @return
     */
    static <T extends BaseEnum> T getByText(Class<T> enumClass, String text) {
        if (Objects.isNull(text)) {
            return null;
        }
        return Stream.of(enumClass.getEnumConstants()).filter(x -> x.getText().equals(text)).findAny().orElse(null);
    }

    /**
     * 通过 value 获取指定 枚举类型中的 text
     *
     * @param enumClass
     * @param value
     * @param <T>
     * @return
     */
    static <T extends BaseEnum> String getTextByValue(Class<T> enumClass, Serializable value) {
        return Optional.ofNullable(getByValue(enumClass, value)).map(BaseEnum::getText).orElse(StringUtils.EMPTY);
    }
}
