package com.boman.web.core.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boman.gen.domain.GenTableColumn;
import com.boman.web.core.constant.FormDataConstant;
import com.google.common.collect.Lists;

import java.sql.Timestamp;
import java.util.List;
import java.util.function.Predicate;

import static com.boman.common.core.utils.obj.ObjectUtils.isEmpty;
import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;
import static com.boman.web.core.constant.FormDataConstant.HR;

/**
 * @author shiqian
 * @date 2021年04月13日 15:37
 **/
public class ColumnUtils {

    /**
     * 功能描述: 新增或者修改的时候，是否需要给修改人修改时间赋值
     *
     * @param columns     所有的列
     * @param jsonObject  需要返回的数据
     * @param currentTime currentTime
     */
    public static void packUpdateByAndTime(List<GenTableColumn> columns, JSONObject jsonObject, Timestamp currentTime) {
        for (GenTableColumn column : columns) {
            // 判断是否有修改人、修改时间
            if (FormDataConstant.UPDATE_BY.equalsIgnoreCase(column.getColumnName())) {
                jsonObject.put(FormDataConstant.UPDATE_BY, "张三");
            }
            if (FormDataConstant.UPDATE_TIME.equalsIgnoreCase(column.getColumnName())) {
                jsonObject.put(FormDataConstant.UPDATE_TIME, currentTime);
            }

            // 如果某一列是datetime类型，需要把类型转成datetime，否则数据库会报错
            if (FormDataConstant.DATETIME.equalsIgnoreCase(column.getColumnType())) {
                String columnName = column.getColumnName().toUpperCase();
                jsonObject.put(columnName, jsonObject.getTimestamp(columnName));
            }
        }
    }

    /**
     * 功能描述: 把新增可见或者修改可见或者.....的列过滤出来
     *
     * @param allColumns 所有的列
     * @param sort       那六个1的顺序 [1,1,1,1,1,1]
     *                   sort=0  =>  新增可见
     *                   sort=1  =>  新增可修改
     *                   sort=2  =>  修改可见
     *                   sort=3  =>  修改可修改
     *                   sort=4  =>  列表可见
     *                   sort=5  =>  列表可修改
     * @return List<GenTableColumn>
     */
    public static List<GenTableColumn> filterData(List<GenTableColumn> allColumns, int sort, Predicate<String> predicate) {
        assert sort < 6;
        List<GenTableColumn> returnData = Lists.newArrayListWithCapacity(16);
        for (GenTableColumn allColumn : allColumns) {
            if (!HR.equalsIgnoreCase(allColumn.getHtmlType())) {
                String[] maskArray = requireNonNull(allColumn.getMask(), "mask is empty").split("");
                assert maskArray.length == 6;
                // sort
                String insertVisible = maskArray[sort];
                if (predicate.test(insertVisible)) {
                    returnData.add(allColumn);
                }
            }

        }

        return returnData;
    }

    /**
     * 功能描述: 按照predicate的规则过滤allColumns中包含data并且符合过滤规则的数据
     *
     * @param allColumns 所有的列
     * @param sort       同{@link ColumnUtils#filterData(java.util.List, int, java.util.function.Predicate)}
     * @param data       从其中过滤符合规则的数据，data中字符串全部是大写的
     * @param predicate  predicate
     * @return JSONArray
     */
    public static JSONArray filterData(List<GenTableColumn> allColumns, int sort, JSONArray data, Predicate<String> predicate) {
        assert sort < 6;
        JSONArray returnData = new JSONArray(data.size());
        boolean dataIsEmpty = isEmpty(data);
        if (dataIsEmpty) {
            // data为空，拿出所有列中列表可见的
            for (GenTableColumn allColumn : allColumns) {
                String columnName = allColumn.getColumnName().toUpperCase();
                String[] maskArray = requireNonNull(allColumn.getMask(), "mask is empty").split("");
                assert maskArray.length == 6;
                String maskValue = maskArray[sort];
                if (predicate.test(maskValue)) {
                    returnData.add(columnName);
                }
            }
        } else {
            // data不为空，拿出前端传过来的列中可见的
            for (GenTableColumn allColumn : allColumns) {
                String columnName = allColumn.getColumnName().toUpperCase();
                if (data.contains(columnName)) {
                    String[] maskArray = requireNonNull(allColumn.getMask(), "mask is empty").split("");
                    assert maskArray.length == 6;
                    String maskValue = maskArray[sort];
                    if (predicate.test(maskValue)) {
                        returnData.add(columnName);
                    }
                }
            }
        }


        return returnData;
    }

    public static String parseVariables(String variables) {
        return variables.replaceAll("\\$", "");
    }

}
