package com.hfkj.openapi.v1.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 签名工具类
 */
public class SignatureUtil {

	/**
	 * 参数签名
	 * @param param 参数
	 * @param key   秘钥
	 * @return
	 * @throws Exception
	 */
	public static String createSign(Object param, String key) throws Exception {
		Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class);
		return md5Encode(paramSort(map, key).getBytes());
	}

	/**
	 * 验证签名
	 * @param checkSign  需验证的签名字符串
	 * @param param      参数
	 * @param key        秘钥
	 * @return
	 * @throws Exception
	 */
	public static Boolean checkSign(String checkSign,Object param, String key) throws Exception {
		Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class);
		// 去除签名
		map.remove("sign");
		if (checkSign.equals(createSign(map, key))) {
			return true;
		}
		return false;
	}

	/**
	 * 参数排序
	 * @param param
	 * @return
	 */
	public static String paramSort(final Map<String, Object> param, String key) {
		Set<String> keySet = param.keySet();
		String[] keyArray = keySet.toArray(new String[keySet.size()]);
		Arrays.sort(keyArray);
		StringBuilder sb = new StringBuilder();
		for (String k : keyArray) {
			if (StringUtils.isBlank(sb.toString())) {
				sb.append(k).append("=").append(param.get(k));
			} else {
				sb.append("&").append(k).append("=").append(param.get(k));
			}
		}
		sb.append("&key=").append(key);
		return sb.toString();
	}

	/**
	 * MD5加密
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static String md5Encode(byte[] data) throws Exception {
		 // 初始化MessageDigest
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 执行摘要信息
        byte[] digest = md.digest(data);
        // 将摘要信息转换为32位的十六进制字符串
        return new String(new HexBinaryAdapter().marshal(digest));
	}

	public static void main(String[] args) throws Exception {
		String paramStr = "{\n" +
				"    \"merchantNo\": \"2023041916292112804\",\n" +
				"    \"outTradeNo\": \"ZF1130202305051459532538970034\",\n" +
				"    \"payMode\": \"WECHAT\",\n" +
				"    \"totalAmount\": 0.01,\n" +
				"    \"transType\": \"JSAPI\",\n" +
				"    \"subAppid\": \"wx52bbabe89258602a\",\n" +
				"    \"userId\": \"oz6S35CrEuPfBbpta6DuLninz2tA\",\n" +
				"    \"profitSharing\": 0,\n" +
				"    \"specialField\": \"测试\"" +
				"}";
		String sign = createSign(JSONObject.parseObject(paramStr), "cj0XLsFuryluIXiopa25IwvsurWzBeUW");
		System.out.println(sign);
	}

}
