package com.zanxiang.game.module.sdk.util;

import com.zanxiang.module.util.exception.BaseException;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xufeng
 * @date 2022/6/8 15:37
 */
public class WxPayUtil {

    /**
     * MD5加密
     */
    private static final String SIGN_MD5 = "MD5";

    /**
     * HMACSHA256加密
     */
    private static final String SIGN_HMACSHA256 = "HMACSHA256";

    /**
     * webUrl转换deepLink
     *
     * @param url : webUrl
     * @return : 返回deepLink
     * @throws Exception : 异常
     */
    public static String readUrl(String url, String serverUrl) throws Exception {
        // 定义好匹配规则
        String regex = "weixin://wap/pay?.[^\\x{4e00}-\\x{9fa5}-\"]+";
        Pattern pattern = Pattern.compile(regex);
        URL payUrl = new URL(url);
        URLConnection con = payUrl.openConnection();
        // 加referer防盗链,必须是申请的支付白名单域名
        con.setRequestProperty("Referer", serverUrl);
        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8));
        String result = null;
        String realLineStr;
        while ((realLineStr = br.readLine()) != null) {
            // 一行行查找
            Matcher matcher = pattern.matcher(realLineStr);
            if (matcher.find()) {
                result = matcher.group();
                break;
            }
        }
        return result;
    }

    /**
     * 金额处理
     *
     * @param s : 金额字符串
     * @return : 返回处理完的字符串
     */
    public static String subZeroAndDot(String s) {
        int dotIndex = s.indexOf(".");
        if (dotIndex > 0) {
            s = s.substring(0, dotIndex);
        }
        return s;
    }

    /**
     * 微信支付生成签名(MD5加密)
     *
     * @param data 待签名数据
     * @param key  API密钥
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key) {
        try {
            return generateSignature(data, key, SIGN_MD5);
        } catch (Exception e) {
            throw new BaseException("计算腾讯微信接口签名异常");
        }
    }

    /**
     * 微信支付生成签名, 指定加密方式
     *
     * @param data     待签名数据
     * @param key      API密钥
     * @param signType 签名加密方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, String signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[0]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (Objects.equals("sign", k)) {
                continue;
            }
            // 参数值为空，则不参与签名
            if (data.get(k).trim().length() > 0) {
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
            }
        }
        sb.append("key=").append(key);
        if (Objects.equals(SIGN_MD5, signType)) {
            return SignUtil.MD5(sb.toString());
        } else if (Objects.equals(SIGN_HMACSHA256, signType)) {
            return SignUtil.HMACSHA256(sb.toString(), key).toUpperCase();
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }


    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        Random random = new SecureRandom();
        String symBls = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = symBls.charAt(random.nextInt(symBls.length()));
        }
        return new String(nonceChars);
    }
}