using Grand.Business.Core.Interfaces.Common.Security;
using Grand.Business.Core.Interfaces.System.Admin;
using Grand.Domain.Admin;

namespace Grand.Web.Common.Menu
{
    public class SiteMap
    {
        private readonly IAdminSiteMapService _adminSiteMapService;
        private readonly IPermissionService _permissionService;
        public SiteMap(
            IAdminSiteMapService adminSiteMapService,
            IPermissionService permissionService)
        {
            _adminSiteMapService = adminSiteMapService;
            _permissionService = permissionService;
        }

        public SiteMapNode RootNode { get; set; }

        public virtual async Task Load()
        {
            var adminSiteMaps = await _adminSiteMapService.GetSiteMap();
            var sitemap = new SiteMapNode {
                SystemName = "Home",
                ResourceName = "Admin.Home",
                ControllerName = "Home",
                ActionName = "Overview"
            };
            await PrepareRootNode(sitemap, adminSiteMaps);
        }


        private async Task PrepareRootNode(SiteMapNode siteMap, IList<AdminSiteMap> adminSiteMaps)
        {
            if (adminSiteMaps != null)
            {
                foreach (var item in adminSiteMaps)
                {
                    var mainSite = new SiteMapNode();
                    siteMap.ChildNodes.Add(mainSite);
                    await Iterate(mainSite, item);
                }
            }
            RootNode = siteMap;
        }

        private async Task Iterate(SiteMapNode siteMap, AdminSiteMap siteMapNode)
        {
            await PopulateNode(siteMap, siteMapNode);

            foreach (var item in siteMapNode.ChildNodes.OrderBy(x=>x.DisplayOrder))
            {
                var mainSite = new SiteMapNode();
                siteMap.ChildNodes.Add(mainSite);
                await Iterate(mainSite, item);
            }
        }

        private async Task PopulateNode(SiteMapNode siteMap, AdminSiteMap siteNode)
        {
            siteMap.ActionName = siteNode.ActionName;
            siteMap.AllPermissions = siteNode.AllPermissions;
            siteMap.ControllerName = siteNode.ControllerName;
            siteMap.IconClass = siteNode.IconClass;
            siteMap.OpenUrlInNewTab = siteNode.OpenUrlInNewTab;
            siteMap.ResourceName = siteNode.ResourceName;
            siteMap.SystemName = siteNode.SystemName;
            siteMap.Url = siteNode.Url;

            if (siteNode.PermissionNames.Any())
            {
                if (siteNode.AllPermissions)
                {
                    siteMap.Visible = true;
                    foreach (var permissionName in siteNode.PermissionNames)
                    {
                        if (!await _permissionService.Authorize(permissionName.Trim()))
                            siteMap.Visible = false;
                    }
                }
                else
                {
                    siteMap.Visible = false;
                    foreach (var permissionName in siteNode.PermissionNames)
                    {
                        if (await _permissionService.Authorize(permissionName.Trim()))
                            siteMap.Visible = true;
                    }
                }
            }
            else
            {
                siteMap.Visible = true;
            }
        }
    }
}
