package com.engine.salary.formlua.util;

import com.alibaba.fastjson.JSONObject;
import com.engine.salary.formlua.entity.parameter.DataType;
import com.engine.salary.formlua.entity.parameter.IllegalList;
import com.engine.salary.formlua.entity.parameter.ParamType;
import com.engine.salary.formlua.entity.standard.execute.FixFieldType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class ExcelParamUtil {
    protected static final Logger logger = LoggerFactory.getLogger(ExcelParamUtil.class);
    public final static String[] NUMBERFIELD = new String[]{"NumberComponent", "Money", "Monitor", "Raty", "ProgressBar", FixFieldType.Num.toString(), DataType.NUMBER};
    public final static String[] DATEFIELD = new String[]{"DateComponent", "DateInterval", "TimeComponent", DataType.DATE};
    public final static String[] TEXTFIELD = new String[]{"Text", "TextArea", "Email", "Phone", "Mobile", "IDCard", "FileComponent", "SerialNumber", "PositionComponent", "Paragraph", FixFieldType.Text.toString(), DataType.STRING};
    public final static String[] SELECTFIELD = new String[]{"ImageComponent", "RadioBox", "CheckBox", "Select", "ComboSelect", "ImageRadioBox", "ImageCheckBox", "TreeSelect", "MatrixComponent", FixFieldType.Select.toString(), "option", "employee", "department", "subcompany", "operator", DataType.OPTION};
    public final static String[] DATASOURCEFIELD = new String[]{"Employee", "Department", "Mainline", "Task", "Document", "Workflow", "AgendaComponent", "FormComponent", "CustomerComponent", "ClueComponent", "Subcompany",
            "OrderComponent", "ContactComponent", "ChanceComponent", "ProductionComponent", "ContractComponent", "ActivityComponent", "WorkreportComponent", "CompetitorComponent", "KpiFlowComponent", "Ebuilder", "QuoteComponent", "AttendComponent", "DataSource",
            FixFieldType.Department.toString(), FixFieldType.Employee.toString()};

    private static String[] funcArray = IllegalList.getInstance().getNameIllegalArray();
    private final static String[] NUMBERCOMPONENTS = new String[]{"NumberComponent", "Money", "Raty", "ProgressBar", "Monitor"};
    private static String[] numberTypes = new String[]{"Integer", "integer", "Long", "Double", "Float", "float", "int", "double", "long", "float", "bigdecimal", "BigDecimal"};
    public final static String CHECKLEVEL_NULL = "NULL";
    public final static String CHECKLEVEL_STRING = "STRING";

    /**
     * 自定义脚本生成调用的逻辑
     *
     * @param funcString
     * @return
     */
    public static String initFunc(String funcString) {
        if (StringUtils.isEmpty(funcString)) {
            return funcString;
        }
        int startIdx = funcString.indexOf("(");
        int endIdx = funcString.indexOf(")");
        int funcIdx = funcString.indexOf("function");
        if (startIdx == -1) {
            throw new RuntimeException("【语法错误】缺少左括号(");
        } else if (endIdx == -1) {
            throw new RuntimeException("【语法错误】缺少右括号)");
        } else if (funcIdx == -1) {
            throw new RuntimeException("【语法错误】缺少function关键字");
        }
        String funcName = funcString.substring(funcIdx + 8, startIdx).trim();
        String paramStr = funcString.substring(startIdx + 1, endIdx);
        if (paramStr.trim().equalsIgnoreCase("")) {
            funcString += funcName + "();";
            return funcString;
        }
        String[] paramStrArray = paramStr.split(",");
        logger.info("总参数个数：" + paramStrArray.length);
        String paramNames = "";
        for (int i = 0; i < paramStrArray.length; i++) {
            String paramName = paramStrArray[i].trim();
            if (paramNames.equalsIgnoreCase("")) {
                paramNames = paramName;
            } else {
                paramNames += "," + paramName;
            }

        }
        funcString += funcName + "(" + paramNames + ");";
        return funcString;
    }

    public static String initFuncOnly(String funcString) {
        if (StringUtils.isEmpty(funcString)) {
            return funcString;
        }
        int startIdx = funcString.indexOf("(");
        int endIdx = funcString.indexOf(")");
        int funcIdx = funcString.indexOf("function");
        if (startIdx == -1) {
            throw new RuntimeException("【语法错误】缺少左括号(");
        } else if (endIdx == -1) {
            throw new RuntimeException("【语法错误】缺少右括号)");
        } else if (funcIdx == -1) {
            throw new RuntimeException("【语法错误】缺少function关键字");
        }
        String funcName = funcString.substring(funcIdx + 8, startIdx).trim();
        String paramStr = funcString.substring(startIdx + 1, endIdx);
        if (paramStr.trim().equalsIgnoreCase("")) {
            funcString += funcName + "();";
            return funcString;
        }
        String[] paramStrArray = paramStr.split(",");
        logger.info("总参数个数：" + paramStrArray.length);
        String paramNames = "";
        for (int i = 0; i < paramStrArray.length; i++) {
            String paramName = paramStrArray[i].trim();
            paramName = paramName.replaceAll("int|String|Double|Float|float|double|Integer|boolean|Boolean|Object|object", "").trim();
            if (paramNames.equalsIgnoreCase("")) {
                paramNames = paramName;
            } else {
                paramNames += "," + paramName;
            }

        }
        String func = funcName + "(" + paramNames + ");";
        return func;
    }


    /**
     * 判断控件所属的数据类型
     *
     * @param compnentKey FormField中的ComponentKey
     * @return
     */
    public static String findType(String compnentKey) {
        List<String> numberList = Arrays.asList(NUMBERFIELD);
        List<String> textList = Arrays.asList(TEXTFIELD);
        List<String> selectList = Arrays.asList(SELECTFIELD);
        List<String> dataSourceList = Arrays.asList(DATASOURCEFIELD);
        List<String> dateList = Arrays.asList(DATEFIELD);
        if (numberList.contains(compnentKey)) {
            return DataType.NUMBER;
        } else if (textList.contains(compnentKey)) {
            return DataType.STRING;
        } else if (dateList.contains(compnentKey)) {
            return DataType.STRING;
        } else if (selectList.contains(compnentKey)) {
            return DataType.OPTION;
        } else if (dataSourceList.contains(compnentKey)) {
            return DataType.OPTION;
        } else {
            return "";
        }
    }

    public static String findDataType(String compnentKey) {
        List<String> numberList = Arrays.asList(NUMBERFIELD);
        List<String> textList = Arrays.asList(TEXTFIELD);
        List<String> selectList = Arrays.asList(SELECTFIELD);
        List<String> dataSourceList = Arrays.asList(DATASOURCEFIELD);
        List<String> dateList = Arrays.asList(DATEFIELD);
        if (numberList.contains(compnentKey)) {
            return DataType.NUMBER;
        } else if (textList.contains(compnentKey)) {
            return DataType.STRING;
        } else if (dateList.contains(compnentKey)) {
            return DataType.STRING;
        } else if (selectList.contains(compnentKey)) {
            return DataType.OPTION;
        } else if (dataSourceList.contains(compnentKey)) {
            return DataType.OPTION;
        } else {
            return DataType.STRING;
        }
    }

    public static String findTestDataType(String compnentKey) {
        List<String> numberList = Arrays.asList(NUMBERFIELD);
        List<String> textList = Arrays.asList(TEXTFIELD);
        List<String> selectList = Arrays.asList(SELECTFIELD);
        List<String> dataSourceList = Arrays.asList(DATASOURCEFIELD);
        List<String> dateList = Arrays.asList(DATEFIELD);
        if (numberList.contains(compnentKey)) {
            return DataType.NUMBER;
        } else if (textList.contains(compnentKey)) {
            return DataType.STRING;
        } else if (dateList.contains(compnentKey)) {
            return DataType.DATE;
        } else if (selectList.contains(compnentKey)) {
            return DataType.OPTION;
        } else if (dataSourceList.contains(compnentKey)) {
            return DataType.OPTION;
        } else {
            return DataType.STRING;
        }
    }

    /**
     * 判断变量是否为空
     *
     * @param objects
     * @return
     */
    public static boolean checkIsNull(Object... objects) {
        String checkLevel = objects[objects.length - 1].toString();
        List<Object> formulavars = new ArrayList<>();
        for (int i = 0; i < objects.length; i++) {
            Object object = objects[i];
            if (object instanceof Array) {
                Object[] subArray = (Object[]) object;
                for (int j = 0; j < subArray.length; j++) {
                    formulavars.add(subArray[j]);
                }
            } else {
                formulavars.add(object);
            }
        }

        for (Object object : formulavars) {
            switch (checkLevel) {
                case CHECKLEVEL_NULL:
                    if (null == object) {
                        return true;
                    }
                    break;
                case CHECKLEVEL_STRING:
                    if (null == object) {
                        return true;
                    }
                    if (object instanceof String || object instanceof Character) {
                        if (object.toString().trim().equals("")) {
                            return true;
                        }
                    }
                    break;
            }

        }
        return false;
    }

    /**
     * 替换所有中文参数为Key
     *
     * @param sql
     * @param replaceArray
     * @return
     */
    public static String replaceAllParam(String sql, String[] replaceArray) {
        String partternStr = "\\{.+?\\}{1}?";
        Pattern pt = Pattern.compile(partternStr);
        Matcher matcher = pt.matcher(sql);

        int loop = 0;
        while (matcher.find()) {
            String matherString = matcher.group();
            matherString = matherString.replaceAll("(\\{|\\})", "");
            String replaceStr = replaceArray[loop];
            sql = sql.replaceFirst(matherString, replaceStr);
            loop++;
        }
        return sql;
    }

    /**
     * 找到聚合函数的条件参数
     *
     * @param sql
     * @return
     */
    public static List<String> findAggParam(String sql) {
        List<String> list = new LinkedList<>();
        String partternStr = "(COUNT|SUM|MIN|MAX|AVG){1}\\(+.+?\\)+";
        Pattern pt = Pattern.compile(partternStr);
        Matcher matcher = pt.matcher(sql);
        while (matcher.find()) {
            String aggStr = matcher.group();
            aggStr = aggStr.replaceAll("(COUNT|SUM|MIN|MAX|AVG){1}", "");
            String[] paramArray = aggStr.split(",", 2);
            if (paramArray.length == 2) {
                String cndParam = paramArray[1];
                cndParam = cndParam.substring(0, cndParam.length() - 1);
                list.add(cndParam);
            }
        }


        return list;
    }

    /**
     * 替换聚合函数的条件参数，一般是从规则库返回过来的条件语句
     *
     * @param sql
     * @param replaceArray
     * @return
     */
    public static String replaceAggParam(String sql, List<String> replaceArray) {
        String partternStr = "(COUNT|SUM|MIN|MAX|AVG){1}\\(.+?\\){1}?";
        Pattern pt = Pattern.compile(partternStr);
        Matcher matcher = pt.matcher(sql);
        String paramPattStr = "\\(.+?\\){1}?";
        Pattern ppatt = Pattern.compile(paramPattStr);
        int loop = 0;
        while (matcher.find()) {
            String matherString = matcher.group();
            String[] paramStrArray = matherString.replaceAll("(\\(|\\))", "").split(",");
            String newmatherString = matherString.replace(paramStrArray[1], "{" + replaceArray.get(loop) + "}");
            sql = sql.replace(matherString, newmatherString);
            loop++;
        }
        return sql;
    }


//    public static void checkParamArrayDataType(List<FormulaVar> formulavars) {
//        for (FormulaVar formulaVar : formulavars) {
//            if (formulaVar.getComponentKey() != null && !formulaVar.getComponentKey().equals("")) {
//                String componentKey = formulaVar.getComponentKey();
//                Arrays.sort(NUMBERCOMPONENTS);
//                int searchIdx = Arrays.binarySearch(NUMBERCOMPONENTS, componentKey);
//                if (searchIdx >= 0) {
//                    formulaVar.setFieldType("Number");
//                }
//                Arrays.sort(ReturnType.CHECK_TYPE);
//                if (Arrays.binarySearch(ReturnType.CHECK_TYPE, componentKey) >= 0) {
//                    formulaVar.setFieldType("String");
//                }
//                if (formulaVar.getOptionId() != null) {
//                    formulaVar.setFieldType("String");
//                }
//            }
//
//        }
//    }


    /**
     * 替换语句中的参数为参数列表中的Key
     *
     * @param sql
     * @param formulaVars
     * @return
     */
//    public static String replaceAllParam(String sql, List<FormulaVar> formulaVars) {
//        if (null == formulaVars) {
//            return sql;
//        }
//        //正则表达式匹配所有用 { } 括号包起来的变量，然后跟参数列表中的参数一一对应做替换
//        String partternStr = "\\{.+?\\}{1}?";
//        Pattern pt = Pattern.compile(partternStr);
//        Matcher matcher = pt.matcher(sql);
//
//        int loop = 0;
//        //替换逻辑
//        while (matcher.find()) {
//            String matherString = matcher.group();
//            //替换特殊字符
//            matherString = matherString.replace("{", "");
//            matherString = matherString.replace("}", "");
//            matherString = matherString.replace("(", "\\(");
//            matherString = matherString.replace(")", "\\)");
//            matherString = matherString.replaceAll("\\+", "\\\\+");
//            matherString = matherString.replaceAll("\\-", "\\\\-");
//            matherString = matherString.replaceAll("\\*", "\\\\*");
//            matherString = matherString.replaceAll("\\/", "\\\\/");
//            if (formulaVars != null && loop < formulaVars.size()) {
//                FormulaVar formulaVar = formulaVars.get(loop);
//                //如果参数异常，获取Key为空，根据数据中相应的值做判断，判断是什么类型的控件
//                if (formulaVar.getKey() == null) {
//                    //表格类型变量替换
//                    if (formulaVar.getFormId() != null && formulaVar.getFieldId() == null) {
//                        sql = sql.replaceFirst(matherString, formulaVar.getFormId().toString());
//                        //普通变量的替换
//                    } else if (formulaVar.getFormId() != null && formulaVar.getFieldId() != null && formulaVar.getOptionId() == null) {
//                        sql = sql.replaceFirst(matherString, formulaVar.getFieldId().toString());
//                    } else if (formulaVar.getOptionId() != null) {
//                        //选项型变量的替换是用optionID
//                        sql = sql.replaceFirst(matherString, formulaVar.getOptionId().toString());
//                    } else {
//                        sql = sql.replaceFirst(matherString, formulaVar.getOptionId().toString());
//                    }
//                } else {
//                    //普通变量的替换是用Key
//                    sql = sql.replaceFirst(matherString, formulaVar.getKey());
//                }
//                loop++;
//            }
//        }
//
//        ExcelParamUtil.findAggParam(sql);
//
//        if (loop != formulaVars.size()) {
//            throw new RuntimeException("参数列表与执行语句不一致");
//        }
//        return sql;
//    }


    /**
     * 替换参数
     *
     * @param sourceString
     * @return
     */
    public static String replaceParam(String sourceString) {
        String formatStr = sourceString.replace("&gt;", ">")
                .replace("&lt;", "<");
        return formatStr;
    }

    /**
     * 过滤 除了数字外的其他参数类型
     *
     * @param param
     * @return
     */
    public static boolean inNumber(Object param) {
        boolean r = false;
        Class[] paramClasses = new Class[]{Integer.class, Double.class, Float.class, Long.class, Short.class};
        for (int i = 0; i < paramClasses.length; i++) {
            if ((param.equals(paramClasses[i].getName())) || (param.equals(getParamType(paramClasses[i].getName())))) {
                r = true;
                break;
            }
        }
        return r;
    }

    /**
     * 获取参数名
     *
     * @param typeAllName
     * @return
     */
    public static String getParamType(String typeAllName) {
        int fnameIdx = typeAllName.lastIndexOf(".");
        typeAllName = typeAllName.substring(fnameIdx + 1);
        List<String> numberList = Arrays.asList(numberTypes);
        if (typeAllName.equals("Character")) {
            return "String";
        } else if (numberList.contains(typeAllName.toLowerCase())) {
            return "Number";
        }
        return typeAllName;
    }

    /**
     * 获取参数类型
     *
     * @param
     * @return
     */
    public static String getParamType(Object dataType) {
        if (dataType instanceof DataType) {
            DataType data = (DataType) dataType;
            String filedType = data.getDataType();
            filedType = filedType.toLowerCase();

            switch (filedType) {
                case "number":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "string":
                    filedType = ParamType.STRING.getName();
                    break;
                case "boolean":
                    filedType = ParamType.BOOLEAN.getName();
                    break;
                case "select":
                    filedType = ParamType.STRING.getName();
                    break;
                case "text":
                    filedType = ParamType.STRING.getName();
                    break;
                case "employee":
                    filedType = ParamType.STRING.getName();
                    break;
                case "department":
                    filedType = ParamType.STRING.getName();
                    break;
                case "integer":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "double":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "float":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "int":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "long":
                    filedType = ParamType.DOUBLE.getName();
                    break;
                case "bigdecimal":
                    filedType = ParamType.DOUBLE.getName();
                    break;

            }
            return filedType;
        } else {
            return getParamType(dataType.getClass().getName());
        }
    }

    /**
     * 从DataType中获取值
     *
     * @param object
     * @return
     */
    public static List getParamContent(Object object) {
        List<Object> dataList = new ArrayList<>();
        if (object != null) {
            if (object instanceof DataType) {
                DataType data = (DataType) object;
                dataList.add(getDataTypeContent(data));
                return dataList;
            } else if (object instanceof List) {
                List<Object> sourceDataList = (List) object;
                for (Object paramObj : sourceDataList) {
                    if (paramObj instanceof DataType) {
                        DataType pramDataType = (DataType) paramObj;
                        dataList.add(pramDataType.getContent());
                    } else {
                        dataList.add(paramObj);
                    }
                }
                return dataList;
            } else if (object instanceof Object[]) {
                Object[] sourceDataList = (Object[]) object;
                for (Object paramObj : sourceDataList) {
                    if (paramObj instanceof DataType) {
                        DataType pramDataType = (DataType) paramObj;
                        dataList.add(pramDataType.getContent());
                    } else {
                        dataList.add(paramObj);
                    }
                }
                return dataList;
            } else {
                dataList.add(object);
                return dataList;
            }
        }
        dataList.add(object);
        return dataList;
    }

    public static Object getDataTypeContent(DataType dataType) {
        String properType = "";
        Object content = null;
        if (StringUtils.isNotEmpty(dataType.getComponentKey())) {
            properType = dataType.getComponentKey();
        } else if (StringUtils.isNotEmpty(dataType.getDataType())) {
            properType = dataType.getDataType();
        }
        switch (findType(properType)) {
            case DataType.NUMBER:
            case DataType.STRING:
            case DataType.DATE:
                content = dataType.getContent();
                break;
            case DataType.OPTION:
                content = dataType.getContent();
                break;
        }
        return content;
    }

    /**
     * 获取JSON的content内容
     *
     * @param object
     * @return
     */
    public static Object getParamContent(Object object, String funcType) {
        Object result = null;
        if (object instanceof DataType) {
            DataType dataType = (DataType) object;
            switch (dataType.getDataType()) {
                case DataType.DATE:
                    if (dataType.getContent() == null || dataType.getContent().equals("")) {
                        return "";
                    }
                    String format = DateUtil.buildFormat(dataType.getContent().toString());
                    SimpleDateFormat formatter = new SimpleDateFormat(format);
                    try {
                        Date date = formatter.parse(dataType.getContent().toString());
                        result = funcType.equalsIgnoreCase("string") ? dataType.getContent() : date.getTime();
                    } catch (ParseException e) {
                        logger.error("err", e);
                    }
                    break;
                case DataType.NUMBER:
                    if (null == dataType.getContent() || dataType.getContent().equals("")) {
                        return 0;
                    }
                    if (funcType.equalsIgnoreCase("string")) {
                        result = dataType.getContent();

                    } else {
                        if (!RegularUtil.isNumber(dataType.getContent())) {
                            return 0;
                        }
                        if (dataType.getContent().toString().indexOf(".") >= 0) {
//							result=Double.parseDouble(dataType.getContent().toString());
                            result = new BigDecimal(dataType.getContent().toString());
                        } else if (dataType.getContent().toString().length() <= 9) {
                            result = Integer.parseInt(dataType.getContent().toString());
                        } else {
                            result = Long.parseLong(dataType.getContent().toString());
                        }
                    }
                    break;
                case DataType.STRING:
                    if (null == dataType.getContent()) {
                        result = "";
                    } else {
                        result = dataType.getContent().toString().trim();
                    }

                    break;
                case DataType.OPTION:
                    if (funcType.equalsIgnoreCase("string")) {
                        if (StringUtils.isNotEmpty(dataType.getOptionContent())) {
                            result = dataType.getOptionContent();
                        } else {
                            result = "";
                        }

                    } else {
                        result = dataType.getContent();
                    }
                    break;
                case DataType.BOOL:
                    result = dataType.getContent();
                    break;
                default:
                    if (dataType.getContent() == null) {
                        return "";
                    }
                    result = dataType.getContent().toString();
                    break;
            }
        } else if (object instanceof Date) {
            Date date = (Date) object;
            result = date.getTime();
        } else {
            if (funcType.equalsIgnoreCase(DataType.BOOL)) {
                result = object == null ? false : object;
            } else if (object instanceof Boolean) {
                result = object;
            } else if (object instanceof Integer || object instanceof Double || object instanceof Long || object instanceof BigDecimal) {
                result = object;
            } else {
                result = object == null ? "" : object + "";
            }

        }
        return result;
    }

    /**
     * 获取参数的数据类型，从DataType中获取或者直接获取
     *
     * @param object
     * @return
     */
    public static String checkParamType(Object object) {
        String typeName = null;
        if (object instanceof DataType) {
            DataType dataType = (DataType) object;
            typeName = dataType.getDataType();
        } else {
            typeName = ExcelParamUtil.getParamType(object.getClass().getName());
        }
        return typeName;
    }

//    /**
//     * 运行公式时的参数设置
//     *
//     * @param formulavars
//     * @param expressMap
//     * @return
//     */
//    public static Map<String, Object> buildParam(List<FormulaVar> formulavars, Map<String, Object> expressMap) {
//        checkParamArrayDataType(formulavars);//检查控件类型，设置相应控件对应的数据类型
//        for (FormulaVar formulaVar : formulavars) {
//            DataType dataType = new DataType();
//            String key = null;
//            if (formulaVar.getFormId() != null && formulaVar.getFieldId() == null) {
//                key = "form" + formulaVar.getFormId();
//            } else if (formulaVar.getFieldId() != null && formulaVar.getOptionId() == null) {
//                String fieldId = formulaVar.getFieldId().toString();
//                key = "field" + fieldId;
//                dataType.setFieldId(fieldId);
//            } else if (formulaVar.getOptionId() != null) {
//                key = "option" + formulaVar.getOptionId();
//                dataType.setContent(formulaVar.getOptionId());
//            } else {
//                key = "option" + formulaVar.getOptionId();
//            }
//
//            Arrays.sort(funcArray);
//            int sidx = Arrays.binarySearch(funcArray, key);
//            if (sidx >= 0) {
//                throw new RuntimeException("变量名非法");
//            }
//            if (formulaVar.getOptionId() != null) {
//                dataType.setDataType(DataType.OPTION);
//            }
//            if (expressMap.containsKey(key)) {
//                String newKey = ExcelParamUtil.randomNumber() + "_" + key;
//                expressMap.put(newKey, dataType);
//                formulaVar.setKey(newKey);
//            } else {
//                expressMap.put(key, dataType);
//            }
//        }
//
//        return expressMap;
//    }
//
//    /***
//     * 验证函数时构建参数设置参数值
//     * 把FormulaVar类型的参数封装成DataType类型参数
//     * @param formulavars 入参类型
//     * @param expressMap 返回Map
//     * @return
//     */
//    public static Map buildLocalParam(List<FormulaVar> formulavars, Map<String, Object> expressMap, DataCollectionEmployee employee) {
//
//        checkParamArrayDataType(formulavars);//检查控件类型，设置相应控件对应的数据类型
//        for (FormulaVar formulaVar : formulavars) {
//            DataType dataType = new DataType();
//            dataType.setScore(0d);
//            dataType.setName((null == formulaVar.getName() || formulaVar.getName().equals("")) ? formulaVar.getParent() : formulaVar.getName());
//            dataType.setFieldId(formulaVar.getFieldId() != null ? formulaVar.getFieldId().toString() : null);
//            String key = null;
//            if (formulaVar.getModule() != null && !formulaVar.getModule().equals("")) {
//                try {
//                    dataType.setModule(formulaVar.getModule());
//                } catch (IllegalArgumentException e) {
//                    logger.error("err", e);
//                    dataType.setModule(formulaVar.getModule());
//                }
//            }
//            dataType.setFormId(formulaVar.getFormId() != null ? Long.parseLong(formulaVar.getFormId()) : null);
//            if (formulaVar.getName() != null && formulaVar.getName().equals("当前操作人")) {
//                key = formulaVar.getKey();
//                formulaVar.setContent(employee.getUserId().toString());
//                dataType.setContent(formulaVar.getContent());
//                dataType.setText(formulaVar.getContent());
//                dataType.setDataType(DataType.OPTION);
//            } else {
//                if (formulaVar.getFormId() != null && formulaVar.getFieldId() == null && formulaVar.getOptionId() == null) {
//                    key = "form" + formulaVar.getFormId().toString();
//                    ThreadLocalData threadLocalData = new ThreadLocalData();
//                    threadLocalData.setEmployee(employee);
//                    threadLocalData.setModuleSource(ModuleSource.biaoge);
//                    ParamContext.get().setValue(formulaVar.getFormId().toString(), threadLocalData);
//                } else if (formulaVar.getFieldId() != null && formulaVar.getOptionId() == null) {
//                    String fieldId = formulaVar.getFieldId().toString();
//                    key = "field" + fieldId;
//                    dataType.setFieldId(fieldId);
//                } else if (formulaVar.getOptionId() != null) {
//                    key = "option" + formulaVar.getOptionId().toString();
//                    dataType.setContent(formulaVar.getOptionId());
//                    dataType.setText(formulaVar.getName());
//                    dataType.setFormId(null);
//                } else {
//                    key = "option" + formulaVar.getOptionId().toString();
//                }
//            }
//
//            Arrays.sort(funcArray);
//            int sidx = Arrays.binarySearch(funcArray, key);
//            if (sidx >= 0) {
//                throw new RuntimeException("变量名非法");
//            }
//            if (formulaVar.getOptionId() != null) {
//                dataType.setDataType(DataType.OPTION);
//            }
//
//            if (StringUtils.isEmpty(dataType.getDataType())) {
//                String typeKey = null;
//                if (StringUtils.isNotEmpty(formulaVar.getFieldType())) {
//                    typeKey = formulaVar.getFieldType();
//                } else if (StringUtils.isNotEmpty(formulaVar.getType())) {
//                    typeKey = formulaVar.getType();
//                } else if (StringUtils.isNotEmpty(formulaVar.getFieldType())) {
//                    typeKey = formulaVar.getFieldType();
//                }
//                dataType.setDataType(ExcelParamUtil.findTestDataType(typeKey));
//            }
//            if (StringUtils.isEmpty(dataType.getComponentKey())) {
//                dataType.setComponentKey(formulaVar.getComponentKey());
//            }
//            if (expressMap.containsKey(key)) {
//                String newKey = key + ExcelParamUtil.randomNumber();
//                formulaVar.setKey(newKey);
//                dataType.setAggCndKey(key);
//                expressMap.put(newKey, dataType);
//            } else {
//                expressMap.put(key, dataType);
//            }
//        }
//
//        return expressMap;
//    }

    /**
     * 格式化变量为数字
     *
     * @param
     */
    public static Object convertParamValToNumber(Object op1) {
        BigDecimal oop1 = new BigDecimal(ExcelParamUtil.getParamContent(op1, "string").toString());
        return oop1;
    }

    /**
     * 格式化参数
     *
     * @param op1
     * @param op2
     * @return
     */
    public static List<Object> converParamValue(Object op1, Object op2) {
        List<Object> list = new ArrayList<>();


        if (op1 instanceof DataType) {
            list.add(op1);
            DataType op1Data = (DataType) op1;
            if (!(op2 instanceof DataType) && op1Data.getDataType().toLowerCase().equals("date")) {
                DataType dataType = new DataType();
                dataType.setDataType(DataType.STRING);
                dataType.setContent(op2);
                list.add(dataType);
            } else if (op2 instanceof DataType && op1Data.getDataType().toLowerCase().equals("date")) {
                DataType dataType = (DataType) op2;
                dataType.setDataType(DataType.STRING);
                list.add(dataType);
            } else {
                list.add(op2);
            }

        } else if (op2 instanceof DataType) {
            DataType op2Data = (DataType) op2;
            if (!(op1 instanceof DataType) && op2Data.getDataType().toLowerCase().equals("date")) {
                DataType dataType = new DataType();
                dataType.setDataType(DataType.STRING);
                dataType.setContent(op1);
                list.add(dataType);
            } else if (op1 instanceof DataType && op2Data.getDataType().toLowerCase().equals("date")) {
                DataType dataType = (DataType) op1;
                dataType.setDataType(DataType.STRING);
                list.add(dataType);
            } else {
                list.add(op1);
            }
            list.add(op2);
        } else {
            list.add(op1);
            list.add(op2);
        }

        return list;
    }

    /**
     * 统一处理参数类型不一致问题
     *
     * @param typeName
     * @return
     */
    public static String checkParamType(String typeName) {
        typeName = typeName.toLowerCase();
        switch (typeName) {
            case "option":
                typeName = ParamType.STRING.getName();
                break;
            case "date":
                typeName = DataType.STRING;
                break;
            case "number":
                typeName = DataType.NUMBER;
                break;
            case "string":
                typeName = ParamType.STRING.getName();
                break;
            case "boolean":
                typeName = ParamType.BOOLEAN.getName();
                break;
            case "select":
                typeName = ParamType.STRING.getName();
                break;
            case "text":
                typeName = ParamType.STRING.getName();
                break;
            case "employee":
                typeName = ParamType.STRING.getName();
                break;
            case "department":
                typeName = ParamType.STRING.getName();
                break;
            case "integer":
                typeName = DataType.NUMBER;
                break;
            case "double":
                typeName = DataType.NUMBER;
                break;
            case "float":
                typeName = DataType.NUMBER;
                break;
            case "int":
                typeName = DataType.NUMBER;
                break;
            case "long":
                typeName = DataType.NUMBER;
                break;
            case "bigdecimal":
                typeName = DataType.NUMBER;
                break;

        }
        return typeName;
    }

    public static String getKeyString(Object obj) {
        if (obj instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) obj;
            return jsonObject.getString("key");
        } else {
            return obj.toString();
        }
    }

    /**
     * 替换变量的错误位置
     *
     * @param startIdx
     * @param endIdx
     * @param excuteStr
     */
    public static Map<String, Integer> replaceErrorPlace(int startIdx, int endIdx, String errorFunc, String excuteStr, Map<String, Object> paramMap) {
        Map<String, String> kvMap = loopMap(paramMap);
        Map<String, Integer> replaceMap = new HashMap<>();
        String excuteLeftStr = excuteStr.substring(0, startIdx);
        if (!excuteLeftStr.equals("")) {
            Iterator<String> wordItaretor = kvMap.keySet().iterator();
            while (wordItaretor.hasNext()) {
                String key = wordItaretor.next();
                String name = kvMap.get(key);
                if (excuteLeftStr.indexOf(key) >= 0) {
                    String newStr = excuteLeftStr.replaceAll(key, name);
                    startIdx = startIdx - (excuteLeftStr.length() - newStr.length());
                }
            }

        }
        if (kvMap.get(errorFunc) != null) {
            endIdx = startIdx + kvMap.get(errorFunc).length() - 1;
        } else {
            endIdx = startIdx + errorFunc.length() - 1;
        }

        replaceMap.put("startIdx", startIdx);
        replaceMap.put("endIdx", endIdx);
        return replaceMap;
    }

    public static Map<String, String> loopMap(Map<String, Object> paramMap) {
        Map<String, String> kvMap = new HashMap<>();

        Set<String> set = paramMap.keySet();
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            DataType dataType = (DataType) paramMap.get(key);
            kvMap.put(key, dataType.getName());
        }
        return kvMap;
    }

    public static boolean isNumber(Object object) {
        String type = ExcelParamUtil.getParamType(object.getClass().getName());
        Arrays.sort(numberTypes);
        if (Arrays.binarySearch(numberTypes, type) >= 0) {
            return true;
        }
        return false;
    }

    public static String randomNumber() {
        int max = 1000, min = 1;
        long randomNum = System.currentTimeMillis();
        int ran3 = (int) (randomNum % (max - min) + min);
        return ran3 + "";
    }

    /**
     * 长度不够则添加元素的字符串拼接
     *
     * @param chars        将要拼接的字符
     * @param sourceStr    源字符
     * @param targetLength 目标字符长度
     * @param place        位置在左还是右
     * @return
     */
    public static String appendString(String chars, String sourceStr, int targetLength, String place) {
        StringBuilder builder = new StringBuilder(sourceStr);

        while (true) {
            //长度相等，不做处理
            if (builder.length() == targetLength) {
                break;
            } else if (builder.length() > targetLength) {
                //源字符长度大于目标长度则截取
                int length = builder.length() - targetLength;

                if ("LEFT".equals(place)) {
                    String tempStr = builder.substring(length, builder.length());
                    builder.replace(0, builder.length(), tempStr);
                } else {
                    String tempStr = builder.substring(0, targetLength);
                    builder.replace(0, builder.length(), tempStr);
                }
                break;
            }

            //源字符长度小于目标长度则不断拼接
            if ("LEFT".equals(place)) {
                builder.insert(0, chars.replaceAll(",", ""));
            } else {
                builder.append(chars.replaceAll(",", ""));
            }
        }
        return builder.toString();
    }

