using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OneMore.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace OneMore.Areas.Admin.Models
{
    public class JLActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // do something before the action executes
            //获取标签，有标签才认证
            MemberInfo[] members = context.Controller.GetType().GetMembers();
            var Acl = members.Where(o => String.Compare(o.Name, context.RouteData.Values["action"].ToString(), true) == 0);

            var Acls = 0;
            foreach (var item in Acl)
            {
                Acls = Acls + item.GetCustomAttributes(typeof(DescriperAttribute), false).Count();
            }

            if (Acls > 0)
            {
                var eMsg = new eMsgv();
                var mems = context.HttpContext.Session.GetObj<Memlogin>("mems");
                if (mems == null) {

                    eMsg.Msgtxt = "抱歉，您未登录或登录已超时，请重新登录。";
                    eMsg.v = "重新登录";
                    eMsg.Udo = (int)eMsgv.go.goAction;
                    eMsg.RoutName = "Houtai";
                    eMsg.Controller = "Fo";
                    eMsg.Action = "Index";

                    

                    context.HttpContext.Session.SetObj("emsg", eMsg);

                    context.Result = new RedirectToRouteResult("Houtai", new { Controller = "Fo", Action = "noPemit",jstxt= "<script>alert('no!');window.history.back()</script>" });
                    return;
                }

                if (!Ones.uPermit(
                    context.RouteData.Values["area"].ToString()+"_"+context.RouteData.Values["controller"].ToString(),
                    context.RouteData.Values["action"].ToString()))
                    {//不许可

                    eMsg.Msgtxt = "抱歉，您无权进行此项操作。";
                    eMsg.v = "返回";
                    eMsg.Udo = (int)eMsgv.go.goBack;                   

                    context.HttpContext.Session.SetObj("emsg", eMsg);

                    context.Result =new RedirectToRouteResult("Houtai", new { Controller = "Fo", Action = "noPemit" });

                    return;

                }
                else
                {
                    return;
                }
            }




        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // do something after the action executes
        }
    }



    #region 后台工作模块
    public class Mtreepx
    {
        public string mtid { set; get; }//菜单id
        public int mtpx { set; get; }//序号
    }
    public class AdminWorks
    {

        /// <summary>
        /// 把页面的树排序遍历的json传过来，由此解析成数组，交由数据库修改排序
        /// 只解析一维简单数据
        /// </summary>
        public List<Mtreepx> GetMenuTreespx(string tjson)
        {
            var mlist = new List<Mtreepx>();
            var m = new Mtreepx();

            var jo = (JArray)JsonConvert.DeserializeObject(tjson);

            for(var i = 0; i < jo.Count; i++)
            {
                m = new Mtreepx();
                m.mtid = (string)jo[i]["id"];
                if (jo[i]["px"] != null)
                {
                    m.mtpx = (int)jo[i]["px"];
                }
                else { m.mtpx = 0; }
                
                mlist.Add(m);
            }


            return mlist;
        }

        public string GetMenuTrees(string jb, List<Amenu> Treels)
        {//遍历后台菜单 jb 级别，Treels 数据列表

            var Treejson = "";
            var Mtree = Treels.Where(s => s.mjb == jb).OrderBy(s => s.px).ToList();

            foreach (var item in Mtree)
            {
                Treejson = Treejson + "{\"id\":\"" + item.muid + "\", \"name\":\"" + item.mname + "\"";
                if (Treels.Where(s => s.mjb == item.muid).Count() > 0)
                {
                    Treejson = Treejson + ",\"open\": \"true\", \"childOuter\": false,";
                    Treejson = Treejson + "\"children\":[";
                    Treejson = Treejson + GetMenuTrees(item.muid, Treels);
                    Treejson = Treejson + "]";

                }
                Treejson = Treejson + "},";

            }
            Treejson = Treejson + "end";
            Treejson = Treejson.Replace(",]", "]");
            Treejson = Treejson.Replace(",end", "");
            Treejson = Treejson.Replace("end", "");
            return Treejson;
        }

        public string GetMenuTreesCk(string jb, List<Amenu> Treels,List<Qxlist> cknodes)
        {//遍历后台菜单 jb 级别，Treels 数据列表

            var Treejson = "";
            var Mtree = Treels.Where(s => s.mjb == jb).OrderBy(s => s.px).ToList();

            foreach (var item in Mtree)
            {
                Treejson = Treejson + "{\"id\":\"" + item.muid + "\", \"name\":\"" + item.mname + "\"";

                if (cknodes.Where(c=>c.v== item.muid).Count()>0) { Treejson = Treejson + ",\"checked\":\"true\""; }

                if (Treels.Where(s => s.mjb == item.muid).Count() > 0)
                {
                    Treejson = Treejson + ",\"open\": \"true\", \"childOuter\": false,";
                    Treejson = Treejson + "\"children\":[";
                    Treejson = Treejson + GetMenuTreesCk(item.muid, Treels, cknodes);
                    Treejson = Treejson + "]";

                }
                Treejson = Treejson + "},";

            }
            Treejson = Treejson + "end";
            Treejson = Treejson.Replace(",]", "]");
            Treejson = Treejson.Replace(",end", "");
            Treejson = Treejson.Replace("end", "");
            return Treejson;
        }

    }

    #endregion

    #region 遍历Control与Action
    //获取控制器
    public class ReflectMenuModel
    {
        public string MenuName { set; get; }//自定义控制器名
        public string MenuController { set; get; }//控制器名
        public string MenuAC { set; get; }//区域_控制器
        public string MenuLink { set; get; }// 菜单链接 
        public List<ReflectMenuActionModel> MenuMx { set; get; }// 菜单明细
    }
    public class ReflectMenuActionModel
    {
        public string ActionCode { set; get; }//Action名
        public string ActionName { set; get; }//自定义Action名
        public string ActionMemo { set; get; }//自定义Action备注
        public string ActioniCode { set; get; }//自定义Action权限代码，便于权限验证
        public bool ActionSuper { set; get; }//是否完全掌控者才能进入 
    }
    //自定义标签类[Description("我的控制器")][Descriper(Name = "联系", Memo = "这里是公司联系方式")]
    public class DescriperAttribute : Attribute
    {
        public string Name { set; get; }//名称 
        public string Memo { set; get; }//备注 
        public string Icode { set; get; }//自定义权限代码
        public bool Super { set; get; } = false;// 开发者及完全掌控者 S
    }

    public class GlistCAmenus
    {
        public static List<ReflectMenuModel> GetALLMenuByReflection()
        {
            List<ReflectMenuModel> controls = new List<ReflectMenuModel>();
            var asm = Assembly.GetEntryAssembly();
            List<Type> typeList = new List<Type>();
            var types = asm.GetTypes();
            foreach (Type type in types)
            {
                string s = type.FullName.ToLower();
                //{AFTER} Core2.0时再改进
                //if (s.EndsWith("controller"))
                    typeList.Add(type);
            }
            typeList.Sort(delegate (Type type1, Type type2) { return type1.FullName.CompareTo(type2.FullName); });
            foreach (Type type in typeList)
            {
                ReflectMenuModel rm = new ReflectMenuModel();
                rm.MenuMx = new List<ReflectMenuActionModel>();
                MemberInfo[] members = type.GetMembers();

                string controller = type.Name.Replace("Controller", "");
                var descriptionList = type.GetTypeInfo().GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (descriptionList != null && descriptionList.Count() > 0)
                {
                    foreach (var dm in descriptionList)
                    {
                        DescriptionAttribute da = dm as DescriptionAttribute;
                        rm.MenuName = da.Description;
                        break;
                    }
                }
                else
                {
                    rm.MenuName = controller;
                }
                rm.MenuController = controller;
                rm.MenuAC = (type.FullName.Replace(asm.GetName().Name, "")).ToLower()
                    .Replace("areas", "")
                    .Replace("controller", "").Replace(".s.", "_");

                rm.MenuAC = rm.MenuAC
                    .Replace("model", "").Replace(".s.", "*");


                rm.MenuAC = rm.MenuAC.Replace(".", "");


                string url = "/AMTF/" + controller + "/";
                rm.MenuLink = url;
                foreach (var m in members)
                {
                    if (m.DeclaringType.GetTypeInfo().Attributes.HasFlag(TypeAttributes.Public) != true)
                        continue;
                    ReflectMenuActionModel rma = new ReflectMenuActionModel();
                    string action = m.Name;
                    rma.ActionCode = action;
                    if (action.Contains("<") || action.Contains(">")) continue;

                    bool isNeedAdd = true;
                    //// 反射系统自己带的其它属性  

                    //反射自定义属性DescriperAttribute,过滤不需要的  
                    isNeedAdd = false;
                    var deserlist = m.GetCustomAttributes(typeof(DescriperAttribute), false);
                    if (deserlist != null && deserlist.Count() > 0)
                    {
                        foreach (var cm in deserlist)
                        {
                            DescriperAttribute da = cm as DescriperAttribute;

                            rma.ActionSuper = da.Super;
                            rma.ActionMemo = da.Memo;
                            rma.ActionName = da.Name;
                            rma.ActioniCode = da.Icode;
                            isNeedAdd = true;
                            break;
                        }
                    }
                    if (!isNeedAdd)
                    {
                        continue;
                    }
                    if (rma.ActionName == null)
                    {
                        rma.ActionName = action;
                    }

                    var om = controls.FirstOrDefault(pm => pm.MenuLink == url);
                    if (om == null)
                    {
                        rm.MenuMx.Add(rma);
                        controls.Add(rm);
                    }
                    else
                    {
                        var som = om.MenuMx.FirstOrDefault(pm => pm.ActionCode == action);
                        if (som == null)
                        {
                            rm.MenuMx.Add(rma);
                        }
                    }
                }
            }
            return controls;
        }

        //加载未进行权限组规划的权限
        public static List<ReflectMenuModel> GetALLweiqx(List<Qxlist> hadqx)
        {
            List<ReflectMenuModel> controls = new List<ReflectMenuModel>();
            var asm = Assembly.GetEntryAssembly();
            List<Type> typeList = new List<Type>();
            var types = asm.GetTypes();
            foreach (Type type in types)
            {
                string s = type.FullName.ToLower();
                typeList.Add(type);
            }
            typeList.Sort(delegate (Type type1, Type type2) { return type1.FullName.CompareTo(type2.FullName); });
            foreach (Type type in typeList)
            {
                ReflectMenuModel rm = new ReflectMenuModel();
                rm.MenuMx = new List<ReflectMenuActionModel>();
                MemberInfo[] members = type.GetMembers();

                string controller = type.Name.Replace("Controller", "");
                var descriptionList = type.GetTypeInfo().GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (descriptionList != null && descriptionList.Count() > 0)
                {
                    foreach (var dm in descriptionList)
                    {
                        DescriptionAttribute da = dm as DescriptionAttribute;
                        rm.MenuName = da.Description;
                        break;
                    }
                }
                else
                {
                    rm.MenuName = controller;
                }

                rm.MenuController = controller;
                rm.MenuAC = (type.FullName.Replace(asm.GetName().Name, "")).ToLower()
                    .Replace("areas", "")
                    .Replace("controller", "").Replace(".s.", "_");

                rm.MenuAC = rm.MenuAC
                    .Replace("model", "").Replace(".s.", "*");

                rm.MenuAC = rm.MenuAC.Replace(".", "");


                string url = "/AMTF/" + controller + "/";
                rm.MenuLink = url;
                foreach (var m in members)
                {
                    if (m.DeclaringType.GetTypeInfo().Attributes.HasFlag(TypeAttributes.Public) != true)
                        continue;
                    ReflectMenuActionModel rma = new ReflectMenuActionModel();
                    string action = m.Name;
                    rma.ActionCode = action;
                    if (action.Contains("<") || action.Contains(">")) continue;

                    bool isNeedAdd = true;
                    //// 反射系统自己带的其它属性  

                    //反射自定义属性DescriperAttribute,过滤不需要的  
                    isNeedAdd = false;
                    var deserlist = m.GetCustomAttributes(typeof(DescriperAttribute), false);
                    if (deserlist != null && deserlist.Count() > 0)
                    {
                        foreach (var cm in deserlist)
                        {
                            DescriperAttribute da = cm as DescriperAttribute;

                            rma.ActionSuper = da.Super;
                            rma.ActionMemo = da.Memo;
                            rma.ActionName = da.Name;
                            rma.ActioniCode = da.Icode;
                            isNeedAdd = true;

                            if (hadqx.Where(f=> String.Compare(f.c, rm.MenuAC, true) == 0 && String.Compare(f.a, rma.ActionCode, true) == 0).Count()>0)
                            {
                                isNeedAdd = false;
                            }
                            if (da.Super == true)
                            {
                                isNeedAdd = false;
                            }

                            break;
                        }
                    }
                    if (!isNeedAdd)
                    {
                        continue;
                    }
                    if (rma.ActionName == null)
                    {
                        rma.ActionName = action;
                    }

                    var om = controls.FirstOrDefault(pm => pm.MenuLink == url);
                    if (om == null)
                    {
                        rm.MenuMx.Add(rma);
                        controls.Add(rm);
                    }
                    else
                    {
                        var som = om.MenuMx.FirstOrDefault(pm => pm.ActionCode == action);
                        if (som == null)
                        {
                            rm.MenuMx.Add(rma);
                        }
                    }
                }
            }
            return controls;
        }

        //加载已进行权限组规划的权限
        public static List<ReflectMenuModel> GetALLhadqx(List<Qxlist> hadqx)
        {
            List<ReflectMenuModel> controls = new List<ReflectMenuModel>();
            var asm = Assembly.GetEntryAssembly();
            List<Type> typeList = new List<Type>();
            var types = asm.GetTypes();
            foreach (Type type in types)
            {
                string s = type.FullName.ToLower();
                typeList.Add(type);
            }
            typeList.Sort(delegate (Type type1, Type type2) { return type1.FullName.CompareTo(type2.FullName); });
            foreach (Type type in typeList)
            {
                ReflectMenuModel rm = new ReflectMenuModel();
                rm.MenuMx = new List<ReflectMenuActionModel>();
                MemberInfo[] members = type.GetMembers();

                string controller = type.Name.Replace("Controller", "");
                var descriptionList = type.GetTypeInfo().GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (descriptionList != null && descriptionList.Count() > 0)
                {
                    foreach (var dm in descriptionList)
                    {
                        DescriptionAttribute da = dm as DescriptionAttribute;
                        rm.MenuName = da.Description;
                        break;
                    }
                }
                else
                {
                    rm.MenuName = controller;
                }

                rm.MenuController = controller;
                rm.MenuAC = (type.FullName.Replace(asm.GetName().Name, "")).ToLower()
                    .Replace("areas", "")
                    .Replace("controller", "").Replace(".s.", "_");

                rm.MenuAC = rm.MenuAC
                    .Replace("model", "").Replace(".s.", "*");

                rm.MenuAC = rm.MenuAC.Replace(".", "");


                string url = "/AMTF/" + controller + "/";
                rm.MenuLink = url;
                foreach (var m in members)
                {
                    if (m.DeclaringType.GetTypeInfo().Attributes.HasFlag(TypeAttributes.Public) != true)
                        continue;
                    ReflectMenuActionModel rma = new ReflectMenuActionModel();
                    string action = m.Name;
                    rma.ActionCode = action;
                    if (action.Contains("<") || action.Contains(">")) continue;

                    bool isNeedAdd = true;
                    //// 反射系统自己带的其它属性  

                    //反射自定义属性DescriperAttribute,过滤不需要的  
                    isNeedAdd = false;
                    var deserlist = m.GetCustomAttributes(typeof(DescriperAttribute), false);
                    if (deserlist != null && deserlist.Count() > 0)
                    {
                        foreach (var cm in deserlist)
                        {
                            DescriperAttribute da = cm as DescriperAttribute;

                            rma.ActionSuper = da.Super;
                            rma.ActionMemo = da.Memo;
                            rma.ActionName = da.Name;
                            rma.ActioniCode = da.Icode;
                            isNeedAdd = true;

                            if (hadqx.Where(f => String.Compare(f.c, rm.MenuAC, true) == 0 && String.Compare(f.a, rma.ActionCode, true) == 0).Count() > 0)
                            {
                                isNeedAdd = true;
                            }
                            else { isNeedAdd = false; }
                            if (da.Super == true)
                            {
                                isNeedAdd = false;
                            }

                            break;
                        }
                    }
                    if (!isNeedAdd)
                    {
                        continue;
                    }
                    if (rma.ActionName == null)
                    {
                        rma.ActionName = action;
                    }

                    var om = controls.FirstOrDefault(pm => pm.MenuLink == url);
                    if (om == null)
                    {
                        rm.MenuMx.Add(rma);
                        controls.Add(rm);
                    }
                    else
                    {
                        var som = om.MenuMx.FirstOrDefault(pm => pm.ActionCode == action);
                        if (som == null)
                        {
                            rm.MenuMx.Add(rma);
                        }
                    }
                }
            }
            return controls;
        }

    }
    #endregion





}
