using Furion.DatabaseAccessor.Extensions;
using YBEE.EQM.Core;

namespace YBEE.EQM.Application;

/// <summary>
/// 角色服务
/// </summary>
public class SysRoleService(IRepository<SysRole> roleRep, IRepository<SysRoleUser> roleUserRep, ISysRoleMenuService roleMenuService, ICacheService cacheService) : ISysRoleService, ITransient
{

    /// <summary>
    /// 添加角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Add(AddSysRoleInput input)
    {
        var isExist = await roleRep.DetachedEntities.AnyAsync(u => u.Name == input.Name);
        if (isExist)
        {
            throw Oops.Oh(ErrorCode.E2004);
        }

        var role = input.Adapt<SysRole>();
        role.RoleType = RoleType.NORMAL;

        await role.InsertNowAsync();
    }
    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Del(DeleteSysRoleInput input)
    {
        var sysRole = await roleRep.FirstOrDefaultAsync(u => u.Id == input.Id);
        if (sysRole.RoleType != RoleType.NORMAL)
        {
            throw Oops.Oh(ErrorCode.E8201);
        }

        await sysRole.DeleteNowAsync();

        //级联删除该角色对应的用户-角色表关联信息
        var userRoles = await roleUserRep.Where(u => u.SysRoleId == sysRole.Id).ToListAsync();
        await roleUserRep.DeleteAsync(userRoles);

        //级联删除该角色对应的角色-菜单表关联信息
        await roleMenuService.DeleteRoleMenuListByRoleId(sysRole.Id);
    }
    /// <summary>
    /// 更新角色
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Update(UpdateSysRoleInput input)
    {
        var role = await roleRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id);
        if (role.RoleType != RoleType.NORMAL)
        {
            throw Oops.Oh(ErrorCode.E8202);
        }

        var isExist = await roleRep.DetachedEntities.AnyAsync(u => u.Name == input.Name && u.Id != input.Id);
        if (isExist)
        {
            throw Oops.Oh(ErrorCode.E2004);
        }

        var sysRole = input.Adapt<SysRole>();
        await sysRole.UpdateExcludeNowAsync(new[] { nameof(sysRole.RoleDataScope) });
    }
    ///// <summary>
    ///// 设置角色数据权限范围
    ///// </summary>
    ///// <returns></returns>
    //public async Task SetDataScope()
    //{
    //    // TODO:
    //    // 清空缓存，DelByPatternAsync，CommonConst.CACHE_KEY_PERMISSION
    //}
    /// <summary>
    /// 获取当前用户角色数据权限范围
    /// </summary>
    /// <returns></returns>
    public async Task<RoleDataScope> GetCurrentUserDataScope()
    {
        var roles = await cacheService.GetRoleDataScope(CurrentSysUserInfo.SysUserId);
        if (roles == null)
        {
            return new();
        }
        RoleDataScope roleDataScope = new();
        foreach (var role in roles)
        {
            roleDataScope.EducationStages.AddRange(role.RoleDataScope.EducationStages);
            roleDataScope.SysOrgIds.AddRange(role.RoleDataScope.SysOrgIds);
            roleDataScope.TwoWayTables.AddRange(role.RoleDataScope.TwoWayTables);
        }
        roleDataScope.EducationStages = roleDataScope.EducationStages.Distinct().ToList();
        roleDataScope.SysOrgIds = roleDataScope.SysOrgIds.Distinct().ToList();
        roleDataScope.TwoWayTables = roleDataScope.TwoWayTables.Distinct().ToList();
        return roleDataScope;
    }
    /// <summary>
    /// 获取所有角色
    /// </summary>
    /// <returns></returns>
    public async Task<List<SysRoleOutput>> GetAllList()
    {
        return await roleRep.DetachedEntities.OrderBy(u => u.RoleType).ProjectToType<SysRoleOutput>().ToListAsync();
    }
    /// <summary>
    /// 根据角色ID列表获取角色列表
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task<List<SysRoleOutput>> GetListByIds(List<int> ids)
    {
        return await roleRep.DetachedEntities.Where(t => ids.Contains(t.Id)).ProjectToType<SysRoleOutput>().ToListAsync();
    }
}