package com.njzscloud.supervisory.gps.jike.support;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;

/**
 * 即刻物联签名工具类
 */
@Slf4j
public class JikeSignUtil {

    /**
     * 计算GET请求签名 - 从Map参数
     * x-jk-param-signature = MD5(按参数名升序拼接的k=v)
     * x-jk-signature = MD5(x-jk-appid={appId}&x-jk-param-signature={paramSign}&x-jk-secret={secret}&x-jk-timestamp={timestamp})
     */
    public static String buildParamSignature(Map<String, String> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }
        TreeMap<String, String> sorted = new TreeMap<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            String v = entry.getValue();
            if (v == null || v.isEmpty()) {
                continue;
            }
            sorted.put(entry.getKey(), v);
        }
        if (sorted.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : sorted.entrySet()) {
            if (!first) {
                sb.append("&");
            }
            sb.append(entry.getKey()).append("=").append(entry.getValue());
            first = false;
        }
        String result = sb.toString();
        log.debug("Jike param-signature origin: {}", result);
        return DigestUtil.md5Hex(result, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 计算GET请求签名 - 从字符串
     * 直接对queryString签名，如 carNum=京A12345&stime=xxx&etime=xxx
     */
    public static String buildParamSignature(String queryString) {
        if (queryString == null || queryString.isEmpty()) {
            return "";
        }
        log.debug("Jike param-signature origin: {}", queryString);
        return DigestUtil.md5Hex(queryString, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 计算POST请求的签名
     * x-jk-body-signature = MD5(body)
     * x-jk-param-signature = MD5(按参数名升序拼接的k=v, 其中body=md5(body)作为参数参与)
     * x-jk-signature = MD5(x-jk-appid={appId}&x-jk-body-signature={bodySign}&x-jk-param-signature={paramSign}&x-jk-secret={secret}&x-jk-timestamp={timestamp})
     */
    public static String buildPostParamSignature(Map<String, String> params, String bodyMd5) {
        TreeMap<String, String> sorted = new TreeMap<>();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String v = entry.getValue();
                if (v == null || v.isEmpty()) {
                    continue;
                }
                sorted.put(entry.getKey(), v);
            }
        }
        sorted.put("body", StrUtil.emptyToDefault(bodyMd5, ""));
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : sorted.entrySet()) {
            if (!first) {
                sb.append("&");
            }
            sb.append(entry.getKey()).append("=").append(entry.getValue());
            first = false;
        }
        String result = sb.toString();
        log.debug("Jike POST param-signature origin: {}", result);
        return DigestUtil.md5Hex(result, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 计算body的MD5
     */
    public static String md5Hex(String content) {
        if (content == null || content.isEmpty()) {
            return "";
        }
        return DigestUtil.md5Hex(content, CharsetUtil.CHARSET_UTF_8);
    }

    /**
     * 计算GET请求的最终签名（不包含body-signature）
     */
    public static String buildGetFinalSignature(String appId, String paramMd5, String secret, long timestamp) {
        String finalContent = String.format(
                "x-jk-appid=%s&x-jk-param-signature=%s&x-jk-secret=%s&x-jk-timestamp=%d",
                appId,
                StrUtil.emptyToDefault(paramMd5, ""),
                secret,
                timestamp
        );
        log.debug("Jike GET final-signature origin: {}", finalContent);
        return DigestUtil.md5Hex(finalContent, StandardCharsets.UTF_8);
    }

    /**
     * 计算POST请求的最终签名（包含body-signature）
     */
    public static String buildFinalSignature(String appId, String bodyMd5, String paramMd5, String secret, long timestamp) {
        String finalContent = String.format(
                "x-jk-appid=%s&x-jk-body-signature=%s&x-jk-param-signature=%s&x-jk-secret=%s&x-jk-timestamp=%d",
                appId,
                StrUtil.emptyToDefault(bodyMd5, ""),
                StrUtil.emptyToDefault(paramMd5, ""),
                secret,
                timestamp
        );
        log.debug("Jike POST final-signature origin: {}", finalContent);
        return DigestUtil.md5Hex(finalContent, StandardCharsets.UTF_8);
    }
}
