using MediatR;
using TakeoutSaaS.Application.App.Personal.Dto;
using TakeoutSaaS.Application.App.Personal.Queries;
using TakeoutSaaS.Application.App.Personal.Services;
using TakeoutSaaS.Domain.Identity.Repositories;

namespace TakeoutSaaS.Application.App.Personal.Handlers;

/// <summary>
/// 获取个人角色与权限概览处理器。
/// </summary>
public sealed class GetPersonalRolesQueryHandler(
    PersonalContextService personalContextService,
    IUserRoleRepository userRoleRepository,
    IRoleRepository roleRepository,
    IRolePermissionRepository rolePermissionRepository)
    : IRequestHandler<GetPersonalRolesQuery, PersonalRolePermissionSummaryDto>
{
    /// <summary>
    /// 处理查询。
    /// </summary>
    /// <param name="request">查询请求。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>角色权限概览。</returns>
    public async Task<PersonalRolePermissionSummaryDto> Handle(GetPersonalRolesQuery request, CancellationToken cancellationToken)
    {
        // 1. 获取请求上下文
        var context = personalContextService.GetRequiredContext();

        // 2. 获取用户角色关系
        var userRoles = await userRoleRepository.GetByUserIdAsync(context.TenantId, context.UserId, cancellationToken);
        var roleIds = userRoles.Select(static x => x.RoleId).Distinct().ToArray();
        if (roleIds.Length == 0)
        {
            return new PersonalRolePermissionSummaryDto
            {
                Roles = [],
                PermissionCount = 0
            };
        }

        // 3. 获取角色明细
        var roles = await roleRepository.GetByIdsAsync(context.TenantId, roleIds, cancellationToken);
        var roleItems = roles
            .OrderBy(static x => x.Name)
            .Select(static x => new PersonalRoleItemDto
            {
                RoleCode = x.Code,
                RoleName = x.Name
            })
            .ToList();

        // 4. 统计去重权限数量
        var rolePermissions = await rolePermissionRepository.GetByRoleIdsAsync(context.TenantId, roleIds, cancellationToken);
        var permissionCount = rolePermissions
            .Select(static x => x.PermissionId)
            .Distinct()
            .Count();

        // 5. 返回结果
        return new PersonalRolePermissionSummaryDto
        {
            Roles = roleItems,
            PermissionCount = permissionCount
        };
    }
}
