package com.ygtx.common.utils;

import cn.hutool.core.codec.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * AES 解密工具类
 * 用于解密前端传过来的加密数据
 * 配置与前端保持一致：AES-128-CBC 模式，PKCS7/PKCS5 填充
 */
public class AesDecryptUtil {

    // 密钥和 IV（必须与前端保持一致）
    private static final String KEY_STR = "ygtxgxtkey030206";
    private static final String IV_STR = "ygtxgxt-iv030206";

    // 密钥字节数组
    private static final byte[] KEY_BYTES;
    private static final byte[] IV_BYTES;

    static {
        KEY_BYTES = KEY_STR.getBytes(StandardCharsets.UTF_8);
        IV_BYTES = IV_STR.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * AES 解密（与前端 encryptAES 方法对应）
     * @param encryptedText Base64 编码的加密字符串
     * @return 解密后的明文
     */
    public static String decrypt(String encryptedText) {
        try {
            if(StringUtils.isEmpty(encryptedText)){
                return encryptedText;
            }
            // 1. Base64 解码
            byte[] encryptedBytes = Base64.decode(encryptedText);

            // 2. 创建密钥和 IV 规范
            SecretKeySpec secretKeySpec = new SecretKeySpec(KEY_BYTES, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV_BYTES);

            // 3. 创建 Cipher 实例并初始化为解密模式
            // Java 使用 PKCS5Padding，但 AES 中 PKCS5Padding = PKCS7Padding
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            // 4. 解密
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

            // 5. 转换为字符串
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES 解密失败: " + e.getMessage(), e);
        }
    }

    /**
     * AES 加密（用于测试验证）
     * @param plainText 明文
     * @return Base64 编码的加密字符串
     */
    public static String encrypt(String plainText) {
        try {
            if(StringUtils.isEmpty(plainText)){
                return plainText;
            }
            // 1. 创建密钥和 IV 规范
            SecretKeySpec secretKeySpec = new SecretKeySpec(KEY_BYTES, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(IV_BYTES);

            // 2. 创建 Cipher 实例并初始化为加密模式
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

            // 3. 加密
            byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

            // 4. Base64 编码
            return Base64.encode(encryptedBytes);
        } catch (Exception e) {
            throw new RuntimeException("AES 加密失败: " + e.getMessage(), e);
        }
    }

    /**
     * 验证解密是否正确（单元测试用）
     */
    public static boolean verify() {
        try {
            String originalText = "Hello, World! 这是一个测试文本 123456";

            // 加密
            String encrypted = encrypt(originalText);
            System.out.println("加密后: " + encrypted);

            // 解密
            String decrypted = decrypt(encrypted);
            System.out.println("解密后: " + decrypted);

            // 验证
            boolean success = originalText.equals(decrypted);
            System.out.println("验证结果: " + (success ? "成功" : "失败"));

            return success;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 解密前端传来的数据示例
     */
    public static String decryptFromFrontend(String frontendEncryptedText) {
        try {
            // 注意：前端传过来的可能是 URL 安全的 Base64，需要处理
            String base64Text = frontendEncryptedText
                    .replace("-", "+")
                    .replace("_", "/")
                    .replaceAll("\\s", "");

            // 确保 Base64 长度是 4 的倍数
            int padding = base64Text.length() % 4;
            if (padding > 0) {
                base64Text += "====".substring(0, 4 - padding);
            }

            return decrypt(base64Text);
        } catch (Exception e) {
            throw new RuntimeException("解密前端数据失败", e);
        }
    }

    public static void main(String[] args) {
        // 验证工具类是否正确
        verify();

        // 测试解密前端加密的数据
        try {
            // 这个字符串应该是前端 encryptAES("测试数据") 返回的结果
            String frontendEncrypted = "请在这里填入前端加密后的Base64字符串";
            if (!frontendEncrypted.isEmpty()) {
                String decrypted = decrypt(frontendEncrypted);
                System.out.println("解密前端数据: " + decrypted);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
