using MediatR;
using TakeoutSaaS.Application.Identity.Contracts;
using TakeoutSaaS.Application.Identity.Queries;
using TakeoutSaaS.Domain.Identity.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.Identity.Handlers;

/// <summary>
/// 按用户 ID 获取权限概览处理器。
/// </summary>
public sealed class GetUserPermissionsQueryHandler(
    IIdentityUserRepository identityUserRepository,
    IUserRoleRepository userRoleRepository,
    IRoleRepository roleRepository,
    IPermissionRepository permissionRepository,
    IRolePermissionRepository rolePermissionRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetUserPermissionsQuery, UserPermissionDto?>
{
    /// <inheritdoc />
    public async Task<UserPermissionDto?> Handle(GetUserPermissionsQuery request, CancellationToken cancellationToken)
    {
        // 1. 获取租户并查询用户
        var tenantId = tenantProvider.GetCurrentTenantId();
        var user = await identityUserRepository.FindByIdAsync(request.UserId, cancellationToken);
        if (user == null || user.TenantId != tenantId)
        {
            return null;
        }

        // 2. 解析角色与权限
        var roleCodes = await ResolveUserRolesAsync(tenantId, user.Id, cancellationToken);
        var permissionCodes = await ResolveUserPermissionsAsync(tenantId, user.Id, cancellationToken);

        // 3. 返回用户权限概览
        return new UserPermissionDto
        {
            UserId = user.Id,
            TenantId = user.TenantId,
            MerchantId = user.MerchantId,
            Account = user.Account,
            DisplayName = user.DisplayName,
            Roles = roleCodes,
            Permissions = permissionCodes,
            CreatedAt = user.CreatedAt
        };
    }

    private async Task<string[]> ResolveUserRolesAsync(long tenantId, long userId, CancellationToken cancellationToken)
    {
        // 1. 查询用户角色关系
        var relations = await userRoleRepository.GetByUserIdAsync(tenantId, userId, cancellationToken);
        var roleIds = relations.Select(x => x.RoleId).Distinct().ToArray();
        if (roleIds.Length == 0)
        {
            return Array.Empty<string>();
        }

        // 2. 查询角色编码
        var roles = await roleRepository.GetByIdsAsync(tenantId, roleIds, cancellationToken);
        return roles.Select(x => x.Code).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
    }

    private async Task<string[]> ResolveUserPermissionsAsync(long tenantId, long userId, CancellationToken cancellationToken)
    {
        // 1. 查询用户角色关系
        var relations = await userRoleRepository.GetByUserIdAsync(tenantId, userId, cancellationToken);
        var roleIds = relations.Select(x => x.RoleId).Distinct().ToArray();
        if (roleIds.Length == 0)
        {
            return Array.Empty<string>();
        }

        // 2. 查询角色-权限关系
        var rolePermissions = await rolePermissionRepository.GetByRoleIdsAsync(tenantId, roleIds, cancellationToken);
        var permissionIds = rolePermissions.Select(x => x.PermissionId).Distinct().ToArray();
        if (permissionIds.Length == 0)
        {
            return Array.Empty<string>();
        }

        // 3. 查询权限编码
        var permissions = await permissionRepository.GetByIdsAsync(tenantId, permissionIds, cancellationToken);
        return permissions.Select(x => x.Code).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
    }
}
