using System.Security.Cryptography;
using System.Text;

namespace AxKeyEncryptor;

/// <summary>
/// 앱 공용 키(Portable) 암호화/복호화 — CryptoService.cs와 동일한 로직.
/// </summary>
internal static class CryptoHelper
{
    private static readonly byte[] AppSeed =
    {
        // "AX-Commander-Key-0104-sj.baeck" + 2-byte pad
        0x41, 0x58, 0x2D, 0x43, 0x6F, 0x6D, 0x6D, 0x61,
        0x6E, 0x64, 0x65, 0x72, 0x2D, 0x4B, 0x65, 0x79,
        0x2D, 0x30, 0x31, 0x30, 0x34, 0x2D, 0x73, 0x6A,
        0x2E, 0x62, 0x61, 0x65, 0x63, 0x6B, 0xA7, 0x5C
    };

    private static readonly byte[] AppSalt =
    {
        0x58, 0x43, 0x4D, 0x44, 0x53, 0x61, 0x6C, 0x74,
        0x9E, 0x27, 0xC1, 0x4A, 0xB3, 0x06, 0x7F, 0xD8
    };

    private static byte[]? _appKey;

    private static byte[] GetAppKey()
    {
        if (_appKey != null) return _appKey;
        using var pbkdf2 = new Rfc2898DeriveBytes(AppSeed, AppSalt, 100_000, HashAlgorithmName.SHA256);
        _appKey = pbkdf2.GetBytes(32);
        return _appKey;
    }

    public static string Encrypt(string plainText)
    {
        if (string.IsNullOrEmpty(plainText)) return "";
        var key = GetAppKey();
        using var aes = Aes.Create();
        aes.Key = key;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        aes.GenerateIV();

        using var enc = aes.CreateEncryptor();
        var plainBytes = Encoding.UTF8.GetBytes(plainText);
        var cipher = enc.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

        var result = new byte[16 + cipher.Length];
        Buffer.BlockCopy(aes.IV, 0, result, 0, 16);
        Buffer.BlockCopy(cipher, 0, result, 16, cipher.Length);
        return Convert.ToBase64String(result);
    }

    public static (bool Success, string Result) Decrypt(string base64)
    {
        if (string.IsNullOrEmpty(base64)) return (false, "입력이 비어 있습니다.");
        try
        {
            var raw = Convert.FromBase64String(base64);
            if (raw.Length < 17) return (false, "데이터가 너무 짧습니다.");

            var key = GetAppKey();
            var iv = new byte[16];
            Buffer.BlockCopy(raw, 0, iv, 0, 16);
            var cipher = new byte[raw.Length - 16];
            Buffer.BlockCopy(raw, 16, cipher, 0, cipher.Length);

            using var aes = Aes.Create();
            aes.Key = key;
            aes.IV = iv;
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            using var dec = aes.CreateDecryptor();
            var plain = dec.TransformFinalBlock(cipher, 0, cipher.Length);
            return (true, Encoding.UTF8.GetString(plain));
        }
        catch (Exception ex)
        {
            return (false, $"복호화 오류: {ex.Message}");
        }
    }
}
