using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Security.Claims;
using System.Security.Cryptography;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using ZhiZhun.AuthenticationCenter.User;
using ZhiZhun.AuthenticationCenter.Utility.RSA;

namespace ZhiZhun.AuthenticationCenter.Utility
{

    public class JWTRSService : IJWTService
    {
        private static Dictionary<string, UserBasicInfo> TokenCache = new Dictionary<string, UserBasicInfo>();

        #region Option注入
        private readonly JWTTokenOptions _JWTTokenOptions;
        public JWTRSService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
        {
            this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
        }
        #endregion


        public string GetToken(UserBasicInfo userModel)
        {
            return this.IssueToken(userModel);
        }


        private string IssueToken(UserBasicInfo user, int second = 600*6)
        {

            var claims = new[]
            {
                   //new Claim(ClaimTypes.Name, userModel.Name),
                   //new Claim("EMail", userModel.EMail),
                   //new Claim("Account", userModel.Account),
                   //new Claim("Age", userModel.Age.ToString()),
                   //new Claim("Id", userModel.Id.ToString()),
                   //new Claim("Mobile", userModel.Mobile),
                   //new Claim("Sex", userModel.Sex.ToString())//各种信息拼装
                   //new Claim(ClaimTypes.Role,userModel.Role),
                   //new Claim("Role", userModel.Role),//这个不能角色授权

                   new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                   new Claim("id", user.Id.ToString()),
                   new Claim("name", user.UserName),
                   new Claim("realName", user.RealName),
                   new Claim("reviewerCode",user.ReviewerCode),
                   new Claim("userTypeEnumName",user.UserTypeEnum.ToString()),
                   new Claim("userTypeEnumInt",((int)user.UserTypeEnum).ToString()),
                   new Claim("userTypeShortName",user.UserTypeShortName),
                   new Claim("isAdmin",(user.UserTypeEnum==UserType.SuperAdmin).ToString())



                  
                 
            };

            string keyDir = Directory.GetCurrentDirectory();
            if (RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false)
            {
                keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
            }
            var credentials = new SigningCredentials(new RsaSecurityKey(keyParams), SecurityAlgorithms.RsaSha256Signature);

            var token = new JwtSecurityToken(
               issuer: this._JWTTokenOptions.Issuer,
               audience: this._JWTTokenOptions.Audience,
               claims: claims,
                expires: DateTime.Now.AddSeconds(second),//默认10分钟有效期
                 notBefore: DateTime.Now.AddMilliseconds(30),
               signingCredentials: credentials);
            var handler = new JwtSecurityTokenHandler();
            string tokenString = handler.WriteToken(token);
            return tokenString;
        }



        /// <summary>
        /// 刷新token的有效期问题上端校验
        /// </summary>
        /// <param name="refreshToken"></param>
        /// <returns></returns>
        public string GetTokenByRefresh(string refreshToken)
        {
            if (TokenCache.ContainsKey(refreshToken))
            {
                string token = this.IssueToken(TokenCache[refreshToken], 60);
                return token;
            }
            else
            {
                return "";
            }
        }

        public Tuple<string, string> GetTokenWithRefresh(UserBasicInfo userInfo)
        {
            string token = this.IssueToken(userInfo, 60);//1分钟
            string refreshToken = this.IssueToken(userInfo, 60 * 60 * 24);//24小时
            TokenCache.Add(refreshToken, userInfo);

            return Tuple.Create(token, refreshToken);
        }

    }
}
