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

namespace GameList.Infrastructure;

public static class PasswordHasher
{
    private const int SaltSize = 16;
    private const int KeySize = 32;
    private const int Iterations = 100_000;

    public static (byte[] Hash, byte[] Salt) HashPassword(string password)
    {
        if (string.IsNullOrEmpty(password))
            throw new ArgumentException("Password required", nameof(password));

        var salt = RandomNumberGenerator.GetBytes(SaltSize);
        var hash = PBKDF2(password, salt);
        return (hash, salt);
    }

    public static bool Verify(string password, byte[] hash, byte[] salt)
    {
        if (hash is null || salt is null || hash.Length == 0 || salt.Length == 0) return false;
        var computed = PBKDF2(password, salt);
        return CryptographicOperations.FixedTimeEquals(computed, hash);
    }

    private static byte[] PBKDF2(string password, byte[] salt)
    {
        return Rfc2898DeriveBytes.Pbkdf2(
            Encoding.UTF8.GetBytes(password),
            salt,
            Iterations,
            HashAlgorithmName.SHA256,
            KeySize);
    }
}
