package com.huimv.employment.common.util;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 敏感字段 AES 加解密工具。
 * <p>
 * 采用 AES/ECB/PKCS5Padding 确定性加密：同一明文 + 同一密钥始终产生相同密文，
 * 从而支持对 {@code fe_user.mobile_enc} 做等值查询（按加密手机号查找用户）。
 * </p>
 * <p>
 * 密钥配置项：{@code fe.security.mobile-aes-key}，生产环境请使用足够长度的随机密钥
 * 并通过环境变量 {@code FE_MOBILE_AES_KEY} 注入。
 * </p>
 * <p>
 * 注意：ECB 模式适用于短且唯一的字段（如手机号）；如需加密更长或重复率高的数据，
 * 后续可升级为 AES-GCM + 独立 hash 索引字段。
 * </p>
 */
public final class AesUtils {

    /** AES 算法：ECB 模式 + PKCS5 填充，128 bit 密钥 */
    private static final String ALGORITHM = "AES/ECB/PKCS5Padding";

    private AesUtils() {
    }

    /**
     * 加密明文，返回 Base64 编码的密文字符串。
     *
     * @param plainText 明文（如手机号）
     * @param secret    AES 密钥字符串（取前 16 字节作为 128 bit 密钥）
     * @return Base64 密文，写入数据库 mobile_enc 字段
     */
    public static String encrypt(String plainText, String secret) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, buildKey(secret));
            byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception ex) {
            throw new IllegalStateException("encrypt failed", ex);
        }
    }

    /**
     * 解密密文，返回明文字符串。
     * <p>仅在后端授权场景使用（如客服查询、实名核验），禁止返回前端或写入日志。</p>
     *
     * @param cipherText Base64 密文
     * @param secret     与加密时相同的密钥
     * @return 解密后的明文
     */
    public static String decrypt(String cipherText, String secret) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, buildKey(secret));
            byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception ex) {
            throw new IllegalStateException("decrypt failed", ex);
        }
    }

    /**
     * 从密钥字符串构建 128 bit AES 密钥。
     * 密钥不足 16 字节时右侧补零，超过 16 字节时截断。
     */
    private static SecretKeySpec buildKey(String secret) {
        byte[] keyBytes = new byte[16];
        byte[] secretBytes = secret.getBytes(StandardCharsets.UTF_8);
        System.arraycopy(secretBytes, 0, keyBytes, 0, Math.min(secretBytes.length, keyBytes.length));
        return new SecretKeySpec(keyBytes, "AES");
    }
}
