using Microsoft.AspNetCore.DataProtection.KeyManagement;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_DTO.System;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.BaseServices;
using WIDESEAWCS_Core.HttpContextUser;
using WIDESEAWCS_ISystemRepository;
using WIDESEAWCS_ISystemServices;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Model.Models.System;
using WIDESEAWCS_SystemRepository;

namespace WIDESEAWCS_SystemServices.System
{
    public class Sys_RoleService : ServiceBase<Sys_Role, ISys_RoleRepository>, ISys_RoleService
    {
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly ISys_MenuRepository _MenuRepository;
        private readonly ISys_MenuService _MenuService;
        private readonly ISys_RoleAuthRepository _RoleAuthRepository;
        public Sys_RoleService(ISys_RoleRepository BaseDal, ISys_MenuRepository MenuRepository, ISys_MenuService MenuService, ISys_RoleAuthRepository roleAuthRepository, IUnitOfWorkManage unitOfWorkManage) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _MenuRepository = MenuRepository;
            _MenuService = MenuService;
            _RoleAuthRepository = roleAuthRepository;
        }

        public List<RoleNodes> GetAllChildren(int roleId)
        {
            if (roleId <= 0) return new List<RoleNodes>() { };
            var roles = GetAllRoleId();
            if (App.User.IsRoleIdSuperAdmin(roleId)) return roles;

            var list = GetChildren(roles, roleId);
            return list;
        }

        public  List<RoleNodes> GetAllRoleId()
        {
            List<RoleNodes> roles = BaseDal.QueryData().Select(s => new RoleNodes() { Id = s.RoleId, ParentId = s.ParentId, RoleName = s.RoleName }).ToList();

            return roles;
        }

        /// <summary>
        /// 获取所有子节点
        /// </summary>
        /// <param name="roleId"></param>
        private List<RoleNodes> GetChildren(List<RoleNodes> roles, int roleId)
        {
            List<RoleNodes> rolesChildren = roles.Where(x => x.Id == roleId).Distinct().ToList();

            for (int i = 0; i < rolesChildren.Count; i++)
            {
                RoleNodes node = rolesChildren[i];
                var children = roles.Where(x => x.ParentId == node.Id && !rolesChildren.Any(c => c.Id == x.Id)).Distinct().ToList();
                rolesChildren.AddRange(children);
            }
            return rolesChildren;
        }

        /// <summary>
        /// 编辑权限时获取当前用户下的所有角色与当前用户的菜单权限
        /// </summary>
        /// <returns></returns>
        public WebResponseContent GetCurrentTreePermission()
        {
            WebResponseContent content = GetCurrentUserTreePermission();
            int roleId = App.User.RoleId;
            return WebResponseContent.Instance.OK(null, new
            {
                tree = content.Data,
                roles = GetAllChildren(roleId)
            });
        }

        /// <summary>
        /// 编辑权限时,获取当前用户的所有菜单权限
        /// </summary>
        /// <returns></returns>
        public WebResponseContent GetCurrentUserTreePermission()
        {
            return GetUserTreePermission(App.User.RoleId);
        }

        /// <summary>
        /// 编辑权限时,获取指定角色的所有菜单权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public WebResponseContent GetUserTreePermission(int roleId)
        {
            if (!App.User.IsRoleIdSuperAdmin(roleId) && App.User.RoleId != roleId)
            {
                if (!(GetAllChildren(App.User.RoleId)).Exists(x => x.Id == roleId))
                {
                    return WebResponseContent.Instance.Error("没有权限获取此角色的权限信息");
                }
            }
            //获取用户权限
            List<Permissions> permissions = _MenuRepository.GetPermissions(roleId);
            //权限用户权限查询所有的菜单信息
            List<Sys_Menu> menus =  _MenuService.GetUserMenuList(roleId);
            //获取当前用户权限如:(Add,Search)对应的显示文本信息如:Add:添加,Search:查询
            var data = menus.Select(x => new
            {
                Id = x.MenuId,
                Pid = x.ParentId,
                Text = x.MenuName,
                IsApp = x.MenuType == 1,
                Actions = _MenuService.GetActions(x.MenuId, x.Actions, permissions, roleId)
            });
            return WebResponseContent.Instance.OK(null, data);
        }

