using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Logging;

namespace FitConnect;

public class EncryptionBaseClass {
    private readonly ILogger _logger;
    private RSA _rsa;

    protected EncryptionBaseClass(ILogger logger) {
        _logger = logger;
        _rsa = RSA.Create(2048);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="cert"></param>
    /// <returns></returns>
    private bool CheckCertificate(X509Certificate2 cert) => true;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="certPath"></param>
    /// <exception cref="ArgumentException"></exception>
    /// <exception cref="Exception"></exception>
    public void ImportCertificate(string certPath) {
        _logger.LogInformation("Importing certificate {CertPath}", certPath);
        var cert =
            new X509Certificate2(certPath, "", X509KeyStorageFlags.MachineKeySet);

        if (!CheckCertificate(cert)) {
            throw new ArgumentException("Certificate is not valid");
        }

        var parameters = cert.PublicKey.GetRSAPublicKey()?.ExportParameters(true);
        if (parameters == null) {
            throw new Exception("Could not get public key from certificate");
        }

        _rsa.ImportParameters(parameters.Value);
    }

    public byte[] DecryptDataAsync(byte[] data, byte[] privateKey) {
        /*
         *             var keyParams = new PbeParameters(
                    PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, numberOfIterations);
                
                var privateKey =
                    _rsa.ExportEncryptedPkcs8PrivateKey(Encoding.UTF8.GetBytes(password), keyParams);
                
                logger?.LogInformation(
                    "Private key: {}", privateKey);
    {
         */
        return _rsa.Decrypt(data, RSAEncryptionPadding.OaepSHA256);
    }

    public byte[] ExportPublicKey() {
        return _rsa.ExportRSAPublicKey();
    }

    public byte[] ExportPrivateKey() {
        return _rsa.ExportRSAPrivateKey();
    }

    public byte[] EncryptData(byte[] data, byte[]? publicKey) {
        _logger?.LogInformation(
            "Encrypting data with public key: {}",
            Convert.ToBase64String(_rsa.ExportRSAPublicKey()));

        if (publicKey != null) {
            _rsa.ImportRSAPublicKey(publicKey, out var read);
        }

        return _rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
    }
}