package com.sunxung.factoring.dict.impl;

import org.springframework.stereotype.Component;

import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.StringUtil;
import com.sunxung.factoring.dict.Dict;
import com.sunxung.factoring.entity.sys.Dictionary;

/**
 * 组织机构级别字典
 */
@Component
public class OrgLevelDict extends Dict {

    /** 编码 */
    public static String CODE = "orgLevel";
    /** 中文名称 */
    public static String CNAME = "组织机构类型";

    /** 子项枚举 */
    public static enum ChildEnum {
        /** 国 */
        COUNTRY("country", "国"),
        /** 省 */
        PROVINCE("province", "省"),
        /** 市 */
        CITY("city", "市"),
        /** 县/区 */
        DISTRICT("district", "县/区"),
        /** 乡/镇 */
        TOWN("town", "乡/镇"),
        /** 村/社区 */
        VILLAGE("village", "村/社区"),
        /** 网格 */
        GRID("grid", "网格");

        /**
         * 根据编码获取枚举类型实例
         * 
         * @param code 编码
         * @return
         */
        public static ChildEnum newInstance(String code) {
            if (StringUtil.isNotEmpty(code)) {
                for (ChildEnum childEnum : ChildEnum.values()) {
                    if (childEnum.getCode().equals(code)) {
                        return childEnum;
                    }
                }
            }
            return null;
        }

        /** 编码 */
        private String code;
        /** 名称 */
        private String cname;

        ChildEnum(String code, String cname){
            this.code = code;
            this.cname = cname;
        }

        public String getCode() {
            return code;
        }

        public String getCname() {
            return cname;
        }

        /**
         * 判断层级顺序，比如省级在市级别前
         * 
         * @param targetCode
         * @return
         */
        public boolean before(String targetCode) {
            ChildEnum next = this.next();
            return isExists(next, targetCode);
        }

        private boolean isExists(ChildEnum next, String targetCode) {
            if (null != next && StringUtil.isNotEmpty(targetCode)) {
                if (!next.getCode().equals(targetCode)) {
                    next = next.next();
                    return isExists(next, targetCode);
                }
                return true;
            }
            return false;
        }

        /**
         * 获取下一级别
         * 
         * @return
         */
        public ChildEnum next() {
            return next(this);
        }

        private ChildEnum next(ChildEnum ele) {
            switch (ele) {
                case COUNTRY: {
                    return PROVINCE;
                }
                case PROVINCE: {
                    return CITY;
                }
                case CITY: {
                    return DISTRICT;
                }
                case DISTRICT: {
                    return TOWN;
                }
                case TOWN: {
                    return VILLAGE;
                }
                case VILLAGE: {
                    return GRID;
                }
                default: {
                    return null;
                }
            }
        }
    }

    @Override
    public void add(int gradation) {
        Dictionary domain = addDomainDictionary(null, gradation);
        if (domain == null) {
            throw new ValidatorException(CodeUtil.FAIL, "组织机构类型字典新增失败");
        }
        for (ChildEnum child : ChildEnum.values()) {
            addChildEnumDictionary(domain.getId(), child);
        }
    }

    private Dictionary addChildEnumDictionary(Long parentId, ChildEnum child) {
        Dictionary dictionary = new Dictionary();
        dictionary.setParentId(parentId);
        dictionary.setName(child.getCname());
        dictionary.setCode(child.getCode());
        dictionary.setGradation(child.ordinal());
        return dictionaryService.add(dictionary);
    }

    private Dictionary addDomainDictionary(Long parentId, int gradation) {
        Dictionary dictionary = new Dictionary();
        dictionary.setParentId(parentId);
        dictionary.setName(CNAME);
        dictionary.setCode(CODE);
        dictionary.setGradation(gradation);
        return dictionaryService.add(dictionary);
    }
}
