package org.example.Utils;

/**
 * DataTableUtil工具类来处理数据类型转换
 */

import org.apache.commons.lang3.function.TriFunction;
import org.example.Entity.System.SystemMenu;

import java.lang.reflect.Method;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DataTableUtil {

    /**
     * 需要访问row中的数据
     */
    public static int getIntValue(Map<String, Object> row, String columnName, int defaultValue) {
        if (row == null || !row.containsKey(columnName)) {
            return defaultValue;
        }
        columnName = columnName.toLowerCase();
        Object value = row.get(columnName);
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static String getStringValue(Map<String, Object> row, String columnName, String defaultValue) {
        if (defaultValue == null) {
            defaultValue = "";
        }
        Object value = get(row, columnName, defaultValue);
        return value != null ? value.toString() : defaultValue;
    }

    public static String getStringValue(Map<String, Object> row, String columnName, String firstVal, String defaultValue) {
        if (defaultValue == null) {
            defaultValue = "";
        }
        Object value = get(row, columnName, firstVal, defaultValue);
        return value != null ? value.toString() : defaultValue;
    }

    public static String getStringValue(Map<String, Object> row, String columnName) {
        Object value = get(row, columnName);
        return value != null ? value.toString() : "";
    }

    public static String getStringValue(Map<String, Object> row, String[] columnNames, String defaultValue) {
        if (defaultValue == null) {
            defaultValue = "";
        }
        Object value = get(row, columnNames, defaultValue);
        return value != null ? value.toString() : "";
    }

    public static boolean getBooleanValue(Map<String, Object> row, String columnName, boolean defaultValue) {
        if (row == null || !row.containsKey(columnName)) {
            return defaultValue;
        }
        columnName = columnName.toLowerCase();
        Object value = row.get(columnName);
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        try {
            return Boolean.parseBoolean(value.toString());
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static int getIntValue(String value, int defaultValue) {
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static boolean getBooleanValue(String value, boolean defaultValue) {
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        return Boolean.parseBoolean(value);
    }

    /**
     * 将对象转换为布尔值
     * 支持的类型包括：Boolean、String、Number、Character、null
     * 其他类型将返回默认值
     */
    public static boolean toBoolean(Object value) {
        return toBoolean(value, false);
    }

    /**
     * 将对象转换为布尔值，允许指定默认值
     * 支持的类型包括：Boolean、String、Number、Character、null
     */
    public static boolean toBoolean(Object value, boolean defaultValue) {
        if (value == null) {
            return defaultValue;
        }

        if (value instanceof Boolean) {
            return (Boolean) value;
        }

        if (value instanceof String) {
            String str = ((String) value).trim().toLowerCase();
            if (str.isEmpty()) {
                return defaultValue;
            }
            if ("true".equals(str) || "yes".equals(str) || "on".equals(str) || "1".equals(str)) {
                return true;
            }
            if ("false".equals(str) || "no".equals(str) || "off".equals(str) || "0".equals(str)) {
                return false;
            }
            return defaultValue;
        }

        if (value instanceof Number) {
            double num = ((Number) value).doubleValue();
            return num != 0;
        }

        if (value instanceof Character) {
            char c = (Character) value;
            return c != '0' && c != '\0';
        }

        return defaultValue;
    }


    /**
     * 获取值
     *
     * @param row        数据行
     * @param name       列名
     * @param defaultVal 默认值
     * @return 获取到的值或默认值
     */
    public static Object getRowVal(Map<String, Object> row, String name, Object defaultVal) {
        if (name == null || name.isEmpty() || row == null) {
            return defaultVal;
        }

        if (row.containsKey(name)) {
            Object value = row.get(name);
            return isEmptyValue(value) ? defaultVal : value;
        }

        String lowerName = name.toLowerCase();
        Optional<String> matchedKey = row.keySet().stream()
                .filter(key -> key.toLowerCase().equals(lowerName))
                .findFirst();

        if (matchedKey.isPresent()) {
            Object value = row.get(matchedKey.get());
            return isEmptyValue(value) ? defaultVal : value;
        }

        return defaultVal;
    }

    /**
     * 获取值
     *
     * @param row        数据行
     * @param name       列名
     * @param firstVal   优先值
     * @param defaultVal 默认值
     * @return 优先值、获取到的值或默认值
     */
    public static Object getRowVal(Map<String, Object> row, String name, Object firstVal, Object defaultVal) {
        return firstVal != null ? firstVal : getRowVal(row, name, defaultVal);
    }

    /**
     * 获取值
     *
     * @param row        数据行
     * @param names      可能的列名数组
     * @param firstVal   优先值
     * @param defaultVal 默认值
     * @return 优先值、获取到的值或默认值
     */
    public static Object getRowVal(Map<String, Object> row, String[] names, Object firstVal, Object defaultVal) {
        return firstVal != null ? firstVal : getRowVal(row, names, defaultVal);
    }

    /**
     * 获取值
     *
     * @param row        数据行
     * @param names      可能的列名数组
     * @param defaultVal 默认值
     * @return 获取到的值或默认值
     */
    public static Object getRowVal(Map<String, Object> row, String[] names, Object defaultVal) {
        if (names == null || names.length == 0 || row == null) {
            return defaultVal;
        }

        Object value = defaultVal;
        for (String name : names) {
            value = getRowVal(row, name, "");
            if (!isEmptyValue(value)) {
                return value;
            }
        }

        return isEmptyValue(value) ? defaultVal : value;
    }

    /**
     * 获取值（扩展方法）
     *
     * @param row        数据行
     * @param name       列名
     * @param defaultVal 默认值
     * @return 获取到的值或默认值
     */
    public static Object get(Map<String, Object> row, String name, Object defaultVal) {
        return getRowVal(row, name, defaultVal);
    }

    public static Object get(Map<String, Object> row, String name) {
        return getRowVal(row, name, null);
    }

    /**
     * 获取值（扩展方法）
     *
     * @param row        数据行
     * @param name       列名
     * @param firstVal   优先值
     * @param defaultVal 默认值
     * @return 优先值、获取到的值或默认值
     */
    public static Object get(Map<String, Object> row, String name, Object firstVal, Object defaultVal) {
        return getRowVal(row, name, firstVal, defaultVal);
    }

    /**
     * 获取值（扩展方法）
     *
     * @param row        数据行
     * @param names      可能的列名数组
     * @param defaultVal 默认值
     * @return 获取到的值或默认值
     */
    public static Object get(Map<String, Object> row, String[] names, Object defaultVal) {
        return getRowVal(row, names, defaultVal);
    }

    /**
     * 获取值（扩展方法）
     *
     * @param row        数据行
     * @param names      可能的列名数组
     * @param firstVal   优先值
     * @param defaultVal 默认值
     * @return 优先值、获取到的值或默认值
     */
    public static Object get(Map<String, Object> row, String[] names, Object firstVal, Object defaultVal) {
        return getRowVal(row, names, firstVal, defaultVal);
    }

    /**
     * 从哈希表获取值
     *
     * @param tab        哈希表
     * @param name       键名
     * @param defaultVal 默认值
     * @return 获取到的值或默认值
     */
    public static Object get(Hashtable<String, Object> tab, String name, Object defaultVal) {
        String key = tab.keySet().stream()
                .filter(k -> k.toLowerCase().equals(name.toLowerCase()))
                .findFirst()
                .orElse(null);

        if (key == null) {
            return defaultVal != null ? defaultVal : "";
        }

        return tab.get(key);
    }

    /**
     * 将Map的键转换为小写
     *
     * @param map 要处理的Map
     * @return 键为小写的新Map
     */
    public static Map<String, Object> toLowerKeyMap(Map<String, Object> map) {
        if (map == null) {
            return null;
        }

        Map<String, Object> result = new HashMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            result.put(entry.getKey().toLowerCase(), entry.getValue());
        }
        return result;
    }

    /**
     * 将列表中的Map转换为哈希表列表
     *
     * @param list 包含Map的列表
     * @return 哈希表列表
     */
    public static List<Map<String, Object>> toHashTable(List<Map<String, Object>> list) {
        return toHashTable(list, null, true, true, false);
    }

    /**
     * 将列表中的Map转换为哈希表列表
     *
     * @param list       包含Map的列表
     * @param ignoreNull 是否忽略空值
     * @return 哈希表列表
     */
    public static List<Map<String, Object>> toHashTable(List<Map<String, Object>> list, boolean ignoreNull) {
        return toHashTable(list, null, ignoreNull, true, false);
    }

    /**
     * 将列表中的Map转换为哈希表列表
     *
     * @param list          包含Map的列表
     * @param ignoreNull    是否忽略空值
     * @param lowerCase     键是否转为小写
     * @param nullToNullStr 是否将null转为空字符串
     * @return 哈希表列表
     */
    public static List<Map<String, Object>> toHashTable(List<Map<String, Object>> list, boolean ignoreNull,
                                                        boolean lowerCase, boolean nullToNullStr) {
        return toHashTable(list, null, ignoreNull, lowerCase, nullToNullStr);
    }

    /**
     * 将列表中的Map转换为哈希表列表
     *
     * @param list          包含Map的列表
     * @param format        格式化字典
     * @param ignoreNull    是否忽略空值
     * @param lowerCase     键是否转为小写
     * @param nullToNullStr 是否将null转为空字符串
     * @return 哈希表列表
     */
    public static List<Map<String, Object>> toHashTable(List<Map<String, Object>> list, Map<String, Object> format,
                                                        boolean ignoreNull, boolean lowerCase, boolean nullToNullStr) {
        if (list == null) {
            return null;
        }

        return list.stream()
                .map(row -> toHashTable(row, format, ignoreNull, lowerCase, nullToNullStr))
                .collect(Collectors.toList());
    }

    /**
     * 将列表中的Map转换为哈希表列表
     *
     * @param list       包含Map的列表
     * @param format     格式化字典
     * @param fillColor  填充颜色的函数
     * @param fillStyle  填充样式的函数
     * @param ignoreNull 是否忽略空值
     * @return 哈希表列表
     */
    public static List<Map<String, Object>> toHashTable(List<Map<String, Object>> list, Map<String, Object> format,
                                                        Function<Map<String, Object>, Map<String, Object>> fillColor,
                                                        Function<Map<String, Object>, Map<String, Object>> fillStyle,
                                                        boolean ignoreNull) {
        if (list == null) {
            return null;
        }

        return list.stream()
                .map(row -> toHashTable(row, format, fillColor, fillStyle, ignoreNull, true, false))
                .collect(Collectors.toList());
    }

    /**
     * 将Map转换为哈希表
     *
     * @param row 要转换的Map
     * @return 转换后的哈希表
     */
    public static Map<String, Object> toHashTable(Map<String, Object> row) {
        return toHashTable(row, null, true, true, false);
    }

    /**
     * 将Map转换为哈希表
     *
     * @param row        要转换的Map
     * @param ignoreNull 是否忽略空值
     * @param lowerCase  键是否转为小写
     * @return 转换后的哈希表
     */
    public static Map<String, Object> toHashTable(Map<String, Object> row, boolean ignoreNull, boolean lowerCase) {
        return toHashTable(row, null, ignoreNull, lowerCase, false);
    }

    /**
     * 将Map转换为哈希表
     *
     * @param row           要转换的Map
     * @param ignoreNull    是否忽略空值
     * @param lowerCase     键是否转为小写
     * @param nullToNullStr 是否将null转为空字符串
     * @return 转换后的哈希表
     */
    public static Map<String, Object> toHashTable(Map<String, Object> row, boolean ignoreNull,
                                                  boolean lowerCase, boolean nullToNullStr) {
        return toHashTable(row, null, ignoreNull, lowerCase, nullToNullStr);
    }

    /**
     * 将Map转换为哈希表
     *
     * @param row           要转换的Map
     * @param format        格式化字典
     * @param ignoreNull    是否忽略空值
     * @param lowerCase     键是否转为小写
     * @param nullToNullStr 是否将null转为空字符串
     * @return 转换后的哈希表
     */
    public static Map<String, Object> toHashTable(Map<String, Object> row, Map<String, Object> format,
                                                  boolean ignoreNull, boolean lowerCase, boolean nullToNullStr) {
        return toHashTable(row, format, null, null, ignoreNull, lowerCase, nullToNullStr);
    }

    /**
     * 将Map转换为哈希表
     *
     * @param row           要转换的Map
     * @param format        格式化字典
     * @param fillColor     填充颜色的函数
     * @param fillStyle     填充样式的函数
     * @param ignoreNull    是否忽略空值
     * @param lowerCase     键是否转为小写
     * @param nullToNullStr 是否将null转为空字符串
     * @return 转换后的哈希表
     */
    public static Map<String, Object> toHashTable(Map<String, Object> row, Map<String, Object> format,
                                                  Function<Map<String, Object>, Map<String, Object>> fillColor,
                                                  Function<Map<String, Object>, Map<String, Object>> fillStyle,
                                                  boolean ignoreNull, boolean lowerCase, boolean nullToNullStr) {
        if (row == null) {
            return null;
        }

        Map<String, Object> hashtable = new HashMap<>();

        for (Map.Entry<String, Object> entry : row.entrySet()) {
            String columnName = entry.getKey();
            Object value = entry.getValue();

            if (ignoreNull && isEmptyValue(value)) {
                continue;
            }

            String key = lowerCase ? columnName.toLowerCase() : columnName;

            // 处理null值
            if (nullToNullStr && isEmptyValue(value)) {
                value = "";
            }

            // 处理大数据值
            if (value != null && value.toString().startsWith("0E-")) {
                value = 0;
            }

            // 格式化处理（注释了原C#中的格式化逻辑，保持与原代码一致）
            if (!isEmptyValue(value) && format != null && format.containsKey(key)) {
                // 原C#代码中取消了后端格式化，此处保持一致
            }

            hashtable.put(key, value);
        }

        // 处理颜色
        if (fillColor != null) {
            Map<String, Object> fontColors = fillColor.apply(row);
            if (fontColors != null && !fontColors.isEmpty()) {
                hashtable.put("$fontcolor", fontColors);
            }
        }

        // 处理样式
        if (fillStyle != null) {
            Map<String, Object> styles = fillStyle.apply(row);
            if (styles != null && !styles.isEmpty()) {
                hashtable.put("$styles", styles);
            }
        }

        return hashtable;
    }

    /**
     * 将List<Map<String, Object>>（替代DataTable）转换为HashMap列表
     * 完全保留原方法的逻辑和参数，仅替换底层数据结构
     *
     * @param table         数据源（替代原DataTable）
     * @param format        格式化字典
     * @param fillColor     行颜色填充处理器
     * @param fillStyle     行样式填充处理器
     * @param ignoreNull    是否忽略空值（默认true）
     * @param lowerCase     是否列名转小写（默认true）
     * @param nullToNullStr 是否将null转为"null"字符串（默认false）
     * @param convert       自定义值转换处理器
     * @return HashMap列表
     */
    public static List<Map<String, Object>> toHashTable(
            List<Map<String, Object>> table,
            Map<String, Object> format,
            Function<Map<String, Object>, Map<String, Object>> fillColor,
            Function<Map<String, Object>, Map<String, Object>> fillStyle,
            Boolean ignoreNull,
            Boolean lowerCase,
            Boolean nullToNullStr,
            TriFunction<Map<String, Object>, String, Object, Object> convert
    ) {
        // 处理默认参数
        ignoreNull = (ignoreNull == null) ? true : ignoreNull;
        lowerCase = (lowerCase == null) ? true : lowerCase;
        nullToNullStr = (nullToNullStr == null) ? false : nullToNullStr;

        // null判断逻辑
        if (table == null) {
            return null;
        }

        List<Map<String, Object>> list = new ArrayList<>();

        // 遍历每一行（原DataRow → 现在的Map<String, Object>）
        for (Map<String, Object> row : table) {
            Map<String, Object> rowMap = toHashTableForRow(
                    row, format, fillColor, fillStyle,
                    ignoreNull, lowerCase, nullToNullStr, convert
            );
            list.add(rowMap);
        }

        return list;
    }

    /**
     * 行级转换方法（处理单个Map<String, Object>）
     */
    private static Map<String, Object> toHashTableForRow(
            Map<String, Object> row,
            Map<String, Object> format,
            Function<Map<String, Object>, Map<String, Object>> fillColor,
            Function<Map<String, Object>, Map<String, Object>> fillStyle,
            boolean ignoreNull,
            boolean lowerCase,
            boolean nullToNullStr,
            TriFunction<Map<String, Object>, String, Object, Object> convert
    ) {
        Map<String, Object> rowMap = new HashMap<>();

        // 1. 处理格式化参数
        if (format != null && !format.isEmpty()) {
            rowMap.putAll(format);
        }

        // 2. 处理颜色填充
        if (fillColor != null) {
            Map<String, Object> colorMap = fillColor.apply(row);
            if (colorMap != null) {
                rowMap.putAll(colorMap);
            }
        }

        // 3. 处理样式填充
        if (fillStyle != null) {
            Map<String, Object> styleMap = fillStyle.apply(row);
            if (styleMap != null) {
                rowMap.putAll(styleMap);
            }
        }

        // 4. 遍历行的所有列（Map的key就是列名）
        for (Map.Entry<String, Object> entry : row.entrySet()) {
            String columnName = entry.getKey();
            // 列名转小写
            if (lowerCase) {
                columnName = columnName.toLowerCase();
            }

            // 获取原始值
            Object value = entry.getValue();

            // 5. 空值处理
            if (value == null) {
                if (ignoreNull) {
                    continue; // 忽略空值
                }
                if (nullToNullStr) {
                    value = "null"; // null转为"null"字符串
                }
            }

            // 6. 自定义值转换（核心：比如填充文件路径）
            if (convert != null) {
                value = convert.apply(row, columnName, value);
            }

            // 7. 放入结果Map
            rowMap.put(columnName, value);
        }

        return rowMap;
    }

    /**
     * 将哈希表数组转换为List<Map>
     *
     * @param tabs 哈希表数组
     * @return 转换后的List<Map>
     */
    public static List<Map<String, Object>> toMapList(Hashtable<String, Object>[] tabs) {
        List<Map<String, Object>> result = new ArrayList<>();
        if (tabs == null || tabs.length == 0) {
            return result;
        }

        Set<String> allKeys = new HashSet<>();
        for (Hashtable<String, Object> tab : tabs) {
            allKeys.addAll(tab.keySet());
        }

        for (Hashtable<String, Object> tab : tabs) {
            Map<String, Object> row = new HashMap<>();
            for (String key : allKeys) {
                Object value = tab.get(key);
                row.put(key, value != null ? value.toString() : null);
            }
            result.add(row);
        }

        return result;
    }

    /**
     * 将Map转换为Dictionary（Java中使用HashMap替代）
     *
     * @param row        要转换的Map
     * @param ignoreNull 是否忽略空值
     * @return 转换后的HashMap
     */
    public static Map<String, Object> toDict(Map<String, Object> row, boolean ignoreNull) {
        return toDict(row, null, ignoreNull);
    }

    /**
     * 将Map转换为Dictionary（Java中使用HashMap替代）
     *
     * @param row        要转换的Map
     * @param format     格式化字典
     * @param ignoreNull 是否忽略空值
     * @return 转换后的HashMap
     */
    public static Map<String, Object> toDict(Map<String, Object> row, Map<String, Object> format, boolean ignoreNull) {
        if (row == null) {
            return null;
        }

        Map<String, Object> dict = new HashMap<>();

        for (Map.Entry<String, Object> entry : row.entrySet()) {
            String columnName = entry.getKey();
            Object value = entry.getValue();

            if (ignoreNull && isEmptyValue(value)) {
                continue;
            }

            String key = columnName.toLowerCase();

            if (!isEmptyValue(value) && format != null && format.containsKey(key)) {
                try {
                    String formatStr = format.get(key).toString();
                    Method toStringMethod = value.getClass().getMethod("toString", String.class);
                    value = toStringMethod != null ? toStringMethod.invoke(value, formatStr) : value;
                } catch (Exception e) {
                    // 忽略格式化异常
                }
            }

            dict.put(key, value);
        }

        return dict;
    }

    /**
     * 判断值是否为空
     *
     * @param value 要判断的值
     * @return 是否为空
     */
    private static boolean isEmptyValue(Object value) {
        if (value == null) {
            return true;
        }
        if (value instanceof String) {
            return ((String) value).trim().isEmpty();
        }
        return false;
    }

    /**
     * 根据数据表和列名获取字段类型
     *
     * @param dtVal      数据表（通常为 List<Map<String, Object>> 类型）
     * @param columnName 列名
     * @return 字段类型（可能是数据库类型编码 Integer 或 ControlType 枚举）
     */
    public static Object getColumnType(List<Map<String, Object>> dtVal, String columnName) {
        if (dtVal == null || dtVal.isEmpty() || columnName == null || columnName.isEmpty()) {
            return null;
        }

        // 1. 尝试从数据表元信息中获取字段类型（假设存在 "FieldDbType" 列存储数据库类型编码）
        for (Map<String, Object> row : dtVal) {
            String fieldName = DataTableUtil.getStringValue(row, "fieldname", "").toLowerCase();
            if (fieldName.equals(columnName.toLowerCase())) {
                // 参考 RowColumn.getFieldDbType() 的实现，返回数据库类型编码
                String dbTypeVal = DataTableUtil.getStringValue(row, "FieldDbType", "");
                return NativeExtensionUtils.parseInt(dbTypeVal);
            }
        }
        return null;
    }

    /**
     * 将List<Map>中所有Map的key转换为小写
     *
     * @param listMap 待处理的List<Map>数据
     * @return 转换后的List<Map>（直接修改原对象，也返回该对象方便链式调用）
     */
    public static List<Map<String, Object>> toLowerColumnName(List<Map<String, Object>> listMap) {
        // 判空处理，避免空指针异常
        if (listMap == null || listMap.isEmpty()) {
            return listMap;
        }

        // 遍历每一个Map对象
        for (Map<String, Object> map : listMap) {
            if (map == null || map.isEmpty()) {
                continue;
            }

            // 先收集所有需要转换的key，避免遍历过程中修改Map导致ConcurrentModificationException
            Set<String> originalKeys = new HashSet<>(map.keySet());

            // 遍历原始key，转换为小写并替换
            for (String key : originalKeys) {
                String lowerKey = key.toLowerCase();
                // 如果key本身已经是小写，无需处理
                if (key.equals(lowerKey)) {
                    continue;
                }
                // 获取原值
                Object value = map.get(key);
                // 移除原key
                map.remove(key);
                // 添加小写key和原值
                map.put(lowerKey, value);
            }
        }

        return listMap;
    }

}
