using System;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Threading.Tasks;
using EasyCaching.Core;
using IRaCIS.Core.Domain.Share;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;

namespace IRaCIS.WX.CoreApi.Auth
{
    public class AuthMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IEasyCachingProvider _provider;
        public AuthMiddleware(RequestDelegate next, IEasyCachingProvider provider)
        {
            _next = next;
            _provider = provider;
        }
        /// <summary>
        ///为了前端 一段时间无操作，需要重新登陆
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext httpContext)
        {
           
            var isLogin = httpContext.Request.Path.ToString().ToLower().Contains("login");
            
            var result = await httpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);

            if (!isLogin)
            {
                if (!result.Succeeded)
                {
                    httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    await httpContext.Response.WriteAsync("Unauthorized");
                }
                else
                {
                    var toekn = result.Properties.Items[".Token.access_token"];
                    var jwtHandler = new JwtSecurityTokenHandler();
                    JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(toekn);
                    object userId;
                    jwtToken.Payload.TryGetValue("id", out userId);

                    var cacheValueExist = await _provider.ExistsAsync(userId.ToString()); //Get<string>(userId.ToString()).ToString();
                    if (!cacheValueExist)
                    {
                        httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        await httpContext.Response.WriteAsync("Unauthorized");
                    }
                    else
                    {
                        await _provider.SetAsync(userId.ToString(), userId.ToString(), TimeSpan.FromMinutes(15));
                        httpContext.User = result.Principal;
                        await _next.Invoke(httpContext);
                    }
                }
            }
            else await _next.Invoke(httpContext);
        }
    }
}
