package com.slodon.b2b2c.interceptor;

import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description: 认证拦截器
 * @author sunshihao
 * @date: 2025/7/30 10:05
 */
@Slf4j
public class BearerTokenInterceptor implements HandlerInterceptor {
    private static final String SK = "Bearer uxl9Wpzh65vXNUyDvynJDjBo";
    // 允许的最大时间差(5分钟)
    private static final long MAX_TIME_DIFF = 5*60*1000;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        log.info("request URI = {}", request.getRequestURI());
        log.info("request QueryString = {}", request.getQueryString());
        String msgId = request.getHeader("msgId");
        String signature = request.getHeader("signature");
        String nonce = request.getHeader("nonce");
        String url = request.getHeader("url");
        if(msgId==null||signature==null||nonce==null||url==null){
            log.error("Incomplete certification parameters");
            return false;
        }
        return validateAuthToken(msgId,url,nonce,signature);
    }

    private boolean validateAuthToken(String msgId, String url, String nonce, String signature) {
        try {
            long clientTime = Long.parseLong(nonce);
            long serverTime = System.currentTimeMillis();
            long timeDiff = Math.abs(serverTime - clientTime);
            if (timeDiff > MAX_TIME_DIFF) {
                log.error("Nonce overtime");
                return false;
            }
        } catch (NumberFormatException e) {
            log.error("Invalid nonce format");
            return false;
        }
        if(!signature.equals(generateSign(msgId,url,nonce))){
            log.error("Invalid signature");
            return false;
        }
        return true;
    }

    /**
     * @description:计算请求签名
     * @param msgId 唯一标识
     * @param url 请求相对路径
     * @param nonce 时间戳
     * @author sunshihao
     * @date: 2025/7/29 14:11
     */
    private String generateSign(String msgId, String url, String nonce) {
        String newStr = String.join("&", msgId,url, nonce);
        HMac mac = new HMac(HmacAlgorithm.HmacSHA256, SK.getBytes());
        return mac.digestHex(newStr);
    }

}
