using CloudBuilder.Core.DependencyInjection.Form;
using CloudBuilder.Core.DependencyInjection.Request;
using CloudBuilder.Security.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;

namespace CloudBuilder.Security.Utility
{
    public static class LoginContextExtensions
    {
        public static bool Assert(this LoginContext loginContext, string permissionName)
        {
            return Assert(loginContext, permissionName, Operate.None);
        }
        public static bool Assert(this LoginContext loginContext, string permissionName, string operate)
        {
            Operate op = Enum.Parse<Operate>(operate);
            return Assert(loginContext, permissionName, op);
        }

        public static bool Assert(this LoginContext loginContext, string permissionName, Operate operate)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            switch (operate)
            {
                case Operate.None:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName) == true;
                case Operate.Find:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && x.ViewIndc == Operate.Find.ToString()) == true;
                case Operate.Insert:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && x.CreateIndc == Operate.Insert.ToString()) == true;
                case Operate.Update:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && x.AmendIndc == Operate.Insert.ToString()) == true;
                case Operate.Delete:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && x.DeleteIndc == Operate.Insert.ToString()) == true;
                default:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName) == true;
            }
        }

        public static bool AssertDependents(this LoginContext loginContext, string permissionName, string dependent)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent) == true;
        }
    }

    public class LoginContextPermission
    {
        private readonly IContext loginContext;
        private IServiceProvider ServiceProvider { get; }
        public LoginContextPermission()
        {
            ServiceProvider = ApplicationServiceContext.ServiceProvider;
            loginContext = ServiceProvider.GetService<IContext>()!;
        }

        public bool Assert(string permissionName)
        {
            return Assert(permissionName, Operate.None);
        }
        public bool Assert(string permissionName, string operate)
        {
            Operate op = Enum.Parse<Operate>(operate);
            return Assert(permissionName, op);
        }

        public bool Assert(string permissionName, Operate operate)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            switch (operate)
            {
                case Operate.None:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName) == true;
                case Operate.Find:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && YesNoPolicy.IsYes(x.ViewIndc)) == true;
                case Operate.Insert:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && YesNoPolicy.IsYes(x.CreateIndc)) == true;
                case Operate.Update:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && YesNoPolicy.IsYes(x.AmendIndc)) == true;
                case Operate.Delete:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName && YesNoPolicy.IsYes(x.DeleteIndc)) == true;
                default:
                    return permissionInfo.Permissions?.Any(x => x.PermissionName == permissionName) == true;
            }
        }

        public bool AssertDependents(string permissionName, string dependent)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent) == true;
        }

        public bool AssertDependents(string permissionName, string dependent, Operate operate)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            switch (operate)
            {
                case Operate.None:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent) == true;
                case Operate.Find:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent && YesNoPolicy.IsYes(x.ViewIndc)) == true;
                case Operate.Insert:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent && YesNoPolicy.IsYes(x.CreateIndc)) == true;
                case Operate.Update:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent && YesNoPolicy.IsYes(x.AmendIndc)) == true;
                case Operate.Delete:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent && YesNoPolicy.IsYes(x.DeleteIndc)) == true;
                default:
                    return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent) == true;
            }
        }

        public bool AssertByFunctionName(string pageName)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();

            return Assert(permissionInfo.PermissionFunctionMaps.Where(x => x.PageName == pageName).FirstOrDefault()?.PermissionName!, Operate.None);
        }
        public bool AssertByFunctionName(string pageName, string operate)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            Operate op = Enum.Parse<Operate>(operate);
            return Assert(permissionInfo.PermissionFunctionMaps.Where(x => x.PageName == pageName).FirstOrDefault()?.PermissionName!, op);
        }

        public bool AssertByFunctionName(string pageName, Operate operate)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            return Assert(permissionInfo.PermissionFunctionMaps.Where(x => x.PageName == pageName).FirstOrDefault()?.PermissionName!, operate);
        }

        public bool AssertDependentsByFunctionName(string pageName, string dependent)
        {
            SecurityUserPermissionInfo permissionInfo = loginContext.GetPermissionInfo();
            string permissionName = permissionInfo.PermissionFunctionMaps.Where(x => x.PageName == pageName).FirstOrDefault()?.PermissionName!;
            return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permissionName && x.DependentDetailName == dependent) == true;
        }
    }
}
