using System;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;
using Strata.Configuration.Client.Models.Jazz;

namespace Strata.Base.Internal.Encryptors
{

    public class UserSaltEncryptionMethod : IPasswordEncryptionMethod
    {

        #region  Declarations 

        private const int NUMBER_ITERATIONS = 100000;

        #endregion

        #region  Methods 

        public string Encode(string username, string anOrgPin, string aNewPassword, Guid aUserGUID, string aSalt)
        {
            if (username is null)
            {
                throw new ArgumentNullException(nameof(username));
            }

            if (anOrgPin is null)
            {
                throw new ArgumentNullException(nameof(anOrgPin));
            }

            if (aNewPassword is null)
            {
                throw new ArgumentNullException(nameof(aNewPassword));
            }

            if (aSalt is null)
            {
                throw new ArgumentNullException(nameof(aSalt));
            }

            // Get encryption key from config, throw if not found
            string encryptionKey = ConfigurationManager.AppSettings[nameof(StrataJazzOptions.UserSaltEncryptionKey)];
            if (string.IsNullOrEmpty(encryptionKey))
            {
                throw new ConfigurationErrorsException("UserSaltEncryptionKey not found in configuration");
            }

            // Combine salt with encryption key
            string saltAndPepper = aSalt + encryptionKey;

            // Use UTF8 encoding to properly handle Unicode characters
            using (var deriveBytes = new Rfc2898DeriveBytes(aNewPassword, Encoding.UTF8.GetBytes(saltAndPepper), NUMBER_ITERATIONS, HashAlgorithmName.SHA256))
            {
                byte[] password = deriveBytes.GetBytes(24);
                return Convert.ToBase64String(password);
            }
        }

        #endregion

    }

}