package com.common.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.core.JsonParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class NestedJsonParserUtil {

    private static final Logger logger = LoggerFactory.getLogger(NestedJsonParserUtil.class);

    // 配置ObjectMapper，启用容错特性
    private static final ObjectMapper objectMapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false)
            .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
            .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
            .configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
            .configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true)
            .configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);

    /**
     * 安全的JSON字符串转Map方法（支持嵌套结构）
     */
    public static LinkedHashMap<String, Object> safeParseJson(String jsonStr) {
        return safeParseJson(jsonStr, new LinkedHashMap<>());
    }

    /**
     * 安全的JSON字符串转Map方法（支持嵌套结构和自定义选项）
     */
    public static LinkedHashMap<String, Object> safeParseJson(String jsonStr, LinkedHashMap<String, Object> options) {
        if (jsonStr == null || jsonStr.trim().isEmpty()) {
            logger.warn("JSON字符串为空或null");
            //return Collections.emptyMap();
            return null;
        }

        // 获取选项,嵌套3层
        int maxDepth = (Integer) options.getOrDefault("maxDepth", 3);
        boolean allowUnquoted = (Boolean) options.getOrDefault("allowUnquoted", true);
        boolean allowSingleQuotes = (Boolean) options.getOrDefault("allowSingleQuotes", true);

        try {
            // 1. 预处理JSON字符串
           // String processedJson = preprocessJsonString(jsonStr, allowUnquoted, allowSingleQuotes);
            String processedJson =jsonStr;

            System.out.println("processedJson:"+processedJson);
            // 2. 深度验证嵌套结构
            //validateNestedStructure(processedJson, maxDepth);
            //ObjectMapper mapper = new ObjectMapper(); // 这里使用Jackson
            //System.out.println( mapper.readTree(processedJson));

            //TypeReference<Map<String, String>> typeRef1 = new TypeReference<Map<String, String>>() {};
            //Map<String, String> result1 =  objectMapper.readValue(processedJson, typeRef1);


            // 3. 尝试解析
            TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {};
            Map<String, Object> result =  objectMapper.readValue(processedJson, typeRef);

            // 4. 后处理：清理和验证解析结果
            return postProcessParsedData(result, maxDepth);

        } catch (JsonProcessingException e) {
            logger.error("JSON解析失败json:{} 错误消息： {}",jsonStr, e.getMessage());

            // 5. 尝试修复并重新解析
            try {
                String fixedJson = tryFixNestedJson(jsonStr, maxDepth);
                if (!fixedJson.equals(jsonStr)) {
                    TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {};
                    Map<String, Object> result = objectMapper.readValue(fixedJson, typeRef);
                    return postProcessParsedData(result, maxDepth);
                }
            } catch (Exception ex) {
                logger.error("JSON修复后解析仍然失败", ex);
            }
            return null;
            //return Collections.emptyMap();

        } catch (Exception e) {
            logger.error("JSON解析发生未知异常", e);
            return null;
        }
    }

    /**
     * 解析JSON为JsonNode（更灵活的嵌套处理）
     */
    public static JsonNode safeParseJsonNode(String jsonStr) {
        if (jsonStr == null || jsonStr.trim().isEmpty()) {
            return objectMapper.createObjectNode();
        }

        try {
            String processedJson = preprocessJsonString(jsonStr, true, true);
            return objectMapper.readTree(processedJson);
        } catch (Exception e) {
            logger.error("解析JSON为JsonNode失败", e);
            try {
                String fixedJson = tryFixNestedJson(jsonStr, 10);
                return objectMapper.readTree(fixedJson);
            } catch (Exception ex) {
                logger.error("修复后解析JSON Node仍然失败", ex);
                return objectMapper.createObjectNode();
            }
        }
    }

    /**
     * 预处理JSON字符串（增强版）
     */
    private static String preprocessJsonString(String jsonStr, boolean allowUnquoted, boolean allowSingleQuotes) {
        if (jsonStr == null) {
            return "{}";
        }

        String processed = jsonStr.trim();

        // 移除BOM字符
        if (processed.startsWith("\uFEFF")) {
            processed = processed.substring(1);
        }

        // 处理不同编码的空白字符
        processed = processed.replaceAll("[\\u00A0\\u2007\\u202F]", " ");

        // 确保字符串以{开头，以}结尾
        if (!processed.startsWith("{") && !processed.startsWith("[")) {
            // 尝试检测是否是JSONP格式
            if (processed.contains("(") && processed.contains(")")) {
                processed = extractJsonFromJsonp(processed);
            } else {
                // 如果不是JSON对象或数组，尝试包装成对象
                processed = "{\"data\": " + processed + "}";
            }
        }

        // 根据选项处理引号
        if (!allowSingleQuotes) {
            processed = convertSingleQuotesToDouble(processed);
        }

        return processed;
    }

    /**
     * 从JSONP中提取JSON
     */
    private static String extractJsonFromJsonp(String jsonp) {
        try {
            int start = jsonp.indexOf('(');
            int end = jsonp.lastIndexOf(')');
            if (start != -1 && end != -1 && end > start) {
                return jsonp.substring(start + 1, end);
            }
        } catch (Exception e) {
            logger.warn("JSONP提取失败", e);
        }
        return "{}";
    }

    /**
     * 验证嵌套结构深度
     */
    private static void validateNestedStructure(String jsonStr, int maxDepth) {
        int depth = calculateJsonDepth(jsonStr);
        if (depth > maxDepth) {
            throw new IllegalArgumentException("JSON嵌套深度超过限制: " + depth + " > " + maxDepth);
        }
    }

    /**
     * 计算JSON最大嵌套深度
     */
    private static int calculateJsonDepth(String jsonStr) {
        int maxDepth = 0;
        int currentDepth = 0;

        for (int i = 0; i < jsonStr.length(); i++) {
            char c = jsonStr.charAt(i);
            if (c == '{' || c == '[') {
                currentDepth++;
                maxDepth = Math.max(maxDepth, currentDepth);
            } else if (c == '}' || c == ']') {
                currentDepth--;
            }

            if (currentDepth < 0) {
                throw new IllegalArgumentException("calculateJsonDepth() JSON括号不匹配");
            }
        }

        if (currentDepth != 0) {
            throw new IllegalArgumentException("calculateJsonDepth() JSON括号不匹配");
        }

        return maxDepth;
    }

    /**
     * 尝试修复嵌套JSON
     */
    private static String tryFixNestedJson(String jsonStr, int maxDepth) {
        if (jsonStr == null) {
            return "{}";
        }

        String fixed = jsonStr.trim();

        try {
            // 修复步骤序列
            fixed = fixJsonpWrapper(fixed);
            fixed = fixUnescapedQuotesInNestedJson(fixed);
            fixed = fixSingleQuotes(fixed);
            fixed = fixUnescapedBackslashes(fixed);
            fixed = fixTrailingCommas(fixed);
            fixed = fixMissingQuotesInNestedJson(fixed);
            fixed = fixNumericIssues(fixed);
            fixed = fixBooleanIssues(fixed);
            fixed = fixNullIssues(fixed);
            fixed = fixArrayIssues(fixed);

            logger.info("尝试修复嵌套JSON字符串");
            return fixed;

        } catch (Exception e) {
            logger.warn("嵌套JSON修复过程中发生异常", e);
            return jsonStr;
        }
    }

    /**
     * 修复JSONP包装
     */
    private static String fixJsonpWrapper(String json) {
        if (json.matches("^[a-zA-Z_$][a-zA-Z0-9_$]*\\s*\\(") && json.contains(")")) {
            return extractJsonFromJsonp(json);
        }
        return json;
    }

    /**
     * 修复嵌套JSON中的未转义引号
     */
    private static String fixUnescapedQuotesInNestedJson(String json) {
        StringBuilder sb = new StringBuilder();
        boolean inString = false;
        char prevChar = 0;
        int braceCount = 0;
        int bracketCount = 0;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            // 跟踪嵌套级别
            if (c == '{') braceCount++;
            if (c == '}') braceCount--;
            if (c == '[') bracketCount++;
            if (c == ']') bracketCount--;

            // 处理字符串状态
            if (c == '"' && prevChar != '\\') {
                inString = !inString;
                sb.append(c);
            } else if (inString && c == '"' && prevChar == '\\') {
                sb.append(c);
            } else if (inString && c == '"') {
                // 在字符串中遇到未转义的双引号，需要转义
                sb.append("\\\"");
            } else {
                sb.append(c);
            }

            prevChar = c;
        }

        return sb.toString();
    }

    /**
     * 修复嵌套JSON中缺失的引号
     */
    private static String fixMissingQuotesInNestedJson(String json) {
        // 使用更复杂的正则表达式来修复嵌套对象中的键
        Pattern pattern = Pattern.compile("([{,{]\\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)(\\s*:\\s*)");
        Matcher matcher = pattern.matcher(json);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            String replacement = matcher.group(1) + "\"" + matcher.group(2) + "\"" + matcher.group(3);
            matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    /**
     * 修复数字问题
     */
    private static String fixNumericIssues(String json) {
        // 修复前导零的数字
        json = json.replaceAll(":\\s*0+(\\d+)", ":$1");
        // 修复缺失小数点的数字
        json = json.replaceAll(":\\s*(\\d+)\\.(\\s*[,\\}])", ":$1.0$2");
        return json;
    }

    /**
     * 修复布尔值问题
     */
    private static String fixBooleanIssues(String json) {
        json = json.replaceAll(":\\s*true", ":true");
        json = json.replaceAll(":\\s*false", ":false");
        json = json.replaceAll(":\\s*TRUE", ":true");
        json = json.replaceAll(":\\s*FALSE", ":false");
        return json;
    }

    /**
     * 修复null值问题
     */
    private static String fixNullIssues(String json) {
        json = json.replaceAll(":\\s*null", ":null");
        json = json.replaceAll(":\\s*NULL", ":null");
        json = json.replaceAll(":\\s*Null", ":null");
        return json;
    }

    /**
     * 修复数组问题
     */
    private static String fixArrayIssues(String json) {
        // 修复数组中的尾随逗号
        //json = json.replaceAll(",(\s*])", "$1");
       // json =json.replaceAll(",(\s[}\])])", "$1");
        return json;
    }

    /**
     * 单引号转双引号
     */
    private static String fixSingleQuotes(String json) {
        return convertSingleQuotesToDouble(json);
    }

    /**
     * 单引号转双引号（智能转换，不转换字符串内的单引号）
     */
    private static String convertSingleQuotesToDouble(String json) {
        StringBuilder sb = new StringBuilder();
        boolean inDoubleString = false;
        boolean inSingleString = false;
        char prevChar = 0;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (c == '"' && prevChar != '\\') {
                inDoubleString = !inDoubleString;
                sb.append(c);
            } else if (c == '\'' && prevChar != '\\' && !inDoubleString) {
                if (!inSingleString) {
                    sb.append('"');
                    inSingleString = true;
                } else {
                    sb.append('"');
                    inSingleString = false;
                }
            } else {
                sb.append(c);
            }

            prevChar = c;
        }

        return sb.toString();
    }

    /**
     * 修复未转义的反斜杠
     */
    private static String fixUnescapedBackslashes(String json) {
        // 简单的反斜杠转义，注意不要破坏已经转义的内容
        return json.replace("\\", "\\\\").replace("\\\\\"", "\\\"");
    }

    /**
     * 修复尾随逗号
     */
    private static String fixTrailingCommas(String json) {
        // 移除对象和数组中的尾随逗号
        //json = json.replaceAll(",(\s*[}\]])", "$1");
        return json;
    }

    /**
     * 后处理解析的数据
     */
    private static LinkedHashMap<String, Object> postProcessParsedData(Map<String, Object> data, int maxDepth) {
        if (data == null) {
            //return Collections.emptyMap();
            return null;
        }

        // 深度清理和验证
        return cleanNestedData(data, 0, maxDepth);
    }

    /**
     * 清理嵌套数据
     */
    @SuppressWarnings("unchecked")
    private static LinkedHashMap<String, Object> cleanNestedData(Map<String, Object> data, int currentDepth, int maxDepth) {
        if (currentDepth > maxDepth) {
            logger.warn("数据嵌套过深，进行截断");
           // return Collections.emptyMap();
            return null;
        }

        LinkedHashMap<String, Object> cleaned = new LinkedHashMap<>();

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

            // 清理键
            String cleanedKey = key.trim();

            // 清理值
            Object cleanedValue = cleanValue(value, currentDepth + 1, maxDepth);

            cleaned.put(cleanedKey, cleanedValue);
        }

        return cleaned;
    }

    /**
     * 清理值
     */
    @SuppressWarnings("unchecked")
    private static Object cleanValue(Object value, int currentDepth, int maxDepth) {
        if (value == null) {
            return null;
        }

        if (value instanceof Map) {
            return cleanNestedData((Map<String, Object>) value, currentDepth, maxDepth);
        } else if (value instanceof List) {
            List<Object> cleanedList = new ArrayList<>();
            for (Object item : (List<?>) value) {
                cleanedList.add(cleanValue(item, currentDepth + 1, maxDepth));
            }
            return cleanedList;
        } else if (value instanceof String) {
            return ((String) value).trim();
        }

        return value;
    }

    public static void main(String[] args) {
        // 测试复杂的嵌套JSON
        String complexJson = "{\"source\":\"portrait\",\"uuid\":\"1a26ac6e-2d77-4ada-b560-1abbcae1de98\",\"host\":{\"cpuConcurrency\":8,\"fonts\":[\"Rockwell\",\"Calibri\",\"Gadugi\",\"Leelawadee UI\",\"Bahnschrift\",\"DengXian\",\"Roboto\",\"DejaVu Sans Mono\",\"Open Sans\",\"Source Han Serif CN\"],\"hasUnity\":false,\"language\":\"zh-CN\",\"memory\":0,\"os\":\"Windows 10.0\",\"render\":\"ANGLE (Intel, Intel(R) UHD Graphics 620 Direct3D9Ex vs_3_0 ps_3_0, igdumdim32.dll-30.0.101.1338)\",\"screenResolution\":[1366,768],\"timezone\":\"Asia/Shanghai\",\"touchSupport\":true},\"network\":{\"externalIP\":{\"ip\":\"60.190.198.14\"},\"internalIP\":{\"ip\":\"\"},\"realIP\":{\"ip\":\"60.190.198.14\"}},\"browser\":{\"arch\":\"\",\"bitness\":\"\",\"canvasFingerprint\":\"7031cc506eaded347eb1b596677ec7be\",\"canvas_fp\":\"7031cc506eaded347eb1b596677ec7be\",\"canvas_fp2\":\"7031cc506eaded347eb1b596677ec7be\",\"chrome_ext\":[\"Google Office\"],\"fp2\":\"559732dbe9bafced9536c77a6c020f88\",\"is_private\":false,\"mobile\":false,\"model\":\"\",\"name\":\"Chrome\",\"os\":\"Windows 10.0\",\"tid\":\"s:16951889730ae4d6af8-b3b4b-5ede70.22c7306819e72dd14e3e5c5644e49ed42a44d857ca55f6df0acd0460f510f15f\",\"version\":\"94.0.4606.71\",\"versionNumber\":94,\"webgl_fp\":\"487f7b22f68312d2c1bbc93b1aea445b\",\"webgl_fp2\":\"487f7b22f68312d2c1bbc93b1aea445b\"},\"social\":{},\"extra\":{\"version\":\"1.1\"},\"node\":\"AQSE\"}";

            //String complexJson ="{\"sn\":\"8cf9a388-578e-4b30-ac4b-098a46dde642\",\"name\":\"茂名市住房和城乡建设局蜜罐探针\",\"send\":true,\"host\":\"172.25.142.16\",\"type\":\"agent_connect\",\"event_type_display_name\":{\"en\":\"Agent Connect Event\",\"cn\":\"探针连接建立\"},\"node\":\"WRx3\"}";
        // 测试有问题的嵌套JSON
        String problematicJson = "{\"source\":\"portrait\",\"uuid\":\"1a26ac6e-2d77-4ada-b560-1abbcae1de98\",\"host\":{\"cpuConcurrency\":8,\"fonts\":[\"Rockwell\",\"Calibri\",\"Gadugi\",\"Leelawadee UI\",\"Bahnschrift\",\"DengXian\",\"Roboto\",\"DejaVu Sans Mono\",\"Open Sans\",\"Source Han Serif CN\"],\"hasUnity\":false,\"language\":\"zh-CN\",\"memory\":0,\"os\":\"Windows 10.0\",\"render\":\"ANGLE (Intel, Intel(R) UHD Graphics 620 Direct3D9Ex vs_3_0 ps_3_0, igdumdim32.dll-30.0.101.1338)\",\"screenResolution\":[1366,768],\"timezone\":\"Asia/Shanghai\",\"touchSupport\":true},\"network\":{\"externalIP\":{\"ip\":\"60.190.198.14\"},\"internalIP\":{\"ip\":\"\"},\"realIP\":{\"ip\":\"60.190.198.14\"}},\"browser\":{\"arch\":\"\",\"bitness\":\"\",\"canvasFingerprint\":\"7031cc506eaded347eb1b596677ec7be\",\"canvas_fp\":\"7031cc506eaded347eb1b596677ec7be\",\"canvas_fp2\":\"7031cc506eaded347eb1b596677ec7be\",\"chrome_ext\":[\"Google Office\"],\"fp2\":\"559732dbe9bafced9536c77a6c020f88\",\"is_private\":false,\"mobile\":false,\"model\":\"\",\"name\":\"Chrome\",\"os\":\"Windows 10.0\",\"tid\":\"s:16951889730ae4d6af8-b3b4b-5ede70.22c7306819e72dd14e3e5c5644e49ed42a44d857ca55f6df0acd0460f510f15f\",\"version\":\"94.0.4606.71\",\"versionNumber\":94,\"webgl_fp\":\"487f7b22f68312d2c1bbc93b1aea445b\",\"webgl_fp2\":\"487f7b22f68312d2c1bbc93b1aea445b\"},\"social\":{},\"extra\":{\"version\":\"1.1\"},\"node\":\"AQSE\"}";

        // 测试解析
        System.out.println("=== 正常嵌套JSON解析 ===");
        LinkedHashMap<String, Object> result1 = NestedJsonParserUtil.safeParseJson(complexJson);
        System.out.println("解析结果: " + result1);

        System.out.println("\\n=== 有问题嵌套JSON解析 ===");
        LinkedHashMap<String, Object> result2 = NestedJsonParserUtil.safeParseJson(problematicJson);
        System.out.println("解析结果: " + result2);

        /**
        System.out.println("\\n=== 嵌套值获取 ===");
        String userName = NestedJsonUtils.getNestedString(result1, "user.name");
        Integer userAge = NestedJsonUtils.getNestedInteger(result1, "user.profile.age");
        String city = NestedJsonUtils.getNestedString(result1, "user.profile.address.city");

        System.out.println("用户名: " + userName);
        System.out.println("年龄: " + userAge);
        System.out.println("城市: " + city);
         **/
        System.out.println("\\n=== 扁平化处理 ===");

        LinkedHashMap<String, Object> flattened = NestedJsonUtils.flattenNestedJson(result1);
        System.out.println("扁平化结果: " + flattened);

    }


}