using OpenAuth.App.Interface;
using OpenAuth.App.Response;
using OpenAuth.Repository.Domain;
using Infrastructure;
using OpenAuth.App.Request;
using OpenAuth.Repository;
using SqlSugar;
using OpenAuth.App.Base;
using OpenAuth.App.BaseApp.Base;
using OpenAuth.App.BasicQueryService;

namespace OpenAuth.App
{
    public class RoleApp : SqlSugarBaseApp<SysRole, SugarDbContext>
    {
        UserManager userManager;
        public RoleApp(
            ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<SysRole> repository,
            IAuth auth,
            UserManager userManager
            ) : base(unitWork, repository, auth)
        {
            this.userManager = userManager;
        }

        #region 查询
        /// <summary>
        /// 查询所有角色分页
        /// </summary>
        public async Task<Response<PageInfo<List<SysRole>>>> LoadAllPage(QueryRoleListReq request)
        {
            RefAsync<int> totalCount = 0;
            var result = new PageInfo<SysRole>();
            var roles = await base.Repository.AsQueryable()
                .WhereIF(!string.IsNullOrEmpty(request.key), r => r.Name.Contains(request.key))
                .OrderByDescending(r => r.CreateTime)
                .ToPageListAsync(request.page, request.limit, totalCount);

            return new Response<PageInfo<List<SysRole>>>
            {
                Result = new PageInfo<List<SysRole>>
                {
                    Items = roles,
                    Total = totalCount
                }
            };
        }

        /// <summary>
        /// 登录用户可访问的角色分页
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<SysRole>>>> LoadPage(QueryRoleListReq request)
        {
            long userId = long.Parse(_auth.GetUserId());

            RefAsync<int> totalCount = 0;
            var result = new PageInfo<SysRole>();
            var roles = await userManager.UserRoles(userId)
                .WhereIF(!string.IsNullOrEmpty(request.key), (u, r) => r.Name.Contains(request.key))
                .OrderByDescending((u, r) => r.CreateTime)
                .Select((u, r) => r)
                .ToPageListAsync(request.page, request.limit, totalCount);

            return new Response<PageInfo<List<SysRole>>>
            {
                Result = new PageInfo<List<SysRole>>
                {
                    Items = roles,
                    Total = totalCount
                }
            };
        }

        public async Task<List<long>> UserRoles(long userId)
        {
            return await base.Repository.AsSugarClient().Queryable<SysUserRole>()
                      .Where(ur => ur.UserId == userId)
                      .Select(ur => ur.RoleId).ToListAsync();
        }
        #endregion



        public SysRole Get(long id)
        {
            return Repository.GetById(id);
        }



        /// <summary>
        /// 添加角色
        /// </summary>
        public async Task<Response<bool>> Add(RoleView obj)
        {
            SysRole role = obj;
            role.CreateTime = DateTime.Now;
            role.Id = Yitter.IdGenerator.YitIdHelper.NextId();
            var flag = await Repository.InsertAsync(role);

            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }



        /// <summary>
        /// 删除角色时，需要删除角色对应的权限
        /// </summary>
        /// <param name="ids"></param>
        public async Task<Response<bool>> Delete(long[] ids)
        {
            using (var uwo = UnitWork.CreateContext())
            {
                await uwo.SysRoleModule.DeleteAsync(a => ids.Contains(a.RoleId));
                await uwo.SysRoleElement.DeleteAsync(a => ids.Contains(a.RoleId));
                await uwo.Role.DeleteAsync(u => ids.Contains(u.Id));
                var flag = uwo.Commit();

                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

        /// <summary>
        /// 更新角色属性
        /// </summary>
        /// <param name="obj"></param>
        public async Task<Response<bool>> Update(RoleView obj)
        {
            SysRole role = obj;

            bool flag = await base.Repository.UpdateAsync(u => new SysRole
            {
                Name = role.Name,
                Status = role.Status
            }, u => u.Id == obj.Id);

            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }

        /// <summary>
        /// 为角色分配菜单和按钮
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AssignModule(ModuleElementWithRole model)
        {
            using (var uwo = UnitWork.CreateContext())
            {
                await uwo.SysRoleModule.DeleteAsync(a => a.RoleId == model.RoleId);
                await uwo.SysRoleElement.DeleteAsync(a => a.RoleId == model.RoleId);
                await uwo.SysRoleModule.InsertRangeAsync(model.ModuleIds.Select(a => new SysRoleModule { RoleId = model.RoleId, ModuleId = a }).ToList());
                await uwo.SysRoleElement.InsertRangeAsync(model.ElementIds.Select(a => new SysRoleElement { RoleId = model.RoleId, ElementId = a }).ToList());

                var flag = uwo.Commit();
                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

    }
}