package org.example.Utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 等效实现 C# DataTable.Select(cond) 的 Java 工具类
 */
public class DataFilterUtil {

    /**
     * 等效 C# DataTable.Select(cond)：按条件字符串过滤 List<Map<String, Object>> 数据
     *
     * @param theDT 待过滤的数据（对应 C# 的 DataTable）
     * @param cond  筛选条件（如 "name = '张三' and age > 18"，支持 =/!=/>/</>=/<= 运算符，and/or 连接）
     * @return 符合条件的行数据（对应 C# 的 DataRow[]）
     * @throws Exception 条件解析失败或数据类型不匹配时抛出
     */
    public static List<Map<String, Object>> select(List<Map<String, Object>> theDT, String cond) throws Exception {
        // 结果集：存储符合条件的行
        List<Map<String, Object>> queryResult = new ArrayList<>();
        if (theDT == null || theDT.isEmpty() || cond == null || cond.trim().isEmpty()) {
            return queryResult;
        }

        // 1. 解析条件字符串（简化版：支持单条件或 "and/or" 连接的多条件，暂不支持括号优先级）
        // 分割条件（处理 and/or 连接，忽略前后空格）
        String[] conditions = cond.replaceAll("\\s+", " ").split("(?i)\\s+(and|or)\\s+");
        // 分割逻辑运算符（如 ["and", "or"]）
        Pattern opPattern = Pattern.compile("(?i)\\s+(and|or)\\s+");
        Matcher opMatcher = opPattern.matcher(cond.replaceAll("\\s+", " "));
        List<String> logicOps = new ArrayList<>();
        while (opMatcher.find()) {
            logicOps.add(opMatcher.group(1).toLowerCase()); // 转为小写统一处理（and/or）
        }

        // 2. 遍历每一行数据，校验是否符合所有条件
        for (Map<String, Object> row : theDT) {
            boolean rowMatch = true; // 标记当前行是否符合条件
            int condIndex = 0; // 条件索引

            // 逐个校验条件（处理多条件的 and/or 逻辑）
            for (String singleCond : conditions) {
                singleCond = singleCond.trim();
                if (singleCond.isEmpty()) {
                    continue;
                }

                // 解析单个条件：拆分为「字段名、运算符、值」（支持字符串值带单引号，如 name = '张三'）
                Pattern condPattern = Pattern.compile("^\\s*([a-zA-Z0-9_]+)\\s*(=|!=|>|<|>=|<=)\\s*('?)(.*?)\\3\\s*$");
                Matcher condMatcher = condPattern.matcher(singleCond);
                if (!condMatcher.matches()) {
                    throw new Exception("条件格式错误：" + singleCond + "（正确格式：字段名 运算符 值，如 name = '张三' 或 age > 18）");
                }

                // 提取条件的三部分
                String field = condMatcher.group(1); // 字段名（如 "name"、"age"）
                String op = condMatcher.group(2);   // 运算符（如 "="、">"、"!="）
                String valueStr = condMatcher.group(4); // 值（如 "张三"、"18"，已去掉单引号）

                // 3. 校验当前行的该字段是否符合条件
                Object fieldValue = row.get(field); // 当前行的字段值
                if (fieldValue == null) {
                    // 字段值为 null 时，仅支持 "is null" 类逻辑（此处简化处理：null 不匹配任何非 null 条件）
                    rowMatch = false;
                    break;
                }

                // 4. 按字段类型（字符串/数值/布尔）执行比较
                boolean singleMatch = compare(fieldValue, op, valueStr);
                if (!singleMatch) {
                    String logicOp = logicOps.get(condIndex - 1);
                    // 若当前条件不匹配，根据逻辑运算符更新 rowMatch
                    if (condIndex == 0) {
                        rowMatch = false;
                    } else {

                        if ("and".equals(logicOp)) {
                            rowMatch = false;
                        } else if ("or".equals(logicOp)) {
                            rowMatch = rowMatch && false; // or 逻辑下，当前条件不匹配不影响之前的匹配结果
                        }
                    }
                    // and 逻辑下，只要有一个条件不匹配，直接跳出当前行的校验
                    if ("and".equals(logicOp) || condIndex == 0) {
                        break;
                    }
                } else {
                    // 若当前条件匹配，根据逻辑运算符更新 rowMatch
                    if (condIndex > 0) {
                        String logicOp = logicOps.get(condIndex - 1);
                        if ("and".equals(logicOp)) {
                            rowMatch = rowMatch && true;
                        } else if ("or".equals(logicOp)) {
                            rowMatch = rowMatch || true;
                        }
                    }
                }
                condIndex++;
            }

            // 5. 若当前行符合所有条件，加入结果集
            if (rowMatch) {
                queryResult.add(row);
            }
        }

        return queryResult;
    }

