package com.yc.ship.module.trade.utils;

import com.alibaba.fastjson.JSONObject;
import com.anji.captcha.util.MD5Util;
import com.yc.ship.framework.common.util.http.HttpUtils;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 签名工具类
 * 用于生成阳光系统要求的MD5签名
 */
public class SignUtil {
    
    /** 字符集 */
    private static final String CHARSET = "UTF-8";
    
    /**
     * 生成MD5签名
     * 用于生成阳光系统要求的MD5签名
     * @param appId 应用ID
     * @param req 请求数据
     * @param key 密钥
     * @return MD5签名
     */
    public static String generateMD5Sign(String appId, String req, String key) {
        try {
            Map<String, String> params = new HashMap<>();
            params.put("appId", appId);
            params.put("req", req);
            return generateMD5Sign(params, key);
        } catch (Exception e) {
            throw new RuntimeException("生成MD5签名失败", e);
        }
    }

    public static String generateMD5Sign(Map<String, String> map) {
        try {
            return generateMD5Sign(map);
        } catch (Exception e) {
            throw new RuntimeException("生成MD5签名失败", e);
        }
    }
    
    /**
     * 生成MD5签名
     * 按照阳光系统的签名规则生成MD5签名
     * 规则：除cipher/sign节点外，其他非空值按照字典顺序以key1=value1&key2=value2&...拼接生成加密源码A（包含最后一个&），然后追加key得到源码B，最后对源码B进行MD5加密
     * @param params 请求参数
     * @param key 密钥
     * @return MD5签名
     */
    public static String generateMD5Sign(Map<String, String> params, String key) {
        try {
            Set<String> keySet = params.keySet();
            TreeSet<String> sortKeySet = new TreeSet<>(keySet);
            StringBuilder sb = new StringBuilder();
            for (String k : sortKeySet) {
                if ("cipher".equals(k) || "sign".equals(k)) {
                    continue;
                }
                String value = params.get(k);
                if (value != null && !value.trim().isEmpty()) {
                    sb.append(k).append("=").append(value).append("&");
                }
            }
            sb.append(key);
            String data = sb.toString();
            System.out.println("data:"+data);
            return MD5Util.md5(data);
        } catch (Exception e) {
            throw new RuntimeException("生成MD5签名失败", e);
        }
    }
    
    /**
     * 将字节数组转换为十六进制字符串
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
    
    /**
     * 验证签名
     * 验证阳光系统返回的签名是否正确
     * @param appId 应用ID
     * @param req 请求数据
     * @param sign 签名
     * @param key 密钥
     * @return 是否验证通过
     */
    public static boolean verifySign(String appId, String req, String sign, String key) {
        String calculatedSign = generateMD5Sign(appId, req, key);
        return calculatedSign.equalsIgnoreCase(sign);
    }

    public static void main(String[] args) {
        String HOST = "https://lbb-admin.anyitech.ltd";
        String QUERY_URL = "/policy/querystatus.do"; // 保单状态查询接口
        RestTemplate restTemplate = new RestTemplate();
        String orderNo = "tys-20260716-YC-39";
        String APPID = "123456";   // appId
        String KEY = "goldpalm"; // key
        Map<String, String> request = new LinkedHashMap<>();
        request.put("appId", APPID);
        request.put("externalOrderNo", orderNo);
        request.put("key", KEY);
        String sign = MD5Util.md5(APPID+orderNo+KEY);

        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("appId", APPID);
        params.add("externalOrderNo", orderNo);
        params.add("sign", sign);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

        String url = HOST + QUERY_URL + "?appId=" + APPID + "&externalOrderNo=" + orderNo + "&sign=" + sign;

        String s = HttpUtils.get(url, null);
        System.out.println(s);

    }
}