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

namespace Performance.Api
{
    public class JwtTokenHelper
    {
        private static byte[] secret = Encoding.ASCII.GetBytes(Consts.Secret);

        public static JwtToken GenerateToken(Claim[] claims, int expiresMinute)
        {
            var authTime = DateTime.UtcNow;
            var expiresAt = authTime.AddMinutes(expiresMinute);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Audience = Consts.Audience,
                Issuer = Consts.Issuer,
                Subject = new ClaimsIdentity(claims),
                Expires = expiresAt,
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(secret), SecurityAlgorithms.HmacSha256Signature)
            };
            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return new JwtToken
            {
                access_token = tokenString,
                token_type = "Bearer",
                auth_time = new DateTimeOffset(authTime).ToUnixTimeSeconds(),
                expires_at = new DateTimeOffset(expiresAt).ToUnixTimeSeconds()
            };
        }

        public static ClaimsPrincipal GetPrincipal(string token)
        {
            try
            {
                // 创建一个JwtSecurityTokenHandler类，用来后续操作
                var tokenHandler = new JwtSecurityTokenHandler();
                // 将字符串token解码成token对象
                var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;

                if (jwtToken == null) return null;

                // 生成验证token的参数
                var validationParameters = new TokenValidationParameters()
                {
                    RequireExpirationTime = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidAudience = Consts.Audience,
                    ValidIssuer = Consts.Issuer,
                    IssuerSigningKey = new SymmetricSecurityKey(secret)
                };

                var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
                // 返回秘钥的主体对象，包含秘钥的所有相关信息
                return principal;
            }

            catch (Exception)
            {
                return null;
            }
        }
    }

    public class JwtToken
    {
        /// <summary>
        /// access token
        /// </summary>
        public string access_token { get; set; }
        /// <summary>
        /// token type
        /// </summary>
        public string token_type { get; set; }
        /// <summary>
        /// 授权时间
        /// </summary>
        public long auth_time { get; set; }
        /// <summary>
        /// 过期时间
        /// </summary>
        public long expires_at { get; set; }
    }

    public static class JwtClaimTypes
    {
        public const string Id = "id";
        public const string Login = "login";
        public const string RealName = "realname";
        public const string Mail = "mail";
        public const string AppName = "appname";
        public const string Device = "device";
        public const string Department = "department";
    }

    public static class Consts
    {
        public const string Secret = "DH4neb6Aipe1ortdalusvo8iosQiBIYupLNPTu3j40PZ9tBbLrPD4mAmDVsB7nZw";
        public const string Issuer = "suvalue";
        public const string Audience = "jixiao.suvalue.com";
    }
}
