namespace BPA.MES.Base.Application
{
    /// <summary>
    /// 名    称 ：授权服务 
    /// 创 建 人 ：yangxiao  
    /// 创建时间 ：2023/3/2 16:11:04 
    /// 描    述 ：授权服务数据维护 
    /// </summary>
    [ApiDescriptionSettings(Name = "Authorize", KeepName = true, SplitCamelCase = true, KeepVerb = true)]
    public class AuthorizeService : IAuthorizeService, ITransient, IDynamicApiController
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ISqlSugarClient db;
        private readonly ISqlSugarClient _dbContext;
        public AuthorizeService(ISqlSugarClient db, IHttpContextAccessor httpContextAccessor)
        {
            this.db = db;
            _dbContext = db;
            _httpContextAccessor = httpContextAccessor;
        }
        #region 当前用户
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        [AllowAnonymous]
        public async Task<bool> Login(AccountInput input)
        {
            var Info = await db.Queryable<AccountEntity>().FirstAsync(t => t.Account == input.Account && t.Pwd == input.Pwd);
            if (Info == null)
                throw Oops.Bah("请输入正确的账号和密码");
            var User = await db.Queryable<EmployeeEntity>().FirstAsync(t => t.Id == Info.EmployeeId);
            if (User == null)
            {
                throw Oops.Bah("账号没有权限");
            }
            //return ResolveService<IJwtService>().CreateAccessToken(new UserIdentity
            //{
            //    Id = User.Id,
            //    UserName = User.Name,
            //    IsAdmin = User.IsAdmin,
            //});

            // 生成Token令牌
            //var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
            var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
            {
                {ClaimConst.CLAINM_USERID, User.Id},
                {ClaimConst.CLAINM_NAME,User.Name},
                {ClaimConst.CLAINM_ACCOUNT,Info.Account },
                {ClaimConst.CLAINM_ISAUTH,User.IsAdmin},
                {ClaimConst.CLAINM_ROLEID,User.RoleId }
            }, 43200);
            // 设置Swagger自动登录
            _httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
            // 生成刷新Token令牌
            var refreshToken =
                JWTEncryption.GenerateRefreshToken(accessToken, int.MaxValue);

