package com.cool.store.utils;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.internal.http.HttpMethod;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;

/**
 * @Author suzhuhong
 * @Date 2025/3/26 19:32
 * @Version 1.0
 */
@Slf4j
public class SignatureUtils {
    
    
    private static final String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCML5dEU4e6BAopiSjxeA2ZNs3VeIXoWe8HpHHGhZP1xE+4vbPv3L4Z7XexeoPMiBcluyGKSRl5jwuvYvcF9A2nGPhxVugYOxpC+TuGVu3TE7a2E/+1iMFfdNCYgqMxfnTe2Svo+X5anc5AcpKar2+AYcdZ4emMQLwrJkEB9endpWPruqC7dCUmAwxByMi525fdipFEDsAIf9ozkBuqwyQa0/RwQ+fyOT87pJ58z7gLXcZxW8YaXNAS5hmdA6/0GqZQQyDTXxZ/nDPpeIIk8PC8VNrgllCxwDtyDMWfUg8+yTlHAjsCX7MGRM3Gd3QcfqrvlIK/Lvn/9qAWcY3KOU1JAgMBAAECggEADwvnokmN6qEW3yTt7FcMrJqFhslgJBONFKapoJuDSVCIFwXji5YHoHxMydOi1F/yDhZzD+bvMU0xfaJzbaPnmD0Vo4KmuD0VwUUDhtSLQ8ncpVfprRgv2zlMT2ZMMlqGnEm2jRPEZGEGO4QgqLI2V1MHZOYa3XcwSzhYp2d38dZvPxWnF9mDt26BbM5Eb3D4oAb+J8rOVsbXEbVTdVTsJmhLOUEK84r2fUCLqHALAOc/za28ToupYD/QRWT6K5nWKDclDWn2tnz3MQJrEYMVvGDVCryqltljd2XB4MXnBZxEYDZyonxxI5M1Avb9mHUyy2wMYSeTUocSnVjgCZPnFQKBgQC34xs/Q0lDTpRdS0a8odzey4jew/nfo8TqzAa2/vomRHkOAoXyqci71tCos5836hxprkhvj1KMauB/rFzCZYfr5a2UMM70p/vuYv5JhTMDStTVx9OPcydZDeK77OY39qPhkW4Tm10BBUodzVV0YhxbCfRmSRSF2FuZCSLdd5bmpQKBgQDDKTUYuA+s/cFt0QsKkRRBm/ONQnETCCXo87NP9RzspcydkULnmuRMLWP4zqHN5TccL0MyI7hyHZ7AwU3qoi4JXFo8k5rRcSdwaBy99B+ZKF159l7chVHE8p4tYSmxwoIOIbpfXA2nfp+zaknt6lb8DSeCw8lewsEZUwmU++bu1QKBgB5M5t16yeS0WxAwajyE828m3KvQYSkvxC/oZKbcxv1tRQFA+y9sOK5zDDjwOCkvg3UKidcQJ8sJhWqkTTifIFGHrB2CGWgJEiNK3pngv/In74A2iC7YC8DJ3/WVaK4KDyEJJLlIXX/gjkDw58bgr8l0j3gXTLFtYFKMRdl2bkAdAoGAHwhNZhnWfEZ5XHHyFIMPOoOGzb5z5nfUN1+Q8rTiHYsbpy5y+gr6JFbPX7/ToL7C7ZtiTvW5HYQyOypBrn6NXXWu75T0+DrK76fOcjIAWEU/3+XaHayhXPTLTCH4FEj+jyqzzPgBP9H1qPzMtqUdocShtLxXJ9dGBzXZ/zOy++UCgYAHgaZC5Jz8+p5Ka7YtPZXpDXt1gUh2bmzIcAOBlizE+ElWZN/skybumos3lP8JOXdB65jEuXI9V0rc6n/KpOLY2Xfy6CX78RpWVXPc30D10DxUVI9hyEU+Xg4t9rwOAVhZaOwjhaEqpdvDrjMmX0bBVwCI2QXt7GnjUPqibNyEbQ==";

    /**
     * 生成 HmacSHA256 签名
     * @param data 待签名字符串
     * @param secret 密钥
     * @return 签名（Hex小写）
     */
    public static String hmacSha256(String data, String secret) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            mac.init(secretKey);
            byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash).toLowerCase();
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("HmacSHA256签名失败", e);
        }
    }

    /**
     * 正新菜品市场系统 验签
     * @param httpMethod
     * @param uri
     * @param requestBody
     * @param timeStamp
     * @param random
     * @return
     */
    public static String sign(String httpMethod, String uri, String requestBody, String timeStamp, String random) throws Exception {
        log.info("timeStamp+random:{}",timeStamp + "/" + random);
        String plainText = new StringJoiner("&")
                .add("CRM")
                .add(httpMethod.toUpperCase())
                .add(uri)
                .add(requestBody)
                .add(timeStamp)
                .add(random)
                .toString();

        log.info("plainText:{}",plainText);
        // 签名算法
        Signature signature = Signature.getInstance("SHA256WithRSA");

        PrivateKey privateKey = readPrivateKey(SignatureUtils.privateKey);
        // 签名
        signature.initSign(privateKey);
        signature.update(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(signature.sign());
    }


    private static  PrivateKey readPrivateKey(String key) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] keys = Base64.getDecoder().decode(key);
        try {
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keys);
            return keyFactory.generatePrivate(keySpec);
        } catch (InvalidKeySpecException e) {
            throw new IllegalStateException("私钥⽆效：", e);
        }
    }

    /**
     * 生成待签名字符串（参数按字母排序 + appkey + timestamp）
     * @param params 请求参数Map（需提前过滤空值）
     * @param appKey 应用Key
     * @param timestamp 时间戳（毫秒）
     */
    public static String buildSignString(Map<String, Object> params, String appKey, long timestamp) {
        TreeMap<String, Object> sortedParams = new TreeMap<>(params);
        StringBuilder sb = new StringBuilder();

        // 拼接排序后的参数
        sortedParams.forEach((key, value) ->{
            if (Objects.isNull(value)|| (value instanceof String && StringUtil.isBlank(value.toString())) || (value instanceof  Double &&((Double) value).intValue()==0)){
                log.info("0或者空值不参与签名");
            }else {
                if (value instanceof Double){
                    sb.append(key).append("=").append(((Double) value).intValue()).append("&");
                }else {
                    sb.append(key).append("=").append(value).append("&");
                }
            }
        });

        sb.append("appkey=").append(appKey).append("&timestamp=").append(timestamp);

        return sb.toString();
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
