package org.qinan.safetyeval.infrastructure.remote;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
 * 助通短信平台（融合云 v2 接口）main 方法测试类
 * 直接运行无需启动 Spring Boot 容器
 *
 * 接口说明：
 *  - 融合云 v2 接口，Content-Type: application/json
 *  - tKey：Unix 时间戳（秒）
 *  - password：md5(原始密码 + tKey)，单次 md5 小写
 *
 * @author safety-eval
 */
public class ZtSmsMainTest {

    /**
     * 助通短信平台配置信息
     */
    private static final String USERNAME = "qhdzyhy";
    private static final String PASSWORD = "Zcloud@88888";
    private static final String API_URL = "https://api-shss.zthysms.com/v2/sendSms";

    /**
     * 测试手机号 - 请替换为实际接收短信的手机号
     */
    private static final String TEST_MOBILE = "19122631081";
//    private static final String TEST_MOBILE = "18375715233";

    public static void main(String[] args) {
        System.out.println("========== 助通短信平台测试开始 ==========");
        System.out.println("用户名: " + USERNAME);
        System.out.println("接口地址: " + API_URL);
        System.out.println();

        // 生成6位随机验证码
        String validCode = generateVerificationCode();
        System.out.println("生成验证码: " + validCode);

        // 构建短信内容（与模板一致：模板ID 793059）
        // 注意：融合云签名必须使用全角【】，不能使用半角[]
        String content = "【秦安安全】您正在注册本系统，验证码:" + validCode + "，5分钟内有效，请勿泄露给他人，如非本人操作请忽略本条短信。";
        System.out.println("短信内容: " + content);
        System.out.println("内容字数: " + content.length());

        // 发送短信
        Map<String, Object> result = sendSms(TEST_MOBILE, content);

        System.out.println();
        System.out.println("========== 发送结果 ==========");
        for (Map.Entry<String, Object> entry : result.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        System.out.println("========== 助通短信平台测试结束 ==========");
    }

    /**
     * 发送短信（融合云 v2 接口，使用 JDK 原生 HttpURLConnection，无需任何依赖）
     *
     * @param mobile  手机号
     * @param content 短信内容
     * @return 发送结果
     */
    public static Map<String, Object> sendSms(String mobile, String content) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 融合云 v2 tKey：当前 Unix 时间戳（秒，10位）
            String tKey = String.valueOf(System.currentTimeMillis() / 1000);

            // 融合云 v2 password：md5(md5(原始密码) + tKey)，两次 md5 小写
            String md5Password = md5(PASSWORD);
            String finalPassword = md5(md5Password + tKey);

            System.out.println("tKey(时间戳): " + tKey);
            System.out.println("md5(password): " + md5Password);
            System.out.println("最终 password: " + finalPassword);

            // 构建融合云 v2 JSON 请求体（字段名：username / password / tKey / mobile / content）
            // content 为明文内容，无需 base64 编码
            String jsonBody = "{"
                    + "\"username\":\"" + USERNAME + "\","
                    + "\"password\":\"" + finalPassword + "\","
                    + "\"tKey\":\"" + tKey + "\","
                    + "\"mobile\":\"" + mobile + "\","
                    + "\"content\":\"" + escapeJson(content) + "\""
                    + "}";

            System.out.println("JSON 请求体: " + jsonBody);

            // 创建连接
            java.net.URL url = new java.net.URL(API_URL);
            java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            conn.setRequestProperty("Accept-Charset", "UTF-8");
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(30000);

            // 发送请求
            try (java.io.OutputStream os = conn.getOutputStream()) {
                os.write(jsonBody.getBytes(StandardCharsets.UTF_8));
            }

            // 读取响应
            int responseCode = conn.getResponseCode();
            System.out.println("HTTP 响应码: " + responseCode);

            java.io.InputStream inputStream;
            if (responseCode >= 400) {
                inputStream = conn.getErrorStream();
            } else {
                inputStream = conn.getInputStream();
            }

            StringBuilder response = new StringBuilder();
            try (java.io.BufferedReader reader = new java.io.BufferedReader(
                    new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
            }

            String responseBody = response.toString();
            System.out.println("响应内容: " + responseBody);

            result.put("success", responseCode == 200);
            result.put("responseCode", responseCode);
            result.put("response", responseBody);
            result.put("message", responseCode == 200 ? "短信发送成功" : "短信发送失败");

        } catch (Exception e) {
            System.err.println("短信发送异常: " + e.getMessage());
            e.printStackTrace();
            result.put("success", false);
            result.put("message", "短信发送异常: " + e.getMessage());
        }
        return result;
    }

    /**
     * MD5 加密（小写）
     *
     * @param input 待加密字符串
     * @return 32位小写 MD5 字符串
     */
    private static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b & 0xff));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException("MD5加密失败", e);
        }
    }

    /**
     * 生成6位随机验证码
     *
     * @return 6位验证码字符串
     */
    private static String generateVerificationCode() {
        return String.format("%06d", (int) (Math.random() * 1000000));
    }

    /**
     * JSON 字符串转义（处理 " \ \n \r \t 等）
     *
     * @param input 原始字符串
     * @return 转义后的字符串
     */
    private static String escapeJson(String input) {
        if (input == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            switch (c) {
                case '"':
                    sb.append("\\\"");
                    break;
                case '\\':
                    sb.append("\\\\");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                default:
                    sb.append(c);
            }
        }
        return sb.toString();
    }
}