package com.malk.lianan.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;

/**
 * RSA签名工具类（基于Hutool）
 * 支持异常处理、日志记录、参数校验
 */
public class RSASignatureUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(RSASignatureUtil.class);
    
    // 默认使用SHA256withRSA
    private static final SignAlgorithm DEFAULT_ALGORITHM = SignAlgorithm.SHA256withRSA;
    
    /**
     * 生成签名（带完整错误处理）
     */
    public static String signSafe(String data, String privateKeyBase64) {
        return signSafe(data, privateKeyBase64, DEFAULT_ALGORITHM);
    }
    
    public static String signSafe(String data, String privateKeyBase64, SignAlgorithm algorithm) {
        // 参数校验
        if (StrUtil.isBlank(data)) {
            logger.warn("签名数据为空");
            return null;
        }
        
        if (StrUtil.isBlank(privateKeyBase64)) {
            logger.error("私钥为空");
            return null;
        }
        
        try {
            // 使用Hutool的签名工具
            Sign sign = SecureUtil.sign(algorithm, privateKeyBase64, null);
            String signature = sign.signHex(data, StandardCharsets.UTF_8);
            
            logger.debug("签名成功，数据长度: {}, 签名长度: {}", 
                        data.length(), signature.length());
            return signature;
            
        } catch (Exception e) {
            logger.error("签名失败 - 数据: {}, 算法: {}, 错误: {}", 
                        StrUtil.subPre(data, 100), // 只记录前100字符
                        algorithm.getValue(),
                        ExceptionUtil.getMessage(e));
            return null;
        }
    }
    
    /**
     * 验证签名（带完整错误处理）
     */
    public static boolean verifySafe(String data, String signatureBase64, String publicKeyBase64) {
        return verifySafe(data, signatureBase64, publicKeyBase64, DEFAULT_ALGORITHM);
    }
    
    public static boolean verifySafe(String data, String signatureBase64, 
                                    String publicKeyBase64, SignAlgorithm algorithm) {
        // 参数校验
        if (StrUtil.isBlank(data)) {
            logger.warn("验证数据为空");
            return false;
        }
        
        if (StrUtil.isBlank(signatureBase64)) {
            logger.warn("签名为空");
            return false;
        }
        
        if (StrUtil.isBlank(publicKeyBase64)) {
            logger.error("公钥为空");
            return false;
        }
        
        try {
            // 使用Hutool的签名工具
            Sign sign = SecureUtil.sign(algorithm, null, publicKeyBase64);
            boolean isValid = sign.verify(
                data.getBytes(StandardCharsets.UTF_8),
                Base64.decode(signatureBase64)
            );
            
            logger.debug("签名验证结果: {}", isValid ? "通过" : "失败");
            return isValid;
            
        } catch (Exception e) {
            logger.error("签名验证失败 - 数据长度: {}, 算法: {}, 错误: {}", 
                        data.length(),
                        algorithm.getValue(),
                        ExceptionUtil.getMessage(e));
            return false;
        }
    }
    
    /**
     * 批量验证签名
     */
    public static boolean verifyBatch(String[] dataArray, String[] signatureArray, 
                                     String publicKeyBase64) {
        if (dataArray == null || signatureArray == null || 
            dataArray.length != signatureArray.length) {
            logger.error("批量验证参数无效");
            return false;
        }
        
        for (int i = 0; i < dataArray.length; i++) {
            if (!verifySafe(dataArray[i], signatureArray[i], publicKeyBase64)) {
                logger.error("第 {} 个签名验证失败", i + 1);
                return false;
            }
        }
        
        logger.info("批量签名验证成功，共验证 {} 个签名", dataArray.length);
        return true;
    }
}