package org.example.Utils;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.StatementCallback;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DMJdbcMultiResultSetUtil {
    /**
     * 执行SQL语句，遍历所有结果集，封装为统一格式返回
     * @param jdbcTemplate JdbcTemplate 实例（由业务层传入，保证灵活性）
     * @param sql 待执行的SQL语句（普通SELECT、PL/SQL块、存储过程调用等）
     * @return List<List<Map<String, Object>>> 所有结果集的封装结果
     *         外层List：所有结果集（按执行顺序排列）
     *         内层List：单个结果集的所有行数据
     *         Map：单行数据的「字段名-字段值」映射
     */
    public static List<List<Map<String, Object>>> executeMultiResultSet(JdbcTemplate jdbcTemplate, String sql) {
        // 入参校验
        if (jdbcTemplate == null) {
            throw new IllegalArgumentException("JdbcTemplate 实例不能为空");
        }
        if (sql == null || sql.trim().isEmpty()) {
            throw new IllegalArgumentException("待执行的SQL语句不能为空");
        }

        try {
            // 执行SQL，遍历并封装所有结果集
            return jdbcTemplate.execute((StatementCallback<List<List<Map<String, Object>>>>) stmt -> {
                // 总结果集：存放所有结果集的封装数据
                List<List<Map<String, Object>>> totalResultSets = new ArrayList<>();
                // 执行SQL语句，获取第一个结果集的标记
                boolean hasMoreResults = stmt.execute(sql.trim());

                // 循环遍历所有结果集（包括更新计数，保证不遗漏）
                while (hasMoreResults || stmt.getUpdateCount() != -1) {
                    if (hasMoreResults) {
                        // 处理当前结果集，封装为 List<Map<String, Object>>
                        ResultSet rs = stmt.getResultSet();
                        List<Map<String, Object>> singleResultSet = null;
                        try {
                            singleResultSet = packSingleResultSet(rs);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        // 将当前结果集存入总结果集列表
                        totalResultSets.add(singleResultSet);
                        // 关闭当前ResultSet，释放资源
                        rs.close();
                    }

                    // 切换到下一个结果集（无更多结果集时，hasMoreResults 为 false，退出循环）
                    hasMoreResults = stmt.getMoreResults();
                }

                return totalResultSets;
            });
        } catch (Exception e) {
            // 封装异常信息，方便排查（可根据业务需求自定义异常类型）
            throw new RuntimeException("执行SQL并处理多结果集失败，SQL：" + sql, e);
        }
    }

    /**
     * 辅助方法：将单个 ResultSet 封装为 List<Map<String, Object>>（贴合 queryForList 格式）
     * @param rs 单个结果集
     * @return 单个结果集的封装数据
     */
    private static List<Map<String, Object>> packSingleResultSet(ResultSet rs) throws Exception {
        List<Map<String, Object>> singleResultSet = new ArrayList<>();
        if (rs == null) {
            return singleResultSet;
        }

        // 获取结果集元数据（字段名、字段数量等）
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();

        // 遍历结果集的每一行，封装为 Map
        while (rs.next()) {
            Map<String, Object> rowMap = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                // 获取字段名和字段值（字段名保持数据库返回的原始格式，可按需转换为小写/大写）
                String columnName = metaData.getColumnName(i);
                Object columnValue = rs.getObject(i);
                // 存入单行 Map（键：字段名，值：字段值）
                rowMap.put(columnName, columnValue);
            }
            // 将单行 Map 存入单个结果集列表
            singleResultSet.add(rowMap);
        }

        return singleResultSet;
    }
}