    /**
     * 按数据类型执行比较（支持字符串、数值、布尔类型）
     *
     * @param fieldValue 行的字段值（Java 原生类型，如 String、Integer、Double、Boolean）
     * @param op         运算符（=、!=、>、<、>=、<=）
     * @param valueStr   条件中的值（字符串形式，需转为对应类型）
     * @return 比较结果（true=符合条件，false=不符合）
     * @throws Exception 类型转换失败或不支持的运算符
     */
    private static boolean compare(Object fieldValue, String op, String valueStr) throws Exception {
        // 处理字符串类型（fieldValue 是 String 或可转为 String）
        if (fieldValue instanceof String) {
            String fieldStr = (String) fieldValue;
            return compareString(fieldStr, op, valueStr);
        }

        // 处理数值类型（Integer、Long、Double、Float 等）
        if (fieldValue instanceof Number) {
            Number fieldNum = (Number) fieldValue;
            double fieldDouble = fieldNum.doubleValue(); // 统一转为 double 比较（避免精度问题）
            double valueDouble = Double.parseDouble(valueStr); // 将条件值转为 double
            return compareNumber(fieldDouble, op, valueDouble);
        }

        // 处理布尔类型
        if (fieldValue instanceof Boolean) {
            boolean fieldBool = (Boolean) fieldValue;
            boolean valueBool = Boolean.parseBoolean(valueStr);
            return compareBoolean(fieldBool, op, valueBool);
        }

        // 不支持的类型
        throw new Exception("不支持的字段类型：" + fieldValue.getClass().getName() + "（仅支持 String、Number、Boolean）");
    }

    /**
     * 字符串类型比较（支持 =、!=、包含（instr）等逻辑，此处实现基础比较）
     */
    private static boolean compareString(String fieldStr, String op, String valueStr) {
        return switch (op) {
            case "=" -> fieldStr.equals(valueStr);
            case "!=" -> !fieldStr.equals(valueStr);
            case ">" -> fieldStr.compareTo(valueStr) > 0; // 字符串按字典序比较
            case "<" -> fieldStr.compareTo(valueStr) < 0;
            case ">=" -> fieldStr.compareTo(valueStr) >= 0;
            case "<=" -> fieldStr.compareTo(valueStr) <= 0;
            default -> false;
        };
    }

    /**
     * 数值类型比较（支持 =、!=、>、<、>=、<=）
     */
    private static boolean compareNumber(double fieldDouble, String op, double valueDouble) {
        return switch (op) {
            case "=" -> fieldDouble == valueDouble;
            case "!=" -> fieldDouble != valueDouble;
            case ">" -> fieldDouble > valueDouble;
            case "<" -> fieldDouble < valueDouble;
            case ">=" -> fieldDouble >= valueDouble;
            case "<=" -> fieldDouble <= valueDouble;
            default -> false;
        };
    }

    /**
     * 布尔类型比较（仅支持 =、!=）
     */
    private static boolean compareBoolean(boolean fieldBool, String op, boolean valueBool) throws Exception {
        return switch (op) {
            case "=" -> fieldBool == valueBool;
            case "!=" -> fieldBool != valueBool;
            default -> throw new Exception("布尔类型仅支持 =、!= 运算符，不支持：" + op);
        };
    }

    /**
     * 等效C#的 FirstOrDefault 方法 - List<Hashtable>专用
     * 根据条件匹配第一个符合的Hashtable，无则返回null
     */
    public static Map<String, Object> firstOrDefault(List<Map<String, Object>> list, String key, String matchVal) {
        if (list == null || list.isEmpty() || key == null || matchVal == null) {
            return null;
        }
        for (Map<String, Object> ht : list) {
            Object valObj = ht.get(key);
            String val = valObj == null ? "" : valObj.toString();
            if (matchVal.equalsIgnoreCase(val)) {
                return ht;
            }
        }
        return null;
    }
}