//    public static FormulaVar getFixFieldVar(List<FixedField> list, String key) {
//        FormulaVar formulaVar = new FormulaVar();
//        for (FixedField fixedField : list) {
//            if (fixedField.getKey().equals(key)) {
//                Component component = (Component) fixedField.getMatchs().get(0);
//                ComponentType componentType = component.getComponentKey();
//                if (componentType.equals(ComponentType.Text)) {
//
//                }
//            }
//        }
//        return formulaVar;
//    }

    public static String findAggCndStr(String sql, Map<String, Object> paramMap) {
        String partternStr = "(COUNT|SUM|MIN|MAX|AVG|count|sum|min|max)+\\(+(.)+\\)+";
        Pattern pattern = Pattern.compile(partternStr);
        Matcher matcher = pattern.matcher(sql);
        int i = 0;
        while (matcher.find()) {
            String cnd = matcher.group();
            String[] cndArray = cnd.split(",", 2);
            if (cndArray.length == 2) {
                String realCnd = cndArray[1].substring(0, cndArray[1].length() - 1);
                String key = "cnd" + i + Math.abs(realCnd.hashCode()) + "";
                sql = sql.replace(realCnd, key);
                realCnd = realCnd.replace("{", "");
                realCnd = realCnd.replace("}", "");
                paramMap.put(key, realCnd);
            }
            i++;
        }
        return sql;
    }


    /**
     * 执行语句的断句算法，通过计算小括号的数量进行断句断点的确定，然后拆分语句
     *
     * @param sql
     */
    public static String spliteSql(String sql, Map<String, Object> paramMap) {
        List<String> strList = new ArrayList<>();
        int pointIdx = 0;
        char[] charArray = sql.toCharArray();
        int leftBrakets = 0;
        char brackeLeft = '(';
        char brackeRight = ')';
        boolean find = false;
        for (int i = 0; i < charArray.length; i++) {
            char charstr = charArray[i];
            if (charstr == brackeLeft) {
                find = true;
                leftBrakets++;
            }
            if (leftBrakets != 0 && charstr == brackeRight) {
                leftBrakets--;
            }
            if (find && leftBrakets == 0) {
                pointIdx = i;
                break;
            }
        }
        pointIdx += 1;
        if (pointIdx == sql.length()) {
            strList.add(sql.substring(0, pointIdx));
        } else {
            strList.add(sql.substring(0, pointIdx));
            strList.add(sql.substring(pointIdx));
        }
        String replaceSql = "";
        for (String s : strList) {
            String[] cndArray = s.split("(COUNT|SUM|MIN|MAX|count|sum|min|max)");
            if (cndArray.length == 2) {
                if (cndArray[0].equals("")) {
                    replaceSql += findAggCndStr(s, paramMap);
                } else {
                    String realCnd = s.substring(cndArray[0].length() - 1 >= 0 ? cndArray[0].length() : 0);
                    replaceSql += cndArray[0] + findAggCndStr(realCnd, paramMap);
                }

            } else {
                replaceSql += findAggCndStr(s, paramMap);
            }

        }
        sql = replaceSql;
        return sql;
    }

}
