package com.cool.bang.modules.generate.utils;

import com.cool.bang.common.constant.GenConstant;
import com.cool.bang.common.tools.secure.SecurityUtil;
import com.cool.bang.common.tools.string.StringUtil;
import com.cool.bang.modules.generate.config.GenerateConfig;
import com.cool.bang.modules.generate.domain.po.TableColumnInfo;
import com.cool.bang.modules.generate.domain.po.TableInfo;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;

/**
 * Generate Util (代码生成工具类)
 *
 * @author PeiZhi Guo
 * 2021-4-13 13:58
 */
public class GenUtil {

    /**
     * 初始化表信息
     */
    public static void initTable(TableInfo tableInfo) {
        if (StringUtils.isEmpty(tableInfo.getPackageName())) {
            tableInfo.setPackageName(GenerateConfig.getPackageName());
        }
        if (StringUtils.isEmpty(tableInfo.getModuleName())) {
            tableInfo.setModuleName(GenerateConfig.getModuleName());
        }
        if (StringUtils.isEmpty(tableInfo.getBusinessName())) {
            tableInfo.setBusinessName(getBusinessName(tableInfo.getTableName()));
        }
        tableInfo.setClassName(convertClassName(tableInfo.getTableName()));
        tableInfo.setFunctionName(replaceText(tableInfo.getTableComment()));
        tableInfo.setFunctionAuthor(GenerateConfig.getAuthor());
    }

