package com.diagbot.util;

import com.diagbot.core.KeyedNamed;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @author: gaodm
 * @time: 2018/9/19 14:21
 */
public class EnumEntriesBuilder {
    private Map<String, List<Entry>> json;

    public EnumEntriesBuilder() {
        json = new HashMap<>();
    }

    /**
     * 按照enum值来封装options
     */
    public <E extends Enum<E> & KeyedNamed> EnumEntriesBuilder addEnums(String name, E... enums) {
        return addEnums(name, build(enums));
    }

    public <E extends Enum<E>> EnumEntriesBuilder addEnums(String name, KeyedNamedAdapter<E> adapter, E... enums) {
        List<Entry> entries = new ArrayList<>();
        for (E e : enums) {
            KeyedNamed keyedNamed = adapter.from(e);
            entries.add(new Entry(keyedNamed.getName(), keyedNamed.getKey()));
        }
        return addEnums(name, entries);
    }

    /**
     * 转换任意类型
     */
    public <E> EnumEntriesBuilder addEnums(String name, KeyedNamedAdapter<E> adapter, Iterable<E> iterable) {
        List<Entry> entries = new ArrayList<>();
        for (E t : iterable) {
            KeyedNamed keyedNamed = adapter.from(t);
            entries.add(new Entry(keyedNamed.getName(), keyedNamed.getKey()));
        }
        return addEnums(name, entries);
    }


    /**
     * 按照key值来封装options
     * <p/>
     * 不建议使用该方法，以免传入一个不存在的key值
     */
    @Deprecated
    public <E extends Enum<E> & KeyedNamed> EnumEntriesBuilder addEnums(String name, Class<E> clz, Integer... keys) {

        List<Entry> entries = new ArrayList<>();
        for (Integer key : keys) {
            E e = EnumUtil.getEnum(key, clz);
            if (e == null) {
                throw new IllegalArgumentException(name + "对应的key:" + key + "不存在");
            }
            entries.add(new Entry(e.getName(), e.getKey()));
        }
        return addEnums(name, entries);
    }

    public EnumEntriesBuilder addEnums(String name, List<Entry> entries) {
        json.put(name, entries);
        return this;
    }

    public static <E extends Enum<E> & KeyedNamed> List<Entry> build(E... enums) {
        List<Entry> enumEntries = new ArrayList<>();
        for (E e : enums) {
            enumEntries.add(new Entry(e.getName(), e.getKey()));
        }
        return enumEntries;
    }

    public Map<String, List<Entry>> build() {
        return json;
    }

    /**
     * 下拉框的option数据封装
     *
     * @author youmoo
     */
    @Data
    public static class Entry<E> {
        /**
         * option text
         */
        private String name;
        /**
         * option value
         */
        private E key;

        public Entry(String name, E key) {
            this.name = name;
            this.key = key;
        }

        public Entry() {

        }
    }

    public interface KeyedNamedAdapter<E> {
        KeyedNamed from(E e);
    }
}
