using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using System;
using System.Security.Cryptography;
using System.Text;

namespace IRaCIS.Core.Infrastructure.Encryption;

public class AesEncryption
{
    // AES 加密(不带 IV)
    public static string Encrypt(string plainText, string key)
    {
        var keyBytes = Encoding.UTF8.GetBytes(key);

        // 使用 AES 引擎 + PKCS7 填充
        var engine = new AesEngine();
        var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
        blockCipher.Init(true, new KeyParameter(keyBytes)); // true 表示加密

        var inputBytes = Encoding.UTF8.GetBytes(plainText);
        var encryptedBytes = ProcessCipher(blockCipher, inputBytes);

        // 返回 Base64 编码的加密字符串
        return Convert.ToBase64String(encryptedBytes);
    }

    // AES 解密(不带 IV)
    public static string Decrypt(string encryptedText, string key)
    {
        var keyBytes = Encoding.UTF8.GetBytes(key);
        var cipherBytes = Convert.FromBase64String(encryptedText);

        // 使用 AES 引擎 + PKCS7 填充
        var engine = new AesEngine();
        var blockCipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
        blockCipher.Init(false, new KeyParameter(keyBytes)); // false 表示解密

        var decryptedBytes = ProcessCipher(blockCipher, cipherBytes);
        return Encoding.UTF8.GetString(decryptedBytes);
    }

    // AES 加密(带 IV)
    /// <summary>
    /// AES 密钥的长度必须是以下之一:128 位(16 字节)192 位(24 字节)256 位(32 字节)
    /// IV must be 16 bytes
    /// </summary>
    /// <param name="plainText"></param>
    /// <param name="key"></param>
    /// <param name="iv"></param>
    /// <returns></returns>
    public static string Encrypt(string plainText, string key, string iv)
    {
        var keyBytes = Encoding.UTF8.GetBytes(key.PadRight(32, '0').Substring(0, 32));
        var ivBytes = Encoding.UTF8.GetBytes(iv.PadRight(16, '0').Substring(0, 16));

        // 使用 AES 引擎 + PKCS7 填充 + CBC 模式
        var engine = new AesEngine();
        var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding());
        blockCipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // true 表示加密

        var inputBytes = Encoding.UTF8.GetBytes(plainText);
        var encryptedBytes = ProcessCipher(blockCipher, inputBytes);

        // 返回 Base64 编码的加密字符串
        return Convert.ToBase64String(encryptedBytes);
    }

    // AES 解密(带 IV)
    public static string Decrypt(string encryptedText, string key, string iv)
    {
        var keyBytes = Encoding.UTF8.GetBytes(key.PadRight(32, '0').Substring(0, 32));
        var ivBytes = Encoding.UTF8.GetBytes(iv.PadRight(16, '0').Substring(0, 16));
        var cipherBytes = Convert.FromBase64String(encryptedText);

        // 使用 AES 引擎 + PKCS7 填充 + CBC 模式
        var engine = new AesEngine();
        var blockCipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding());
        blockCipher.Init(false, new ParametersWithIV(new KeyParameter(keyBytes), ivBytes)); // false 表示解密

        var decryptedBytes = ProcessCipher(blockCipher, cipherBytes);
        return Encoding.UTF8.GetString(decryptedBytes);
    }

    // 处理加密/解密数据
    private static byte[] ProcessCipher(IBufferedCipher cipher, byte[] input)
    {
        var output = new byte[cipher.GetOutputSize(input.Length)];
        int length = cipher.ProcessBytes(input, 0, input.Length, output, 0);
        length += cipher.DoFinal(output, length);
        Array.Resize(ref output, length); // 调整输出数组大小以适应实际数据长度
        return output;
    }

    public static string DefaultKey = "12345678901234567890123456789012";

    public static string EncryptPartial(string plainText, int unencryptedPrefixLength)
    {
        if (plainText.Length <= unencryptedPrefixLength)
        {
            return Encrypt(plainText, DefaultKey); // 如果文本太短,直接加密
        }

        var prefix = plainText.Substring(0, unencryptedPrefixLength);
        var suffix = plainText.Substring(unencryptedPrefixLength);

        return prefix + Encrypt(suffix, DefaultKey); // 前缀保留,后缀加密
    }

    public static string DecryptPartial(string encryptedText, int unencryptedPrefixLength)
    {
        if (encryptedText.Length <= unencryptedPrefixLength)
        {
            return Decrypt(encryptedText, DefaultKey); // 如果文本太短,直接解密
        }

        var prefix = encryptedText.Substring(0, unencryptedPrefixLength);
        var suffix = encryptedText.Substring(unencryptedPrefixLength);

        return prefix + Decrypt(suffix, DefaultKey); // 前缀保留,后缀解密
    }

    //public static string Encrypt(string plainText)
    //{
    //    using var aes = Aes.Create();
    //    aes.Key = Encoding.UTF8.GetBytes(EncryptionKey);
    //    aes.Mode = CipherMode.ECB; // 根据需要选择加密模式,这里使用 ECB 模式
    //    aes.Padding = PaddingMode.PKCS7;

    //    var encryptor = aes.CreateEncryptor();
    //    var plainBytes = Encoding.UTF8.GetBytes(plainText);
    //    var encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

    //    return Convert.ToBase64String(encryptedBytes);
    //}

    //public static string Decrypt(string encryptedText)
    //{
    //    using var aes = Aes.Create();
    //    aes.Key = Encoding.UTF8.GetBytes(EncryptionKey);
    //    aes.Mode = CipherMode.ECB;
    //    aes.Padding = PaddingMode.PKCS7;

    //    var decryptor = aes.CreateDecryptor();
    //    var encryptedBytes = Convert.FromBase64String(encryptedText);
    //    var decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);

    //    return Encoding.UTF8.GetString(decryptedBytes);
    //}
}