using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Infrastructure;
using Infrastructure.Extensions;
using OpenAuth.App.Base;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.BasicQueryService;
using OpenAuth.App.Response;
using OpenAuth.Repository;
using OpenAuth.Repository.Domain;
using SqlSugar;
using StackExchange.Redis;

namespace OpenAuth.App
{
    /// <summary>
    /// 普通用户授权策略
    /// </summary>
    public class NormalAuthStrategy : SqlSugarBaseApp<SysUser, SugarDbContext>, IAuthStrategy
    {
        ISqlSugarClient client;
        UserManager manager;
        protected SysUser _user;
        private List<long> _userRoleIds;    //用户角色ID

        public NormalAuthStrategy(
            ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<SysUser> repository,
            UserManager userManager
            ) : base(unitWork, repository, null)
        {
            client = base.Repository.AsSugarClient();
            manager = userManager;
        }



        public List<ModuleView> Modules
        {
            get
            {
                //var moduleIds = Repository.ChangeRepository<SugarRepositiry<SysRoleModule>>().GetList(
                //   u =>
                //       (_userRoleIds.Contains(u.RoleId))).Select(u => u.ModuleId);
                //var modules = Repository.ChangeRepository<SugarRepositiry<SysModule>>().AsQueryable().Where(u => moduleIds.Contains(u.Id))
                //    .Select(module => new ModuleView
                //    {
                //        SortNo = module.SortNo,
                //        Name = module.Name,
                //        Code = module.Code,
                //        CascadeId = module.CascadeId,
                //        Id = module.Id,
                //        IconName = module.IconName,
                //        Url = module.Url,
                //        ParentId = module.ParentId,
                //        ParentName = module.ParentName,
                //        IsSys = module.IsSys,
                //        Status = module.Status
                //    }).ToList();

                var modules = manager.RoleModules(_userRoleIds).Distinct().OrderBy((r, m) => m.SortNo).Select<ModuleView>().ToList();

                var usermoduleelements = ModuleElements;

                foreach (var module in modules)
                {
                    module.Elements = usermoduleelements.Where(u => u.ModuleId == module.Id).DistinctBy(u=>u.Id).ToList();
                }

                return modules;
            }
        }

        public List<SysModuleElement> ModuleElements
        {
            get
            {
                return manager.RoleModuleElements(_userRoleIds).OrderBy((r, m) => m.Sort).Select((r, m) => m).ToList();
            }
        }

        public List<SysRole> Roles
        {
            get { return manager.UserRoles(_user.Id).Select((u, r) => r).ToList(); }
        }

        public List<SysResource> Resources
        {
            get
            {
                var resourceIds = base.Repository.ChangeRepository<SugarRepositiry<SysRoleResource>>()
                    .GetList(u => _userRoleIds.Contains(u.RoleId)).Select(u => u.ResourceId);
                return base.Repository.ChangeRepository<SugarRepositiry<SysResource>>().GetList(u => resourceIds.Contains(u.Id)).ToList();
            }
        }

        public List<SysOrg> Orgs
        {
            get
            {
                return manager.UserOrgs(_user.Id).Select((u, o) => o).ToList();
            }
        }

        public List<SysPosition> Positions
        {
            get { return manager.UserPositons(_user.Id).Select((u, p) => p).ToList(); }
        }

        public SysUser User
        {
            get { return _user; }
            set
            {
                _user = value;
                _userRoleIds = manager.UserRoles(_user.Id).Select((u, r) => r.Id).ToList();
            }
        }
      
    }
}