using BPA.SAAS.Manage.Application.Org.Dtos.Role;
using BPA.SAAS.Manage.Application.Org.Interface;
using BPA.SAAS.Manage.Application.System.Dtos;
using BPA.SAAS.Manage.Comm.Const;
using BPA.SAAS.Manage.Comm.Enum;
using BPA.SAAS.Manage.Core.Base;
using BPA.SAAS.Manage.Core.Org;
using BPA.SAAS.Manage.Core.System;
using Furion.LinqBuilder;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPA.SAAS.Manage.Application.Org.Services
{
    public class RoleService: IRoleService, ITransient
    {
        private readonly ISqlSugarClient _db;
        public RoleService(ISqlSugarClient db) 
        {
            _db=db;
        }
        public async Task<PageUtil> Page(RoleDtoPageInput input)
        {
            RefAsync<int> total = 0;
            var res =await _db.Queryable<BPA_Roles>()
                   .WhereIF(!input.Code.IsNullOrEmpty(), t => t.Code.Contains(input.Code))
                   .WhereIF(!input.Name.IsNullOrEmpty(), t => t.Name.Contains(input.Name))

                   .Select(t => new RoleDtoOutput
                   {
                       CreateAt = t.CreateAt,
                       Code = t.Code,
                       Id = t.Id,
                       Name = t.Name,
                       Remark = t.Remark,
                       RoleType = t.RoleType,
                       Sort = t.Sort,
                        Status= t.Status,
                   }).OrderBy(t => t.Sort).OrderBy(x => x.CreateAt, OrderByType.Desc).ToPageListAsync(input.Current, input.PageSize,  total);
            PageUtil util = new PageUtil()
            {
                Total = total,
                Data = res

            };
            return util;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Add(RoleDtoInput input)
        {

            //if (input.Code != "sys_manager_role")
            //{
            //    var resEntitites = _db.Queryable<BPA_Roles>().Where(a => a.Code == input.Code).ToList();
            //    if (resEntitites.Count() > 0)
            //    {
            //        throw Oops.Oh("已存在相同编码的角色");
            //    }
            //}
        
            var role = input.Adapt<BPA_Roles>();
            input.Code = GetNumber2();
            // role.DataScopeType = DataScopeType.ALL;
            return await _db.Insertable(role).CallEntityMethod(t => t.Create()).ExecuteCommandAsync() > 0;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Update(RoleDtoInput input)
        {
            var BPA_Roles = await _db.Queryable<BPA_Roles>().Where(a => a.Code == input.Code).FirstAsync();
            var code = BPA_Roles.Code;
            if (code != input.Code)
            {
                throw Oops.Oh("角色编码不能进行修改");
            }
            var Roles = await _db.Queryable<BPA_Roles>().Where(a => a.Id == input.Id).FirstAsync();
            Roles.Name= input.Name;
            Roles.Code= input.Code;
            Roles.Remark= input.Remark;
            Roles.Sort = input.Sort;
            return _db.Updateable(Roles).ExecuteCommandHasChange();

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Delete(List<string> input)
        {
            try
            {
                _db.Ado.BeginTran();
                // 查询数据库中是否存在未删除的活动信息
                var resEntitites = _db.Queryable<BPA_Roles>().In(input).ToList();
                var ids = resEntitites.Select(a => a.Id).ToArray();
                //校验用户
                var dara = _db.Queryable<BPA_UserRole>().Where(x => ids.Contains(x.SysRoleId)).ToList();
                if (dara.Count() <= 0)
                {
                    var res =await _db.Deleteable(resEntitites).ExecuteCommandAsync();
                    _db.Ado.CommitTran();
                    return res > 0;
                }
                else
                {
                    throw Oops.Oh("删除失败, 请检查用户是否关联该角色");
                }
            }
            catch (Exception)
            {
                _db.Ado.RollbackTran();
                throw Oops.Oh("删除失败");
            }
        }
        /// <summary>
        /// 根据角色查询角色菜单
        /// </summary>
        /// <param name="RoleId"></param>
        /// <returns></returns>
        public async Task<List<QueryRoleMenuListDto>> GetMenuRole(string RoleId)
        {
            var MenuName =await _db.Queryable<BPA_RoleMenu>().LeftJoin<BPA_Menu>((t, x) => t.SysMenuId == x.Id)
                  .Where(t => t.SysRoleId == RoleId).OrderBy((t, x) => x.CreateAt).Select((t, x) => new QueryRoleMenuListDto()
                  {
                      Name = x.Name,
                      Id = x.Id,
                      IsParentMenu = string.IsNullOrWhiteSpace(x.Pid)
                  }).ToListAsync();

            return MenuName;
        }
        /// <summary>
        /// 编辑角色菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> AddOrUpdateMenuRole(RoleMenuDtoInput input)
        {
            List<BPA_RoleMenu> models = new List<BPA_RoleMenu>();
            List<string> NewMenuId = new List<string>();
            _db.Deleteable<BPA_RoleMenu>(t => t.SysRoleId == input.SysRoleId).ExecuteCommandHasChange();
            if (input.SysMenuId != null)
            {
                var Menus = _db.Queryable<BPA_Menu>().ToList();

                foreach (var item in input.SysMenuId)
                {
                    var Pid = Menus.FirstOrDefault(t => t.Id == item).Pid;
                    if (Pid != null && Pid != "")
                    {
                        var Pid2 = Menus.FirstOrDefault(t => t.Id == Pid).Pid;

                        if (Pid2 != null)
                        {
                            NewMenuId.Add(Pid2);
                        }
                        NewMenuId.Add(Pid);
                    }
                    NewMenuId.Add(item);
                }
                NewMenuId.Distinct().ToList().ForEach(item =>
                {
                    models.Add(new BPA_RoleMenu
                    {
                        Id = Guid.NewGuid().ToString(),
                        SysMenuId = item,
                        SysRoleId = input.SysRoleId
                    });
                });
            }
            if (models.Count <= 0)
                return true;

           
            return await _db.Insertable(models).ExecuteCommandAsync() > 0;


        }
        /// <summary>
        /// 启用
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<bool> Enable(string Id)
        {
            var resEntitites = _db.Queryable<BPA_Roles>().In(Id).ToList();
            resEntitites.ForEach(x =>
            {
                x.Status = CommonStatus.ENABLE;
            });
            var res =await _db.Updateable(resEntitites).ExecuteCommandAsync();
            return res>0;
        }

        /// <summary>
        /// 禁用
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<bool> Disable(string Id)
        {
            var resEntitites = _db.Queryable<BPA_Roles>().In(Id).ToList();
            resEntitites.ForEach(x =>
            {
                x.Status = CommonStatus.DISABLE;
            });
            var res =await _db.Updateable(resEntitites).ExecuteCommandAsync();
            return res>0;
        }
        public async Task<Dictionary<string, object>> GetRole()
        {
            var res =await _db.Queryable<BPA_Roles>().Where(t => t.IsDeleted == 0 && t.Status == CommonStatus.ENABLE).ToDictionaryAsync(t => t.Id, t => t.Name);

            return res;
        }
        private string GetNumber2(int Length = 10)
        {
            byte[] buffer = Guid.NewGuid().ToByteArray();
            var ram = BitConverter.ToInt64(buffer, 0);
            var str = string.Format("{0}", ram.ToString().Substring(0, Length));
            return str;
        }
    }
}
