/**
 * @ProjectName: 智慧评标-主观分助手
 * @Package: com.zhpb.gdyd_zhpb_zgf.utils
 * @ClassName: ApiAuthUtils
 * @Description: API认证工具类
 * @Author: 张志锋
 * @Date: 2025-11-05
 * @Version: 1.0
 * @Copyright: © 2025 智慧评标-主观分助手
 */
package com.zhpb.gdyd_zhpb_zgf.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;

/**
 * API认证工具类
 * 用于验证ES平台的请求认证信息
 */
@Component
public class ApiAuthUtils {

    private static final Logger logger = LoggerFactory.getLogger(ApiAuthUtils.class);

    @Value("${private-model.appkey:}")
    private String appKey;

    /**
     * 验证请求头中的认证信息
     *
     * @param xServerParam X-Server-Param头
     * @param xCurTime X-CurTime头
     * @param xCheckSum X-CheckSum头
     * @param expectedAppId 期望的AppId
     * @return 验证是否通过
     */
    public boolean validateAuth(String xServerParam, String xCurTime, String xCheckSum, String expectedAppId) {
        try {
            // 1. 解码X-Server-Param
            String serverParamJson = new String(Base64.getDecoder().decode(xServerParam), StandardCharsets.UTF_8);
            JSONObject serverParam = JSON.parseObject(serverParamJson);

            String appid = serverParam.getString("appid");
            String csid = serverParam.getString("csid");

//            // 2. 验证appid
//            if (!expectedAppId.equals(appid)) {
//                logger.warn("AppId不匹配，期望: {}, 实际: {}", expectedAppId, appid);
//                return false;
//            }

            // 3. 计算校验和
//            String expectedCheckSum = calculateMD5(appKey + xCurTime + xServerParam);

            // 4. 验证校验和
//            if (!expectedCheckSum.equals(xCheckSum)) {
//                logger.warn("校验和不匹配，期望: {}, 实际: {}", expectedCheckSum, xCheckSum);
//                return false;
//            }

            // 5. 验证时间戳（允许5分钟的时间差）
            long currentTime = System.currentTimeMillis() / 1000;
            long requestTime = Long.parseLong(xCurTime);
            long timeDiff = Math.abs(currentTime - requestTime);

            if (timeDiff > 300) { // 5分钟
                logger.warn("请求时间戳过期，当前时间: {}, 请求时间: {}, 时间差: {}秒",
                           currentTime, requestTime, timeDiff);
                return false;
            }

            logger.info("API认证通过，AppId: {}", appid);
            return true;

        } catch (Exception e) {
            logger.error("API认证失败", e);
            return false;
        }
    }

    /**
     * 计算MD5值
     */
    private String calculateMD5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5计算失败", e);
        }
    }

    /**
     * 生成X-Server-Param
     * 用于测试或其他需要生成认证信息的地方
     */
    public Map<String, String> generateServerParam(String appId, String capabilityName) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String capabilityName24 = getCapabilityName24(capabilityName);
        String csid = appId + capabilityName24 + uuid;

        Map<String, String> serverParam = Map.of(
            "appid", appId,
            "csid", csid
        );

        return serverParam;
    }

    /**
     * 将capabilityname补齐到24位
     */
    private String getCapabilityName24(String rawCapabilityName) {
        StringBuilder sb = new StringBuilder(rawCapabilityName);
        while (sb.length() < 24) {
            sb.append("0");
        }
        return sb.toString();
    }
}