    /**
     * 初始化表列信息
     */
    public static void initTableColumn(TableColumnInfo column, TableInfo tableInfo) {
        String dataType = getDbType(column.getColumnType());
        String columnName = column.getColumnName();

        column.setTableId(tableInfo.getId());
        column.setCreateBy(SecurityUtil.getCurrentUser().getId());

        // 设置java字段名
        column.setJavaField(StringUtil.toCamelCase(columnName));

        // 判断字段类型
        // 如果是字符串类型
        if (arraysContains(GenConstant.COLUMN_TYPE_STR, dataType)) {
            column.setJavaType(GenConstant.TYPE_STRING);
            Integer columnLength = getColumnLength(column.getColumnType());
            String htmlType = columnLength >= 500 ? GenConstant.HTML_TEXTAREA : GenConstant.HTML_INPUT;
            column.setHtmlType(htmlType);
            column.setJdbcType(dataType.toUpperCase());
        }
        // 如果是时间类型
        else if (arraysContains(GenConstant.COLUMN_TYPE_TIME, dataType)) {
            column.setJavaType(GenConstant.TYPE_DATE);
            column.setHtmlType(GenConstant.HTML_DATETIME);
            if (dataType.equals("datetime")) {
                column.setJdbcType("TIMESTAMP");
            } else {
                column.setJdbcType(dataType.toUpperCase());
            }
        }
        // 如果是数值类型
        else if (arraysContains(GenConstant.COLUMN_TYPE_NUMBER, dataType)) {
            column.setHtmlType(GenConstant.HTML_INPUT);
            // 如果是浮点型
            String[] str = StringUtil.split(StringUtil.substringBetween(column.getColumnType(), "(", ")"), ",");
            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
                column.setJavaType(GenConstant.TYPE_BIG_DECIMAL);
            // 如果是整形
            } else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 11) {
                column.setJavaType(GenConstant.TYPE_INTEGER);
            // 长整形
            } else {
                column.setJavaType(GenConstant.TYPE_LONG);
            }
            if (dataType.equals("int") || dataType.equals("number")) {
                column.setJdbcType("INTEGER");
            } else {
                column.setJdbcType(dataType.toUpperCase());
            }
        }

        // 插入字段（默认所有字段都需要插入）
        column.setIsInsert(GenConstant.REQUIRE);

        // 编辑字段
        if (arraysContains(GenConstant.COLUMN_NAME_NOT_EDIT, columnName)) {
            column.setIsEdit(GenConstant.NO_REQUIRE);
        } else if (null == column.getIsEdit()) {
            column.setIsEdit(GenConstant.REQUIRE);
        }
        // 列表字段
        if (arraysContains(GenConstant.COLUMN_NAME_NOT_LIST, columnName)) {
            column.setIsList(GenConstant.NO_REQUIRE);
        } else if (null == column.getIsList()) {
            column.setIsList(GenConstant.REQUIRE);
        }
        // 查询字段
        if (arraysContains(GenConstant.COLUMN_NAME_NOT_QUERY, columnName)) {
            column.setIsQuery(GenConstant.NO_REQUIRE);
        } else if (null == column.getIsQuery()) {
            column.setIsQuery(GenConstant.REQUIRE);
        }
        // 查询字段类型
        if (StringUtil.endsWithIgnoreCase(columnName, "name")) {
            column.setQueryType(GenConstant.QUERY_LIKE);
        } else {
            column.setQueryType(GenConstant.QUERY_EQ);
        }
        // 状态字段设置单选框
        if (StringUtil.endsWithIgnoreCase(columnName, "status")) {
            column.setHtmlType(GenConstant.HTML_RADIO);
        }
        // 类型&性别字段设置下拉框
        else if (StringUtil.endsWithIgnoreCase(columnName, "type")
                || StringUtil.endsWithIgnoreCase(columnName, "sex")) {
            column.setHtmlType(GenConstant.HTML_SELECT);
        }
        // 文件字段设置上传控件
        else if (StringUtil.endsWithIgnoreCase(columnName, "file")) {
            column.setHtmlType(GenConstant.HTML_UPLOAD);
        }
    }

    /**
     * 校验数组是否包含指定值
     *
     * Param arr
     * Param targetValue
     * Return
     */
    private static boolean arraysContains(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }

    /**
     * 表名称转换 (java类名)
     *
     * Param tableName
     * Return String
     */
    private static String convertClassName(String tableName) {
        boolean autoRemovePre = GenerateConfig.isAutoRemovePre();
        String tablePrefix = GenerateConfig.getTablePrefix();
        if (autoRemovePre && StringUtil.isNotEmpty(tablePrefix)) {
            String[] searchList = StringUtil.split(tablePrefix, ",");
            tableName = replaceFirst(tableName, searchList);
        }
        return StringUtil.convertToCamelCase(tableName);
    }

    /**
     * 截取包名的最后一个 (".") 后面的名称为模块名
     *
     * Param packageName
     * Return String
     */
    private static String getModuleName(String packageName) {
        int lastIndex = packageName.lastIndexOf(".");
        int nameLength = packageName.length();
        return StringUtil.substring(packageName, lastIndex + 1, nameLength);
    }

    /**
     * 截取包名的最后一个 ("_") 后面的名称为业务名
     *
     * Param tableName
     * Return
     */
    private static String getBusinessName(String tableName) {
        int lastIndex = tableName.lastIndexOf("_");
        int nameLength = tableName.length();
        return StringUtil.substring(tableName, lastIndex + 1, nameLength);
    }


    /**
     * 关键字替换 (正则匹配)
     *
     * Param text
     * Return
     */
    public static String replaceText(String text) {
        return RegExUtils.replaceAll(text, "(?:表)", "");
    }

    /**
     * 截取数据库字段类型参数 (比如：varchar(32) 截取为 varchar)
     *
     * Param columnType
     * Return
     */
    private static String getDbType(String columnType) {
        if (StringUtil.indexOf(columnType, "(") > 0) {
            return StringUtil.substringBefore(columnType, "(");
        } else {
            return columnType;
        }
    }

    /**
     * 获取字段长度
     *
     * Param columnType
     * return
     */
    private static Integer getColumnLength(String columnType) {
        if (StringUtil.indexOf(columnType, "(") > 0) {
            String length = StringUtil.substringBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        } else {
            return 0;
        }
    }

    /**
     * 批量替换前缀
     *
     * Param replacement 替换值
     * Param searchList  替换列表
     * Return
     */
    private static String replaceFirst(String replacement, String[] searchList) {
        String text = replacement;
        for (String searchString : searchList) {
            if (replacement.startsWith(searchString)) {
                text = replacement.replaceFirst(searchString, "");
                break;
            }
        }
        return text;
    }

}
