package cc.smtweb.framework.core.common;

import cc.smtweb.framework.core.util.NumberUtil;
import org.apache.commons.lang3.StringUtils;

import java.sql.Types;

/**
 * Created by Akmm at 2022/3/23 9:39
 * 系统的一些枚举变量
 */
public interface SwEnum {


    /**
     * Created by Akmm at 2022/2/9 10:01
     * 字段业务类别
     */
    class FieldTypeBean extends AbstractEnum.IntEnumBean {
        public String dataType;
        public int notNull;

        public FieldTypeBean(Integer value, String name, String dataType) {
            super(value, name);
            this.dataType = dataType;
            this.notNull = 0;
        }

        public FieldTypeBean(Integer value, String name, String dataType, int notNull) {
            super(value, name);
            this.dataType = dataType;
            this.notNull = notNull;
        }
    }

    class FieldType extends AbstractEnum<Integer, FieldTypeBean> {
        public static FieldType instance = new FieldType();

        public static FieldTypeBean ID = instance.addEnum(1, "主键", DataType.ID.value, 1);
        public static FieldTypeBean CODE = instance.addEnum(2, "编码字段", DataType.CODE.value, 1);
        public static FieldTypeBean NAME = instance.addEnum(3, "名称字段", DataType.NAME.value, 1);
        public static FieldTypeBean PARENT_ID = instance.addEnum(4, "父ID", DataType.ID.value);
        public static FieldTypeBean LEVEL_CODE = instance.addEnum(5, "级次码", DataType.CODE.value);
        public static FieldTypeBean LEVEL = instance.addEnum(6, "级次", DataType.SHORT.value);
        //        public static FieldTypeBean ORDER = instance.addEnum(6, "排序字段", "");
        public static FieldTypeBean CREATE_USER = instance.addEnum(7, "创建人", DataType.ID.value);
        public static FieldTypeBean CREATE_TIME = instance.addEnum(8, "创建时间", DataType.DATETIME.value);
        public static FieldTypeBean UPDATE_USER = instance.addEnum(9, "更新人", DataType.ID.value);
        public static FieldTypeBean LAST_TIME = instance.addEnum(10, "更新时间", DataType.DATETIME.value);

        @Override
        protected FieldTypeBean buildBean(Integer value, String name) {
            return new FieldTypeBean(value, name, "");
        }

        public FieldTypeBean addEnum(Integer value, String name, String dataType) {
            final FieldTypeBean bean = new FieldTypeBean(value, name, dataType);
            mapAll.put(value, bean);
            return bean;
        }

        public FieldTypeBean addEnum(Integer value, String name, String dataType, int notNull) {
            final FieldTypeBean bean = new FieldTypeBean(value, name, dataType, notNull);
            mapAll.put(value, bean);
            return bean;
        }
    }

    /**
     * 字段编辑类型
     */
    class EditorType extends StrEnum {
        public static EditorType instance = new EditorType();

        public static StrEnumBean INPUT = instance.addEnum("text", "文本");
        public static StrEnumBean TEXT = instance.addEnum("textarea", "长文本");
        public static StrEnumBean NUMBER = instance.addEnum("number", "数字");
        public static StrEnumBean SWITCH = instance.addEnum("switch", "布尔型");
        public static StrEnumBean DATE = instance.addEnum("date", "日期");
        public static StrEnumBean TIME = instance.addEnum("time", "时间");
        public static StrEnumBean DATETIME = instance.addEnum("datetime", "日期时间");
        public static StrEnumBean COMBO = instance.addEnum("select", "下拉列表");
        public static StrEnumBean TREE = instance.addEnum("tree-select", "下拉树");
    }

    /**
     * 数据字段类型Bean
     */
    class DataTypeBean extends AbstractEnum.StrEnumBean {
        public String sqlType;
        public int dataLength;
        public String javaType;
        public String shortJavaType;
        //java.sql.Types里的值
        public int type;
        public String defaultValue;
        public String editor;

        public DataTypeBean(String value, String name, String sqlType, int dataLength, String javaType, String shortJavaType, int type, String defaultValue, String editor) {
            super(value, name);
            this.sqlType = sqlType;
            this.dataLength = dataLength;
            this.javaType = javaType;
            this.shortJavaType = shortJavaType;
            this.defaultValue = defaultValue;
            this.editor = editor;
            this.type = type;
        }

        public String getSqlTypeCreate() {
            if (dataLength > 0) return sqlType + "(" + dataLength + ")";
            return sqlType;
        }

    }

    /**
     * 数据类型定义，参见design_db.yaml配置
     */
    class DataType extends AbstractEnum<String, DataTypeBean> {
        public final static String TYPE_BOOL = "bool";
        public final static String TYPE_DATE = "date";
        public final static String TYPE_DATETIME = "datetime";

