using System.Security.Cryptography;

namespace Fast.Shared.Logic
{
    public static class Encryption
    {

        private const string commonKey = "xrwtst2526";
        public static string Encrypt(string vstrTextToBeEncrypted, string key = commonKey)
        {
            string vstrEncryptionKey = key;
            byte[] bytValue;
            byte[] bytKey;
            byte[] bytEncoded = Array.Empty<byte>();
            byte[] bytIV = { 121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62 };

            int intLength;
            MemoryStream objMemoryStream = new();
            CryptoStream objCryptoStream;
            Aes objAes;
            vstrTextToBeEncrypted = StripNullCharacters(vstrTextToBeEncrypted);

            bytValue = Encoding.ASCII.GetBytes(vstrTextToBeEncrypted.ToCharArray());

            intLength = vstrEncryptionKey.Length;

            if (intLength >= 32)
            {
                vstrEncryptionKey = vstrEncryptionKey[..32];
            }
            else
            {
                intLength = vstrEncryptionKey.Length;
                int intRemaining = 32 - intLength;
                vstrEncryptionKey += new string('X', intRemaining);
            }

            bytKey = Encoding.ASCII.GetBytes(vstrEncryptionKey.ToCharArray());

            objAes = Aes.Create();

            try
            {
                objCryptoStream = new CryptoStream(objMemoryStream, objAes.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write);
                objCryptoStream.Write(bytValue, 0, bytValue.Length);
                objCryptoStream.FlushFinalBlock();

                bytEncoded = objMemoryStream.ToArray();
                objMemoryStream.Close();
                objCryptoStream.Close();
            }
            catch
            {
            }

            return Convert.ToBase64String(bytEncoded);
        }

        public static string Decrypt(string vstrStringToBeDecrypted, string key = commonKey)
        {
            string vstrDecryptionKey = key;
            byte[] bytIV = { 121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62 };
            Aes objAes = Aes.Create();
            byte[] bytDataToBeDecrypted = Convert.FromBase64String(vstrStringToBeDecrypted);

            int intLength = vstrDecryptionKey.Length;

            if (intLength >= 32)
            {
                vstrDecryptionKey = vstrDecryptionKey[..32];
            }
            else
            {
                intLength = vstrDecryptionKey.Length;
                int intRemaining = 32 - intLength;
                vstrDecryptionKey += new string('X', intRemaining);
            }

            byte[] bytDecryptionKey = Encoding.ASCII.GetBytes(vstrDecryptionKey.ToCharArray());
            byte[] bytTemp = new byte[bytDataToBeDecrypted.Length + 1];

            MemoryStream objMemoryStream = new(bytDataToBeDecrypted);

            try
            {
                CryptoStream objCryptoStream = new(objMemoryStream, objAes.CreateDecryptor(bytDecryptionKey, bytIV), CryptoStreamMode.Read);
                objCryptoStream.ReadExactly(bytTemp);
                objMemoryStream.Close();
                objCryptoStream.Close();
            }
            catch
            {
            }

            return StripNullCharacters(Encoding.ASCII.GetString(bytTemp));
        }

        private static string StripNullCharacters(string vstrStringWithNulls)
        {
            var strStringWithOutNulls = vstrStringWithNulls.Replace("\0", string.Empty);

            return strStringWithOutNulls;
        }
    }
}
