using AutoTurnOver.Utility;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace AutoTurnOver.Models
{
    public class NoLoginAttribute : Attribute
    {
    }

    /// <summary>
    /// 操作权限
    /// </summary>
    public class UseActionAttribute : Attribute
    {
    }

    public class UserFilterAttribute : ActionFilterAttribute
    {

        /// <summary>
        ///  请求验证，当前验证部分不要抛出异常，ExceptionFilter不会处理
        /// </summary>
        /// <param name="context">请求内容信息</param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //filterContext.HttpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
            var context = filterContext.HttpContext;

            var isDefined = false;
            var controllerActionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
            if (controllerActionDescriptor != null)
            {
                isDefined = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                  .Any(a => a.GetType().Equals(typeof(NoLoginAttribute)));
            }
            if (!isDefined)
            {
                isDefined = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(inherit: true)
                  .Any(a => a.GetType().Equals(typeof(NoLoginAttribute)));
            }
            if (isDefined) return;

            string token = context.Request.Headers["Authorization"];
            if (string.IsNullOrWhiteSpace(token))
            {
                token = context.Request.Query["token"].FirstOrDefault();
            }
            if ((!string.IsNullOrWhiteSpace(token)) && (!"null".Equals(token)))
            {
                token = WebUtility.UrlDecode(token);
                var tokenDecode = WebUtility.UrlDecode(token);
                context.Response.Cookies.Delete("BailunToken");
                context.Response.Cookies.Append("BailunToken", tokenDecode, new CookieOptions { Domain = "bailuntec.com" });
                //Console.WriteLine(tokenDecode);
                var dd = new JwtSecurityToken(tokenDecode.Replace("Bearer ", ""));
                var userId = dd.Claims.FirstOrDefault(m => m.Type == "UserId").Value;
                var exp = dd.Claims.FirstOrDefault(m => m.Type == "exp").Value;

                var userData = RedisHelper.Get("sso-aims-authorization-user-info-" + userId+"-"+ exp, () => {
                    var getTokenValid = ConfigHelper.GetValue("Saas_GetTokenValid").ToString();
                    var getUser = ConfigHelper.GetValue("Saas_GetUser").ToString();
                    var getMenus = ConfigHelper.GetValue("Saas_GetMenus").ToString();

                    var httpHelper = new HHttpHelper();
                    httpHelper.AddHeaderValue("Authorization", token);
                    string tokenValidJson = httpHelper.Request(getTokenValid, HHttpHelper.RequestType.GET);
                    var objToken = tokenValidJson.ToObj<TokenResult>();
                    if (objToken.result)
                    {
                        string userStr = httpHelper.Request(getUser, HHttpHelper.RequestType.GET);
                        tokenUser user_info = userStr.ToObj<tokenUser>();
                        user_info.result.has_admin = false;
                        var menusStr = httpHelper.Request(getMenus + "?ProjectCode=Bailun_aims", HHttpHelper.RequestType.GET);
                        var saas_menus = menusStr.ToObj<saas_result_dto<Saas_MenusDto>>();
                        if (saas_menus == null)
                        {
                            throw new Exception("saas系统异常：权限获取失败");
                        }
                        else
                        {
                            if (saas_menus.statusCode != 200)
                            {
                                throw new Exception(saas_menus.message);
                            }
                            else
                            {
                                if (saas_menus.result == null)
                                {
                                    throw new Exception("saas系统异常：权限获取失败");
                                }
                                else
                                {
                                    if (!saas_menus.result.success)
                                    {
                                        throw new Exception("saas系统异常：权限获取失败");
                                    }
                                    else
                                    {
                                        user_info.result.menuInfoDtos = saas_menus.result.menuInfoDtos;
                                    }
                                }
                            }
                        }
                        return user_info;
                    }
                    else
                    {
                        context.Response.StatusCode = 401;
                        filterContext.Result = new ContentResult
                        {
                            Content = "未授权",
                            StatusCode = StatusCodes.Status401Unauthorized,
                            ContentType = "text/html;charset=utf-8"
                        };
                        return null;
                    }
                },24 * 60);

                #region 效验操作权限
                var isAciton = false;
                if (controllerActionDescriptor != null)
                {
                    // 判断控制器或者acion 是否需要验证
                    isAciton = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                      .Any(a => a.GetType().Equals(typeof(UseActionAttribute)))
                      ||
                      controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(inherit: true)
                      .Any(a => a.GetType().Equals(typeof(UseActionAttribute)))
                      ;

                    //需要验证
                    if (isAciton)
                    {
                        SaasUserInfo userInfoData = userData.result;
                        var controllerName = controllerActionDescriptor.ControllerTypeInfo.Name.Replace("Controller", "");
                        var requst_url = ("/api/" + controllerName + "/" + controllerActionDescriptor.MethodInfo.Name);
                        if (!userInfoData.menuInfoDtos.Any(s => s.menuUrl_list != null && s.menuUrl_list.Any(m => m != null && requst_url.Equals(m, StringComparison.OrdinalIgnoreCase))))
                        {
                            context.Response.StatusCode = 401;
                            filterContext.Result = new ContentResult
                            {
                                Content = "无该功能的操作权限",
                                StatusCode = StatusCodes.Status401Unauthorized,
                                ContentType = "text/html;charset=utf-8"
                            };
                        }
                    }

                }
                else
                {
                    throw new Exception("程序异常");
                }


                #endregion



            }
            else
            {
                context.Response.StatusCode = 401;
                filterContext.Result = new ContentResult
                {
                    Content = "未授权",
                    StatusCode = StatusCodes.Status401Unauthorized,
                    ContentType = "text/html;charset=utf-8"
                };
            }

        }

    }
}
