using AutoMapper.Configuration;
using Microsoft.IdentityModel.Tokens;
using OnlineAssessment.Domain.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace OnlineAssessment.Data
{
    public class Security
    {
        private static Microsoft.Extensions.Configuration.IConfiguration _config;

        public Security(Microsoft.Extensions.Configuration.IConfiguration config)
        {
            _config = config;
        }
        public static string GetNewSalt(int saltLength = 4)
        {
            string guidResult = Guid.NewGuid().ToString().Replace("-", "");
            if (saltLength <= 0 || saltLength >= guidResult.Length)
            {
                throw new ArgumentException(string.Format("Length must be between 1 to {0}", guidResult.Length));
            }
            return guidResult.Substring(0, saltLength);
        }

        public static string GetSaltedHashPassword(string salt, string password)
        {
            string sourceText = string.Concat(salt.Trim(), password.Trim());

            //Create an encoding object to ensure the encoding standard for the source text
            UnicodeEncoding ue = new UnicodeEncoding();

            //Retrieve a byte array based on the source text
            Byte[] byteSourceText = ue.GetBytes(sourceText);

            //Instantiate an MD5 Provider object
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            //Compute the hash value from the source
            Byte[] byteHash = md5.ComputeHash(byteSourceText);

            //And convert it to String format for return
            return Convert.ToBase64String(byteHash);
        }

        internal static string GetAccessToken()
        {
            return Guid.NewGuid().ToString().Replace("-", "");
        }

        internal static string GetJwtToken(UserViewModel userInfo)
        {
            var jwtSecretyKey = _config["Jwt:Key"];
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecretyKey));
            var credential = new SigningCredentials(securityKey,SecurityAlgorithms.HmacSha256);

            return "";
        }


        /// <summary>
        /// Encrypt with Character Choice
        /// </summary>
        /// <param name="encryptString"></param>
        /// <returns></returns>
        public static string Encrypt(string encryptString)
        {
            string EncryptionKey = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            byte[] clearBytes = Encoding.Unicode.GetBytes(encryptString);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(clearBytes, 0, clearBytes.Length);
                        cs.Close();
                    }
                    encryptString = Convert.ToBase64String(ms.ToArray());
                }
            }
            return encryptString;
        }


        /// <summary>
        /// Decrypt with Character Choice
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        public static string Decrypt(string cipherText)
        {
            string EncryptionKey = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            cipherText = cipherText.Replace(" ", "+");
            byte[] cipherBytes = Convert.FromBase64String(cipherText);
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(cipherBytes, 0, cipherBytes.Length);
                        cs.Close();
                    }
                    cipherText = Encoding.Unicode.GetString(ms.ToArray());
                }
            }
            return cipherText;
        }


        public static string EncryptString(string s)
        {
            byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes(s);
            string encrypted = Convert.ToBase64String(b);
            return encrypted;
        }

        public static string DecryptString(string s)
        {
            byte[] b;
            string decrypted = string.Empty;
            try
            {
                b = Convert.FromBase64String(s);
                decrypted = System.Text.ASCIIEncoding.ASCII.GetString(b);
            }
            catch (FormatException fe)
            {
                throw fe;
            }
            return decrypted;
        }

    }
}