            _httpContextAccessor.HttpContext.Response.Headers["access-token"] = accessToken;
            // 设置刷新Token令牌
            _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
            return true;
        }
        /// <summary>
        /// 获取个人信息
        /// </summary>
        /// <returns></returns>
        public async Task<object> GetUserInfo()
        {
            string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            var user = await db.Queryable<EmployeeEntity>().LeftJoin<RoleEntity>((t, x) => t.RoleId == x.Id)
                    .Where((t, x) => t.Id == userId).Select((t, x) => new
                    {
                        RoleName = x.Name,
                        RoleType = x.RoleType,
                        Id = t.Id,
                        UserName = t.Name
                    }).FirstAsync();


            var menus = (await GetJurisdictionItemsAsync())?.Menus;
            return new
            {
                Menus = menus,
                UserInfo = new
                {
                    UserId = user?.Id,
                    user?.RoleName,
                    user?.UserName
                }
            };
        }
        [HttpGet]
        public async Task<List<string>> MultipleModuleAuthorityAsync()
        {
            return (await GetJurisdictionItemsAsync())?.AuthorizationCodes;
        }
        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        async Task<UserRoleCacheDto> GetJurisdictionItemsAsync()
        {

            string userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;  
            string roleId = App.User?.FindFirst(ClaimConst.CLAINM_ROLEID)?.Value;
          
            var result = new UserRoleCacheDto();
            //根据角色获取权限Id
            var employeeEntity = await db.Queryable<EmployeeEntity>().FirstAsync(x => x.RoleId==roleId);
            if (employeeEntity.IsAdmin)
            {
                var temp = await db.Queryable<ModuleEntity>().Where(t =>t.Category!=3 && !t.IsDisabled).OrderBy(t => t.ParentId)
                        .ToListAsync();
                result.Menus = temp.Adapt<List<UserMenu>>().BuildTree();
            }
            else
            {
                var roleModuleEntities = await db.Queryable<RoleModuleEntity>().Where(x => x.RoleId == roleId).ToListAsync();
                result.AuthorizationCodes = roleModuleEntities.Select(t => t.ModuleId).ToList();
                if (result.AuthorizationCodes.HasVal())
                {
                    var temp = await db.Queryable<ModuleEntity>().Where(t => result.AuthorizationCodes.Contains(t.Id) && !t.IsDisabled).OrderBy(t => t.ParentId)
                         .ToListAsync();

                    result.Menus = temp.Adapt<List<UserMenu>>().BuildTree();
                }
            }
            result.Menus ??= new List<UserMenu>();
            result.Menus =  result.Menus.OrderBy(t => t.Sort).ToList();
            return result;
        }
        /// <summary>
        /// 获取账户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SqlSugarPagedList<AccountOutput>> AccountPageList(AccountQueryPageInput input)
        {
          var entity = await _dbContext.Queryable<AccountEntity>()
                .WhereIF(!string.IsNullOrEmpty(input.Account),x=>x.Account==input.Account)
                .ToPagedListAsync(input.PageIndex,input.PageSize);
            SqlSugarPagedList<AccountOutput> output = entity.Adapt<SqlSugarPagedList<AccountOutput>>();
            return output;
        }

        /// <summary>
        /// 添加账户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> AddAccount(AccountAddInput input)
        {
            var entity = input.Adapt<AccountEntity>();
            return await _dbContext.Insertable(entity).ExecuteCommandIdentityIntoEntityAsync();
        }
        /// <summary>
        /// 修改账户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAccount(AccountUpdateInput input) {
            var entity = input.Adapt<AccountEntity>();
            return await _dbContext.Updateable(entity).IgnoreColumns(true).ExecuteCommandHasChangeAsync();
        }
        /// <summary>
        /// 删除账户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> DelAccount(AccountDelInput input) {
            var entity = input.Adapt<AccountEntity>();
            return await _dbContext.Deleteable(entity).Where(x=>x.Id==input.Id).ExecuteCommandHasChangeAsync();
        }
        #endregion
        #region 角色
        [HttpPost]
        public async Task<bool> AddRole(RoleAddInput input)
        {
            var check = await db.Queryable<RoleEntity>().FirstAsync(t => t.Name == input.Name);
            if (check != null) throw Oops.Bah ("角色名称不能重复");
            var model = input.Adapt<RoleEntity>();
            model.RoleType = 2;
            return await db.Insertable(model).ExecuteCommandAsync() > 0;
        }
        [HttpPost]
        public async Task<bool> EditRole(RoleUpdateInput input)
        {
            if (!await db.Queryable<RoleEntity>().Where(it => it.Id == input.Id).AnyAsync())
                throw Oops.Bah("角色不存在或已被删除");
            if (await _dbContext.Queryable<RoleEntity>().Where(it => it.Id != input.Id && it.Name == input.Name).AnyAsync())
                throw Oops.Bah("角色名称已经存在");
            return await _dbContext.Updateable<RoleEntity>(input).Where(a => a.Id == input.Id).ExecuteCommandHasChangeAsync();
        }
        [HttpGet]
        public async Task<bool> RemoveRole(string input)
        {
            return await db.Deleteable<RoleEntity>().Where(t => t.Id == input).ExecuteCommandHasChangeAsync();
        }
        [HttpGet]
        public async Task<RoleOutput> GetRole(string input)
        {
            var entity = await db.Queryable<RoleEntity>().FirstAsync(t => t.Id == input);
            return entity.Adapt<RoleOutput>();
        }
        [HttpGet]
        public async Task<List<RoleOutput>> GetRoleList()
        {
            var entity = await db.Queryable<RoleEntity>().Where(t => t.RoleType != 1).ToListAsync();
            return entity.Adapt<List<RoleOutput>>();
        }
        [HttpPost]
        public async Task<SqlSugarPagedList<RoleOutput>> QueryRole(RoleQueryPageInput input)
        {
            var eneity = await db.Queryable<RoleEntity>()
                 .WhereIF(!string.IsNullOrEmpty(input.Keyword), t => t.Name.Contains(input.Keyword))
                 .Select<RoleOutput>()
                 .ToPagedListAsync(input.PageIndex, input.PageSize);
            return eneity;
        }
        #endregion

        #region 模块
        [HttpPost]
        public async Task<bool> AddModule(ModuleAddInput input)
        {
            input.ParentId = input.ParentId ?? string.Empty;
            var entity = input.Adapt<ModuleEntity>();
            await db.Insertable(entity).IgnoreColumns(true).ExecuteCommandAsync();
            return true;
        }
        [HttpPost]

        public async Task<bool> EditModule(ModuleUpdateInput input)
        {
            if (!await db.Queryable<ModuleEntity>().Where(it => it.Id == input.Id ).AnyAsync())
            {
                throw Oops.Bah("模块不存在或已被删除");
            }
            input.ParentId = input.ParentId ?? string.Empty;
            return await db.Updateable<ModuleEntity>(input).Where(a => a.Id == input.Id).ExecuteCommandHasChangeAsync();
        }
        [HttpGet]

        public async Task RemoveModule(string input)
        {
            var list = await db.Queryable<ModuleEntity>().Where(it => it.ParentId == input).ToListAsync();
            if (list.HasVal())
            {
                foreach (var item in list)
                {
                    await RemoveModule(item.Id);
                }
            }
            await _dbContext.Deleteable<ModuleEntity>().Where(it => it.Id == input).ExecuteCommandAsync();
        }
        [HttpPost]
        public async Task<List<ModuleTreeOutput>> GetTreeGrid(ModuleTreeQueryInput input)
        {
            var list = new List<ModuleTreeOutput>();

            var datas = await db.Queryable<ModuleEntity>()
                .WhereIF(!string.IsNullOrEmpty(input.Name), t => t.Name.Contains(input.Name))
                .OrderBy(it => it.Sort)
                .ToListAsync();

            var modules = datas.Adapt<List<ModuleTreeOutput>>();

            if (modules.HasVal())
            {
                foreach (var item in modules.Where(it=>it.ParentId=="").ToList())
                {
                    item.Children = modules.Where(it => it.ParentId == item.Id ).OrderBy(it => it.Sort).ToList();
                    foreach (var view in item.Children)
                    {
                        view.Children = modules.Where(it => it.ParentId == view.Id ).OrderBy(it => it.Sort).ToList();
                    }

                    list.Add(item);
                }
            }
            return list;
        }
        #endregion

        #region 授权模板详情
        [HttpGet]
        public async Task<bool> RestoreAccountByUser(string input)
        {
            var Demo = "123456".ToMD5Encrypt();
            return await db.Updateable<AccountEntity>().SetColumns(t => t.Pwd == Demo)
                .Where(t => t.EmployeeId == input).ExecuteCommandHasChangeAsync();
        }
        [HttpPost]
        public async Task<bool> AddAccountByUser(AccountAddInput input)
        {
            var temp = await db.Queryable<AccountEntity>().FirstAsync(t => t.EmployeeId == input.TB_Employee_Id);
            if (temp != null)
            {
                //throw new BusinessException("该员工已绑定账户，请勿重复绑定");
                temp.Account = input.Account;
                return await db.Updateable(temp).ExecuteCommandAsync() > 0;
            }
            else
            {
                var model = input.Adapt<AccountEntity>();
                //默认123456
                model.Pwd = "123456".ToMD5Encrypt();
                model.EmployeeId = input.TB_Employee_Id;
                return await db.Insertable(model).ExecuteCommandAsync() > 0;
            }
        }
        [HttpPost]
        public async Task<bool> EditAccountPwd(AccountUpdatePwdInput input)
        {
            var Account  = App.User?.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value;
            var model = db.Queryable<AccountEntity>().First(t => t.Account == Account && t.Pwd == input.OldPwd);
            if (model == null) throw Oops.Bah("原密码不正确");
            model.Pwd = input.NewPwd;
            return await db.Updateable(model).ExecuteCommandAsync() > 0;
        }
        [HttpGet]
        public async Task<AccountOutput> GetAccountByUser(string input)
        {
            var data = await db.Queryable<AccountEntity>().FirstAsync(t => t.EmployeeId == input);
            return data.Adapt<AccountOutput>();
        }

        [HttpPost]
        public async Task<bool> AddEmployee(EmployeeAddInput input)
        {
            var model = input.Adapt<EmployeeEntity>();
            model.IsAdmin = false;
            return await db.Insertable(model).IgnoreColumns(true).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 编辑员工
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> EditEmployee(EmployeeUpdateInput input)
        {
            var temp = await db.Queryable<EmployeeEntity>().FirstAsync(t => t.Id == input.Id);
            temp.Name = input.Name;
            temp.Status = input.Status;
            return await db.Updateable(temp).ExecuteCommandHasChangeAsync();
        }
        /// <summary>
        /// 查询员工
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<SqlSugarPagedList<EmployeeOutput>> QueryEmployee(EmployeeQueryPageInput input)
        {
         
            var entity = await db.Queryable<EmployeeEntity>()

                   .WhereIF(!string.IsNullOrEmpty(input.name), t => t.Name.Contains(input.name))
                   .WhereIF(input.Status > 0, t => t.Status == input.Status).
                   WhereIF(input.Gender > 0, t => t.Gender == input.Gender)
                   .Where(t => t.IsAdmin == false)
                 
                   .Select(t => new EmployeeOutput()
                     {
                         Id = t.Id.SelectAll(),
                         IsAccount = SqlFunc.Subqueryable<AccountEntity>().Where(s => s.EmployeeId == t.Id).Any(),
                         Account = SqlFunc.Subqueryable<AccountEntity>().Where(s => s.EmployeeId == t.Id).Select(s => s.Account)
                     })
                   .ToPagedListAsync(input.PageIndex, input.PageSize);
            return entity;
        }
        /// <summary>
        /// 删除员工
        /// </summary>
        /// <param name="employeeId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<bool> RemoveEmployee([FromQuery] string employeeId)
        {
            try
            {
                db.Ado.BeginTran();
                await db.Deleteable<EmployeeEntity>().Where(t => t.Id == employeeId).ExecuteCommandAsync();
                await db.Deleteable<AccountEntity>().Where(t => t.EmployeeId == employeeId).ExecuteCommandAsync();
                db.Ado.CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                db.Ado.RollbackTran();
                throw Oops.Bah("删除失败!");
            }
        }
        [HttpGet]
        public async Task<List<EmployeeOutput>> EmployeeList()
        {
            var data = await db.Queryable<EmployeeEntity>().Where(t => t.IsAdmin == false).ToListAsync();
            return data.Adapt<List<EmployeeOutput>>();
        }
        /// <summary>
        /// 分配角色权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<bool> AddRoleModule(RoleModuleAddInput input)
        {
            List<RoleModuleEntity> entitys = new();
            var moduleList =await _dbContext.Queryable<ModuleEntity>().ToListAsync();
            var parentId = input.ModuleIds.Where(x=>x.ParentId!="").GroupBy(x => x.ParentId).ToList();
            foreach (var item in parentId)
            {
                if (input.ModuleIds.FirstOrDefault(x=>x.ModuleId==item.Key && x.ParentId=="")==null)
                {
                    input.ModuleIds.Add(new RoleModuleDto { ModuleId = item.Key, ParentId = "", RoleId = input.RoleId });
                }
            }
            foreach (var item in input.ModuleIds)
            {
                
                RoleModuleEntity entity = new()
                {
                    ModuleId = item.ModuleId,
                    ParentId = item.ParentId,
                    RoleId = input.RoleId
                };
                entitys.Add(entity);
            }
            try
            {
                _dbContext.Ado.BeginTran();
                await _dbContext.Deleteable<RoleModuleEntity>().Where(x => x.RoleId == input.RoleId).ExecuteCommandAsync();
                await _dbContext.Insertable(entitys).ExecuteCommandAsync();
                _dbContext.Ado.CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                throw Oops.Bah(ex.Message);
            }
        }
        /// <summary>
        /// 根据角色获取权限模块
        /// </summary>
        /// <param name="RoleId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<List<RoleModuleOutput>> RoleModuleList(string RoleId)
        {
            var entitys = await _dbContext.Queryable<RoleModuleEntity>().Where(x => x.RoleId == RoleId).ToListAsync();
            var tementity = entitys.Where(x => x.ParentId == "").ToList();//查询出主菜单
            var delentity = new List<RoleModuleEntity>();
            foreach (var item in tementity)//查询出主菜单是否有多个
            {
              var v =  entitys.Where(x=>x.ParentId==item.ModuleId).ToList();
                if (v.Count>0)//如果只有一个，就不删除
                {
                    delentity.Add(item);
                }
            }
            foreach (var item in delentity)
            {
                entitys.Remove(item);
            }
            var output = entitys.Adapt<List<RoleModuleOutput>>();
            return output;
        } 
        #endregion
    }
}
