package cn.novalon.gym.manage.common.util;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * HTML 转义工具类
 * 防止 XSS 注入攻击
 *
 * @author 付嘉
 * @date 2026-05-29
 */
public class HtmlEscapeUtil {

    private static final Map<Character, String> ESCAPE_MAP = new HashMap<>();
    private static final Map<String, Character> UNESCAPE_MAP = new HashMap<>();
    private static final Pattern HTML_PATTERN = Pattern.compile("<[^>]*>");

    static {
        // HTML 特殊字符转义映射
        ESCAPE_MAP.put('&', "&amp;");
        ESCAPE_MAP.put('<', "&lt;");
        ESCAPE_MAP.put('>', "&gt;");
        ESCAPE_MAP.put('"', "&quot;");
        ESCAPE_MAP.put('\'', "&#39;");

        // 反向映射
        UNESCAPE_MAP.put("&amp;", '&');
        UNESCAPE_MAP.put("&lt;", '<');
        UNESCAPE_MAP.put("&gt;", '>');
        UNESCAPE_MAP.put("&quot;", '"');
        UNESCAPE_MAP.put("&#39;", '\'');
    }

    /**
     * 转义 HTML 特殊字符
     *
     * @param input 原始字符串
     * @return 转义后的字符串
     */
    public static String escape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        StringBuilder result = new StringBuilder();
        for (char c : input.toCharArray()) {
            String escaped = ESCAPE_MAP.get(c);
            if (escaped != null) {
                result.append(escaped);
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    /**
     * 反转义 HTML 特殊字符
     *
     * @param input 转义后的字符串
     * @return 原始字符串
     */
    public static String unescape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        String result = input;
        for (Map.Entry<String, Character> entry : UNESCAPE_MAP.entrySet()) {
            result = result.replace(entry.getKey(), String.valueOf(entry.getValue()));
        }
        return result;
    }

    /**
     * 移除所有 HTML 标签
     *
     * @param input 原始字符串
     * @return 移除标签后的字符串
     */
    public static String stripHtmlTags(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        return HTML_PATTERN.matcher(input).replaceAll("");
    }

    /**
     * 安全转义（转义 + 移除标签）
     *
     * @param input 原始字符串
     * @return 安全字符串
     */
    public static String sanitize(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        // 先移除 HTML 标签，再转义特殊字符
        String noTags = stripHtmlTags(input);
        return escape(noTags);
    }

    /**
     * 判断是否包含 HTML 标签
     *
     * @param input 原始字符串
     * @return true-包含, false-不包含
     */
    public static boolean containsHtmlTags(String input) {
        if (input == null || input.isEmpty()) {
            return false;
        }
        return HTML_PATTERN.matcher(input).find();
    }
}