using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.IdentityModel.Tokens;

namespace adas_core.Domain.Utils;

public abstract class JwtHelper
{
    public static JwtSecurityToken GetJwtToken(
        string username,
        string secret,
        string issuer,
        string audience,
        int expiration,
        Claim[]? additionalClaims = null
    )
    {
        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, username),
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.NameIdentifier, username),
            // this guarantees the token is unique
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

        if (additionalClaims != null)
        {
            var claimList = new List<Claim>(claims);
            claimList.AddRange(additionalClaims);
            claims = claimList.ToArray();
        }

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var expireDate = DateTime.UtcNow.AddMinutes(expiration);

        return new JwtSecurityToken(
            issuer,
            audience,
            expires: expireDate,
            claims: claims,
            signingCredentials: creds
        );
    }


    public static string GenerateRefreshToken()
    {
        var randomNumber = new byte[64];
        using var rng = RandomNumberGenerator.Create();
        rng.GetBytes(randomNumber);
        return Convert.ToBase64String(randomNumber);
    }

    /// <summary>
    ///     return username from claim
    /// </summary>
    /// <param name="principal"></param>
    /// <returns></returns>
    public static string? GetUsernameFromPrincipal(ClaimsPrincipal principal)
    {
        var nameClaim = principal.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier));
        return nameClaim?.Value;
    }
}