using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Mall.Common.API;
using Mall.Common.Plugin;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Mall.WebApi.Helper
{
    /// <summary>
    /// Token帮助类
    /// </summary>
    public class ApiTokenHelper
    {
        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="tokenUser"></param>
        /// <returns></returns>
        public static string CreateToken(TokenUserInfo tokenUser)
        {
            IDateTimeProvider provider = new UtcDateTimeProvider();
            var now = provider.GetNow().AddMinutes(-1);
            var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // or use JwtValidator.UnixEpoch
            var secondsSinceEpoch = Math.Round((now - unixEpoch).TotalSeconds);
            var payload = new Dictionary<string, object>
                                {
                                        {"iat",secondsSinceEpoch },
                                        {"exp",secondsSinceEpoch+ Common.Config.JwtExpirTime},
                                        {"mall_userInfo",tokenUser }
                                };
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            string token = encoder.Encode(payload, Common.Config.JwtSecretKey);
            return token;
        }

        /// <summary>
        /// 解析Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static TokenUserInfo ParsingToken(string token)
        {
            TokenUserInfo tokenUser = new TokenUserInfo();
            if (!string.IsNullOrEmpty(token))
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
                //token为之前生成的字符串
                var json = decoder.Decode(token, Common.Config.JwtSecretKey, verify: true);
                if (!string.IsNullOrEmpty(json))
                {
                    JObject jwtJson = JObject.Parse(json);
                    var mall_userInfo = JObject.Parse(jwtJson.GetStringValue("mall_userInfo"));
                    tokenUser.requestFrom = (Common.Enum.ApiRequestFromEnum)mall_userInfo.GetInt("requestFrom");
                    tokenUser.uid = mall_userInfo.GetStringValue("uid");
                }
            }
            return tokenUser;
        }

        /// <summary>
        /// 解析Request参数
        /// </summary>
        /// <param name="request"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public static JObject GetRequestParameters(HttpRequest request, ref string token)
        {
            JObject parm = new JObject();
            //如果参数是json实体对象，获取序列化后的数据
            request.EnableBuffering();
            string responseData = "";
            try
            {
                using (var reader = new StreamReader(request.Body, encoding: Encoding.UTF8))
                {
                    var body = reader.ReadToEndAsync();
                    responseData = body.Result;
                    request.Body.Position = 0;
                }
            }
            catch (Exception ex)
            {
                Common.Plugin.LogHelper.Write(ex, "GetRequestParameters");
            }
            if (!string.IsNullOrWhiteSpace(responseData.Trim()))
            {
                try
                {
                    parm = JObject.Parse(responseData);
                    request.HttpContext.Items[Common.GlobalKey.UserPostInfo] = responseData;
                }
                catch (Exception ex)
                {
                    LogHelper.Write(ex, string.Format("DoApiMonitorLog:{0}", responseData));
                }
                token = JsonHelper.GetStringValue(parm, "token");
            }
            return parm;
        }
    }
}
