package com.apobates.forum.member.impl.event;

import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.entity.MemberStatusEnum;
import com.apobates.forum.utils.lang.EnumArchitecture;
import org.springframework.context.ApplicationEvent;
import java.util.*;

public class MemberChangeEvent extends ApplicationEvent {
    private final long memberId;
    private final String key;
    private final int value;
    private final static Map<String,String> MAP_STRUCT = new HashMap<>();

    static {
        MAP_STRUCT.put("MemberStatusEnum", "status");
        MAP_STRUCT.put("MemberGroupEnum", "group");
        MAP_STRUCT.put("MemberRoleEnum", "role");
    }

    public MemberChangeEvent(Object source, long memberId, MemberStatusEnum status) {
        this(source, memberId, status, MemberStatusEnum.class);
    }

    public MemberChangeEvent(Object source, long memberId, MemberRoleEnum role) {
        this(source, memberId, role, MemberRoleEnum.class);
    }

    public MemberChangeEvent(Object source, long memberId, MemberGroupEnum group) {
        this(source, memberId, group, MemberGroupEnum.class);
    }

    private MemberChangeEvent(Object source, long memberId, EnumArchitecture archite, Class<?> cls){
        super(source);
        if(!EnumArchitecture.class.isAssignableFrom(cls)){
            throw new IllegalStateException("参数不是合法值");
        }
        Optional<String> k = getMapKey(cls);
        if(!k.isPresent()){
            throw new IllegalStateException("不支持的Key");
        }
        this.memberId = memberId;
        this.key = k.get();
        this.value = archite.getSymbol();
    }

    public long getMemberId() {
        return memberId;
    }

    public String getKey() {
        return key;
    }

    public int getValue() {
        return value;
    }
    /**
     * 变化事件允许的映射Key
     *
     * @return
     */
    public static Set<String> allowKey(){
        return new HashSet<>(MAP_STRUCT.values());
    }

    /**
     * 根据类查询映射Key
     *
     * @param <T> EnumArchitecture的实现枚举类型
     * @param cls EnumArchitecture的实现枚举.class
     * @return
     */
    public static <T> Optional<String> getMapKey(Class<T> cls){
        String cCN = cls.getSimpleName();
        if(MAP_STRUCT.containsKey(cCN)){
            return Optional.ofNullable(MAP_STRUCT.get(cCN));
        }
        return Optional.empty();
    }

    /**
     *
     * @param <T> EnumArchitecture的实现枚举类型
     * @param cls EnumArchitecture的实现枚举.class
     * @param mapping 映射的值集合
     * @return
     */
    public static <T> Optional<T> get(Class<T> cls, Map<String,Integer> mapping){
        Optional<String> mapKey = getMapKey(cls);
        if(mapKey.isPresent() && mapping.containsKey(mapKey.get())){
            return EnumArchitecture.getInstance(mapping.get(mapKey.get()), cls);
        }
        return Optional.empty();
    }
}