        public final static String JAVA_TYPE_INT = "int";
        public final static String JAVA_TYPE_LONG = "long";
        public final static String JAVA_TYPE_STRING = "String";
        public final static String JAVA_TYPE_BOOL = "boolean";

        public static DataType instance = new DataType();
        public static DataTypeBean ID = instance.addEnum("id", "ID", "bigint", 0, "long", "Long", Types.BIGINT, "", EditorType.INPUT.value);
        public static DataTypeBean CODE = instance.addEnum("code", "编码", "varchar", 32, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value);
        public static DataTypeBean NAME = instance.addEnum("name", "名称", "varchar", 100, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value);
        public static DataTypeBean REMARK = instance.addEnum("remark", "备注", "varchar", 255, "String", "Str", Types.VARCHAR, "", EditorType.INPUT.value);
        public static DataTypeBean TEXT = instance.addEnum("text", "大文本", "text", 0, "String", "Str", Types.CLOB, "", EditorType.TEXT.value);
        public static DataTypeBean LONG = instance.addEnum("long", "长整型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.INPUT.value);
        public static DataTypeBean INT = instance.addEnum("int", "整型", "int", 0, "int", "Int", Types.INTEGER, "0", EditorType.NUMBER.value);
        public static DataTypeBean SHORT = instance.addEnum("short", "短整型", "smallint", 0, "int", "Int", Types.SMALLINT, "0", EditorType.NUMBER.value);
        public static DataTypeBean BOOL = instance.addEnum("bool", "布尔型", "tinyint", 0, "boolean", "Bool", Types.TINYINT, "0", EditorType.SWITCH.value);
        public static DataTypeBean CURRENCY = instance.addEnum("currency", "金额型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.NUMBER.value);
        public static DataTypeBean DATE = instance.addEnum("date", "日期型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.DATE.value);
        public static DataTypeBean TIME = instance.addEnum("time", "时间型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.TIME.value);
        public static DataTypeBean DATETIME = instance.addEnum("datetime", "日期时间型", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.DATETIME.value);
        public static DataTypeBean POS = instance.addEnum("pos", "经纬度", "bigint", 0, "long", "Long", Types.BIGINT, "0", EditorType.NUMBER.value);

        @Override
        protected DataTypeBean buildBean(String value, String name) {
            return null;
        }

        public DataTypeBean addEnum(String value, String name, String sqlType, int dataLength, String javaType, String shortJavaType, int type, String defaultValue, String editor) {
            final DataTypeBean bean = new DataTypeBean(value, name, sqlType, dataLength, javaType, shortJavaType, type, defaultValue, editor);
            mapAll.put(value, bean);
            return bean;
        }

        @Override
        public DataTypeBean getByValue(String value) {
            if (value == null) return null;
            return super.getByValue(value.toLowerCase());
        }

        //根据数据库查询的metadata适配类型
        public static DataTypeBean getBySqlType(int sqlType, int precision, int scale) {
            for (DataTypeBean bean : instance.mapAll.values()) {
                if (bean.type != sqlType) continue;
                if (bean.dataLength == 0 || bean.dataLength == precision) return bean;
            }
            return REMARK;
        }

        public static Object getDataValue(String value, String fieldValue) {
            DataTypeBean dataType = instance.getByValue(value);
            if (dataType == null) return fieldValue;
            switch (dataType.javaType) {
                case JAVA_TYPE_LONG:
                    return NumberUtil.getLongIgnoreErr(fieldValue);
                case JAVA_TYPE_INT:
                    return NumberUtil.getIntIgnoreErr(fieldValue);
                case JAVA_TYPE_BOOL:
                    return NumberUtil.getBoolValue(fieldValue);
                default:
                    return fieldValue;
            }
        }
    }

    /**
     * 数据字段类型Bean
     */
    class IndexTypeBean extends AbstractEnum.StrEnumBean {
        public String fullName;

        public IndexTypeBean(String value, String name, String fullName) {
            super(value, name);
            this.fullName = fullName;
        }
    }

    class IndexType extends AbstractEnum<String, IndexTypeBean> {
        public static IndexType instance = new IndexType();
        public static IndexTypeBean PK = instance.addEnum("P", "主键", "prim-key");
        public static IndexTypeBean I = instance.addEnum("I", "一般索引", "");
        public static IndexTypeBean U = instance.addEnum("U", "唯一索引", "unique");

        @Override
        protected IndexTypeBean buildBean(String value, String name) {
            return null;
        }

        public IndexTypeBean addEnum(String value, String name, String fullName) {
            final IndexTypeBean bean = new IndexTypeBean(value, name, fullName);
            mapAll.put(value, bean);
            return bean;
        }
    }

    /**
     * 表类型
     */
    class TableType extends IntEnum {
        public static TableType instance = new TableType();

        public static AbstractEnum.IntEnumBean TYPE_GENERAL = instance.addEnum(0, "普通表");
        public static AbstractEnum.IntEnumBean TYPE_TREE = instance.addEnum(1, "树型表");
        public static AbstractEnum.IntEnumBean TYPE_CODE = instance.addEnum(2, "编码表");
        public static AbstractEnum.IntEnumBean TYPE_ABSTRACT = instance.addEnum(3, "虚拟抽象表");
        public static AbstractEnum.IntEnumBean TYPE_VIEW = instance.addEnum(4, "视图");
    }

    /**
     * 界面定义类型：：：控件/页面
     */
    class FormType extends IntEnum {
        public static FormType instance = new FormType();

        public static IntEnumBean PAGE = instance.addEnum(0, "页面");
        public static IntEnumBean WIDGET = instance.addEnum(1, "控件");
        public static IntEnumBean MODULE = instance.addEnum(2, "模块");
    }

    /**
     * 子页面类型：：：列表/编辑/详情
     */
    class PageType extends StrEnum {
        public static PageType instance = new PageType();
        public static StrEnumBean LIST = instance.addEnum("list", "列表");
        public static StrEnumBean CARD = instance.addEnum("card", "编辑");
        public static StrEnumBean VIEW = instance.addEnum("view", "详情");
    }

    /**
     * 控件类型：：：grid,tree,combotree,combogrid、custom
     */
    class WidgetType extends StrEnum {
        public static WidgetType instance = new WidgetType();

        public static StrEnumBean GRID = instance.addEnum("grid", "表格");
        public static StrEnumBean TREE = instance.addEnum("tree", "树");
        public static StrEnumBean COMBOGRID = instance.addEnum("combogrid", "下拉表格");
        public static StrEnumBean COMBOTREE = instance.addEnum("combotree", "下拉树");
        public static StrEnumBean CUSTOM = instance.addEnum("custom", "自定义");

        public static String getEditor(String type) {
            if (TREE.value.equals(type) || COMBOTREE.value.equals(type)) return EditorType.TREE.value;
            if (COMBOGRID.value.equals(type)) return EditorType.COMBO.value;
            return EditorType.INPUT.value;
        }
    }

    /**
     * 数据集类型：：：list-列表；form-表单；editList-编辑列表;tree;enum
     */
    class DatasetType extends StrEnum {
        public static DatasetType instance = new DatasetType();

        public static StrEnumBean LIST = instance.addEnum("list", "列表");
        public static StrEnumBean FORM = instance.addEnum("form", "表单");
        //        public static StrEnumBean ITEM = instance.addEnum("item", "子表编辑");
        public static StrEnumBean TREE = instance.addEnum("tree", "树");
//        public static StrEnumBean ENUM = instance.addEnum("enum", "枚举");
    }

    /**
     * 过滤条件类型：：：控件/参数/link/const
     */
    class FilterType extends StrEnum {
        public static FilterType instance = new FilterType();

        public static StrEnumBean INPUT = instance.addEnum("input", "输入");
        public static StrEnumBean PARAM = instance.addEnum("param", "参数");
        public static StrEnumBean LINK = instance.addEnum("link", "关联");
        public static StrEnumBean CONST = instance.addEnum("const", "常量");
        public static StrEnumBean DEPEND = instance.addEnum("depend", "依赖");
    }

    /**
     * 操作符类型：：：and/or/=/>=/<=/like/p
     */
    class OptType extends StrEnum {
        public static OptType instance = new OptType();

        public static StrEnumBean AND = instance.addEnum("and", "且");
        public static StrEnumBean OR = instance.addEnum("or", "或");

        public static StrEnumBean EQ = instance.addEnum("=", "等于");
        public static StrEnumBean NE = instance.addEnum("<>", "不等于");
        public static StrEnumBean GT = instance.addEnum(">", "大于");
        public static StrEnumBean GE = instance.addEnum(">=", "大于等于");
        public static StrEnumBean LT = instance.addEnum("<", "小于");
        public static StrEnumBean LE = instance.addEnum("<=", "小于等于");
        public static StrEnumBean BT = instance.addEnum("bt", "介于");
        public static StrEnumBean PLIKE = instance.addEnum("plike", "开始以");
        public static StrEnumBean LIKE = instance.addEnum("like", "包含");
        public static StrEnumBean IN = instance.addEnum("in", "在列表");
        public static StrEnumBean NOT_IN = instance.addEnum("not in", "不在列表");
        public static StrEnumBean IN_CHILD = instance.addEnum("inChild", "本级及下级");
    }

    //合计栏类型 "summary": "COUNT/SUM/AVG/MAX/MIN/其他为文本"
    class SummaryType extends StrEnum {
        public static SummaryType instance = new SummaryType();

        public static StrEnumBean COUNT = instance.addEnum("count", "计数");
        public static StrEnumBean SUM = instance.addEnum("sum", "求和");
        public static StrEnumBean AVG = instance.addEnum("avg", "均值");
        public static StrEnumBean MAX = instance.addEnum("max", "最大值");
        public static StrEnumBean MIN = instance.addEnum("min", "最小值");

        //是字符串
        public boolean isText(String v) {
            if (StringUtils.isEmpty(v)) return true;
            return !mapAll.containsKey(v.toLowerCase());
        }
    }

    /**
     * 模型
     */
    class ModelType extends StrEnum {
        public static ModelType instance = new ModelType();
        public static StrEnumBean LC_SINGLE = instance.addEnum("LC_SINGLE", "简单列表（含编辑弹窗）");
        public static StrEnumBean LC_NORMAL = instance.addEnum("LC_NORMAL", "普通列表（含编辑卡片）");
        public static StrEnumBean LC_LT = instance.addEnum("LC_LT", "左树-列表（含编辑卡片）");
        public static StrEnumBean LC_LT_2 = instance.addEnum("LC_LT_2", "左树-列表（含编辑弹窗）");
        public static StrEnumBean LC_MS = instance.addEnum("LC_MS", "普通主子列表（含编辑卡片）");
        public static StrEnumBean LC_LT_MS = instance.addEnum("LC_LT_MS", "左树-主子列表（含编辑卡片）");
        public static StrEnumBean LC_LC_1 = instance.addEnum("LC_LC_1", "左列表-右列表（含编辑弹窗、左列表可编辑）");
        public static StrEnumBean LC_LC_2 = instance.addEnum("LC_LC_2", "左列表-右列表（含编辑弹窗、左列表不可编辑）");
        public static StrEnumBean EMPTY = instance.addEnum("EMPTY", "自定义模型");
        public static StrEnumBean FLOW_SINGLE = instance.addEnum("FLOW_SINGLE", "普通列表（含编辑卡片、工作流）");
        public static StrEnumBean FLOW_LC_LT = instance.addEnum("FLOW_LC_LT", "左树-列表（含编辑卡片、工作流）");
        public static StrEnumBean FLOW_LC_LC_1 = instance.addEnum("FLOW_LC_LC_1", "左列表-右列表（含编辑卡片、工作流、左列表可编辑）");
        public static StrEnumBean FLOW_LC_LC_2 = instance.addEnum("FLOW_LC_LC_2", "左列表-右列表（含编辑卡片、工作流、左列表不可编辑）");
        public static StrEnumBean FLOW_LC_MS = instance.addEnum("FLOW_LC_MS", "普通主子列表（含编辑卡片、工作流）");
        public static StrEnumBean FLOW_LT_MS = instance.addEnum("FLOW_LT_MS", "左树-主子列表（含编辑卡片、工作流）");
    }

    // 用户等级
    class UserLevel extends IntEnum {
        public static UserLevel instance = new UserLevel();
        public static IntEnumBean inner = instance.addEnum(102100, "内部用户");
        public static IntEnumBean outer = instance.addEnum(102101, "外部用户");
        public static IntEnumBean pub = instance.addEnum(102102, "公众用户");
    }

    // 数据库操作类型
    class DbEventType extends StrEnum {
        public static DbEventType instance = new DbEventType();
        public static StrEnumBean CREATE = instance.addEnum("CREATE", "创建表");
        public static StrEnumBean ALTER = instance.addEnum("ALTER", "修改表");
        public static StrEnumBean INSERT = instance.addEnum("INSERT", "新增");
        public static StrEnumBean UPDATE = instance.addEnum("UPDATE", "修改");
        public static StrEnumBean DELETE = instance.addEnum("DELETE", "删除");
    }

    /**
     * 字段编辑类型
     */
    class DbType extends StrEnum {
        public static DbType instance = new DbType();
        public static StrEnumBean MYSQL = instance.addEnum("mysql", "MYSQL");
        public static StrEnumBean ORACLE = instance.addEnum("oracle", "ORACLE");
        public static StrEnumBean KBSQL = instance.addEnum("kbsql", "人大金仓V8");
        public static StrEnumBean DMSQL = instance.addEnum("dmsql", "达梦数据库");
    }
}
