package com.ruoyi.rocketmq.utils;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class WeChatWorkBot {
    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * 发送基于模板的文本消息
     * @param webhookUrl webhook地址
     * @param template 消息模板，例如："项目[项目名称]在[时间]发生[事件类型]"
     * @param fieldValues 字段值的映射，key为中文字段名，value为实际值（支持String、Number、Boolean等）
     * @return 是否发送成功
     */
    public static boolean sendTemplateMessage(String webhookUrl, String template,
                                              Map<String, Object> fieldValues) {
        return sendTemplateMessage(webhookUrl, template, fieldValues, null, null, false);
    }

    /**
     * 发送基于模板的文本消息（支持@功能）
     * @param webhookUrl webhook地址
     * @param template 消息模板
     * @param fieldValues 字段值的映射
     * @param mentionedMobiles 被@的用户列表（手机号）
     * @param mentionedAll 是否@所有人
     * @return 是否发送成功
     */
    public static boolean sendTemplateMessage(String webhookUrl, String template,
                                              Map<String, Object> fieldValues,
                                              String[] mentionedMobiles, boolean mentionedAll) {
        return sendTemplateMessage(webhookUrl, template, fieldValues, null, mentionedMobiles, mentionedAll);
    }

    /**
     * 发送基于模板的文本消息（完整参数）
     * @param webhookUrl webhook地址
     * @param template 消息模板
     * @param fieldValues 字段值的映射
     * @param defaultValue 未找到字段时的默认值
     * @param mentionedMobiles 被@的用户列表（手机号）
     * @param mentionedAll 是否@所有人
     * @return 是否发送成功
     */
    public static boolean sendTemplateMessage(String webhookUrl, String template,
                                              Map<String, Object> fieldValues, Object defaultValue,
                                              String[] mentionedMobiles, boolean mentionedAll) {
        try {
            String actualContent = processTemplate(template, fieldValues, defaultValue);
            return sendTextMessage(webhookUrl, actualContent, mentionedMobiles, mentionedAll);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 处理模板，替换字段占位符
     * @param template 消息模板
     * @param fieldValues 字段值映射
     * @param defaultValue 默认值
     * @return 处理后的消息内容
     */
    public static String processTemplate(String template, Map<String, Object> fieldValues,
                                         Object defaultValue) {
        if (template == null) return "";
        if (fieldValues == null || fieldValues.isEmpty()) {
            return template;
        }

        Pattern pattern = Pattern.compile("\\[(.*?)\\]");
        Matcher matcher = pattern.matcher(template);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            String fieldName = matcher.group(1);
            Object fieldValueObj = fieldValues.get(fieldName);
            String fieldValue = convertToString(fieldValueObj);

            // 如果字段值为空，使用默认值或保留原占位符
            if (fieldValue == null || fieldValue.trim().isEmpty()) {
                fieldValue = convertToString(defaultValue);
                if (fieldValue == null) {
                    fieldValue = "[" + fieldName + "]";
                }
            }

            // 对替换值进行转义，防止正则表达式特殊字符问题
            matcher.appendReplacement(result, Matcher.quoteReplacement(fieldValue));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    /**
     * 将对象转换为字符串
     * @param obj 要转换的对象
     * @return 字符串表示
     */
    private static String convertToString(Object obj) {
        if (obj == null) {
            return null;
        }

        if (obj instanceof String) {
            return (String) obj;
        } else if (obj instanceof Number || obj instanceof Boolean) {
            return String.valueOf(obj);
        } else if (obj instanceof java.util.Date) {
            return new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((java.util.Date) obj);
        } else {
            return obj.toString();
        }
    }

    /**
     * 验证模板中的字段是否都有对应的值
     * @param template 消息模板
     * @param fieldValues 字段值映射
     * @return 是否所有字段都有值
     */
    public static boolean validateTemplate(String template, Map<String, Object> fieldValues) {
        if (template == null || fieldValues == null) {
            return false;
        }

        Pattern pattern = Pattern.compile("\\[(.*?)\\]");
        Matcher matcher = pattern.matcher(template);

        while (matcher.find()) {
            String fieldName = matcher.group(1);
            Object fieldValue = fieldValues.get(fieldName);
            String strValue = convertToString(fieldValue);

            if (!fieldValues.containsKey(fieldName) ||
                    strValue == null ||
                    strValue.trim().isEmpty()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取模板中的所有字段名
     * @param template 消息模板
     * @return 字段名列表
     */
    public static java.util.List<String> getTemplateFields(String template) {
        java.util.List<String> fields = new java.util.ArrayList<>();
        if (template == null) {
            return fields;
        }

        Pattern pattern = Pattern.compile("\\[(.*?)\\]");
        Matcher matcher = pattern.matcher(template);

        while (matcher.find()) {
            fields.add(matcher.group(1));
        }
        return fields;
    }

    /**
     * 发送Markdown模板消息
     * @param webhookUrl webhook地址
     * @param template Markdown模板
     * @param fieldValues 字段值映射
     * @return 是否发送成功
     */
    public static boolean sendMarkdownTemplateMessage(String webhookUrl, String template,
                                                      Map<String, Object> fieldValues) {
        return sendMarkdownTemplateMessage(webhookUrl, template, fieldValues, null);
    }

    /**
     * 发送Markdown模板消息
     * @param webhookUrl webhook地址
     * @param template Markdown模板
     * @param fieldValues 字段值映射
     * @param defaultValue 默认值
     * @return 是否发送成功
     */
    public static boolean sendMarkdownTemplateMessage(String webhookUrl, String template,
                                                      Map<String, Object> fieldValues,
                                                      Object defaultValue) {
        try {
            String actualContent = processTemplate(template, fieldValues, defaultValue);
            return sendMarkdownMessage(webhookUrl, actualContent);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 发送文本消息
     */
    public static boolean sendTextMessage(String webhookUrl, String content) {
        return sendTextMessage(webhookUrl, content, null, false);
    }

    /**
     * 发送文本消息（支持@功能）
     */
    public static boolean sendTextMessage(String webhookUrl, String content,
                                          String[] mentionedMobiles, boolean mentionedAll) {
        try {
            Map<String, Object> message = new HashMap<>();
            message.put("msgtype", "text");

            Map<String, Object> textContent = new HashMap<>();
            textContent.put("content", content);

            if (mentionedAll) {
                textContent.put("mentioned_mobile_list", new String[]{"@all"});
            } else if (mentionedMobiles != null && mentionedMobiles.length > 0) {
                textContent.put("mentioned_mobile_list", mentionedMobiles);
            }

            message.put("text", textContent);

            return sendMessage(webhookUrl, mapper.writeValueAsString(message));

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 发送Markdown消息
     */
    public static boolean sendMarkdownMessage(String webhookUrl, String content) {
        try {
            Map<String, Object> message = new HashMap<>();
            message.put("msgtype", "markdown");

            Map<String, Object> markdownContent = new HashMap<>();
            markdownContent.put("content", content);

            message.put("markdown", markdownContent);

            return sendMessage(webhookUrl, mapper.writeValueAsString(message));

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static boolean sendMessage(String webhookUrl, String jsonBody) {
        try {
            URL url = new URL(webhookUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setDoOutput(true);
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(10000);

            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = jsonBody.getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            int responseCode = connection.getResponseCode();
            return responseCode == 200;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}