using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;


using Microsoft.IdentityModel.Tokens;

namespace Services {

  public interface IJwtService {
    string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles);
    JwtSecurityToken ReadJwtToken(string token);
  }
  public class JwtService : IJwtService {
    private readonly JwtSecurityTokenHandler _tokenHandler;
    private readonly IJwtServiceSettings _serviceSettings;

    public JwtService(IJwtServiceSettings serviceSettings) {
      _serviceSettings = serviceSettings;
      _tokenHandler = new JwtSecurityTokenHandler();
    }

    public string CreateJwtToken(IEnumerable<string> issuer, DateTime expires, string userId, string userEmail, string userName, IEnumerable<string> userRoles) {
      var key = Convert.FromBase64String(_serviceSettings.Secret);

      // add roles to claims identity from database
      var claims = new List<Claim>() {
        new Claim(ClaimTypes.Actor, userId),
        new Claim(ClaimTypes.Email, userEmail),
        new Claim(ClaimTypes.NameIdentifier, userName),
        // new Claim(ClaimTypes.Webpage, issuer)
      };

      foreach (var role in userRoles)
        claims.Add(new Claim(ClaimTypes.Role, role));

      foreach (var iss in issuer)
        claims.Add(new Claim(ClaimTypes.Webpage, iss));

      var token = _tokenHandler.CreateToken(new SecurityTokenDescriptor {
        IssuedAt = DateTime.UtcNow,
        Subject = new ClaimsIdentity(claims),
        Expires = expires,
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature),
      });

      return _tokenHandler.WriteToken(token);
    }

    public JwtSecurityToken ReadJwtToken(string token) => _tokenHandler.ReadJwtToken(token);
  }
}