        /// <summary>
        /// 保存角色权限
        /// </summary>
        /// <param name="userPermissions"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public WebResponseContent SavePermission(List<UserPermissionDTO> userPermissions, int roleId)
        {
            WebResponseContent content = new WebResponseContent();
            string message = "";
            try
            {
                if (!GetAllChildren(App.User.RoleId).Exists(x => x.Id == roleId))
                    return WebResponseContent.Instance.Error("没有权限修改此角色的权限信息");
                //当前用户的权限
                List<Permissions> permissions = _MenuRepository.GetPermissions(App.User.RoleId);

                List<int> originalMeunIds = new List<int>();
                //被分配角色的权限
                List<Sys_RoleAuth> roleAuths = _RoleAuthRepository.QueryData(x => x.RoleId == roleId);
                List<Sys_RoleAuth> updateAuths = new List<Sys_RoleAuth>();
                foreach (UserPermissionDTO x in userPermissions)
                {
                    Permissions per = permissions.FirstOrDefault(p => p.MenuId == x.Id);
                    //不能分配超过当前用户的权限
                    if (per == null) continue;
                    //per.UserAuthArr.Contains(a.Value)校验权限范围
                    string[] arr = x.Actions == null || x.Actions.Count == 0
                      ? new string[0]
                      : x.Actions.Where(a => per.UserAuthArr.Contains(a.Value))
                      .Select(s => s.Value).ToArray();

                    //如果当前权限没有分配过,设置Auth_Id默认为0,表示新增的权限
                    var auth = roleAuths.Where(r => r.MenuId == x.Id).Select(s => new { s.AuthId, s.AuthValue, s.MenuId }).FirstOrDefault();
                    string newAuthValue = string.Join(",", arr);
                    //权限没有发生变化则不处理
                    if (auth == null || auth.AuthValue != newAuthValue)
                    {
                        updateAuths.Add(new Sys_RoleAuth()
                        {
                            RoleId = roleId,
                            MenuId = x.Id,
                            AuthValue = string.Join(",", arr),
                            AuthId = auth == null ? 0 : auth.AuthId,
                            ModifyDate = DateTime.Now,
                            Modifier = App.User.UserName,
                            CreateDate = DateTime.Now,
                            Creater = App.User.UserName
                        });
                    }
                    else
                    {
                        originalMeunIds.Add(auth.MenuId);
                    }

                }
                //更新权限
                _RoleAuthRepository.UpdateData(updateAuths);
                //新增的权限
                _RoleAuthRepository.AddData(updateAuths);

                //获取权限取消的权限
                int[] authIds = roleAuths.Where(x => userPermissions.Select(u => u.Id)
                 .ToList().Contains(x.MenuId) || originalMeunIds.Contains(x.MenuId))
                .Select(s => s.AuthId)
                .ToArray();
                List<Sys_RoleAuth> delAuths = roleAuths.Where(x => x.AuthValue != "" && !authIds.Contains(x.AuthId)).ToList();
                delAuths.ForEach(x =>
                {
                    x.AuthValue = "";
                });
                //将取消的权限设置为""
                _RoleAuthRepository.UpdateData(delAuths);

                int addCount = updateAuths.Where(x => x.AuthId <= 0).Count();
                int updateCount = updateAuths.Where(x => x.AuthId > 0).Count();
                
                string _version = DateTime.Now.ToString("yyyyMMddHHMMssfff");


                content.OK($"保存成功:新增加配菜单权限{addCount}条,更新菜单{updateCount}条,删除权限{delAuths.Count}条");
            }
            catch (Exception ex)
            {
                message = "异常信息:" + ex.Message + ex.StackTrace + ",";
            }

            return content;
        }
    }
}