#nullable enable
using Baya.Application.Common;
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Common;
using Baya.Application.Models.PartnerCenters;
using Mediator;

namespace Baya.Application.Features.PartnerCenters.Queries.GetCenterDashboard;

/// <summary>Authorizes the dashboard to the center's own account (or staff) and returns its read model.</summary>
internal sealed class GetCenterDashboardQueryHandler(
    ICurrentUser currentUser,
    IUnitOfWork unitOfWork)
    : IRequestHandler<GetCenterDashboardQuery, OperationResult<CenterDashboardDto>>
{
    public async ValueTask<OperationResult<CenterDashboardDto>> Handle(GetCenterDashboardQuery request, CancellationToken cancellationToken)
    {
        if (currentUser.UserId is not { } userId)
            return OperationResult<CenterDashboardDto>.UnauthorizedResult("Not authenticated.");

        var centerAdminUserId = await unitOfWork.PartnerCenterRepository.GetAdminUserIdAsync(request.CenterId, cancellationToken);
        if (centerAdminUserId is null)
            return OperationResult<CenterDashboardDto>.NotFoundResult("Partner center not found.");

        if (!StaffRoles.IsStaff(currentUser.Roles) && centerAdminUserId != userId)
            return OperationResult<CenterDashboardDto>.ForbiddenResult("This dashboard belongs to another center.");

        var dashboard = await unitOfWork.PartnerCenterRepository.GetDashboardAsync(request.CenterId, cancellationToken);
        return OperationResult<CenterDashboardDto>.SuccessResult(dashboard!);
    }
}
