#nullable enable
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Common;
using Baya.Application.Models.Payouts;
using Baya.Domain.Entities.User;
using Mediator;

namespace Baya.Application.Features.Payouts.Queries.GetNursePayoutDetail;

internal sealed class GetNursePayoutDetailQueryHandler(
    ICurrentUser currentUser,
    IUnitOfWork unitOfWork)
    : IRequestHandler<GetNursePayoutDetailQuery, OperationResult<NursePayoutDetailDto>>
{
    public async ValueTask<OperationResult<NursePayoutDetailDto>> Handle(GetNursePayoutDetailQuery request, CancellationToken cancellationToken)
    {
        if (currentUser.UserId is not { } userId)
            return OperationResult<NursePayoutDetailDto>.UnauthorizedResult("Not authenticated.");

        if (currentUser.Roles?.Contains(RoleNames.Nurse) != true)
            return OperationResult<NursePayoutDetailDto>.ForbiddenResult("Only a nurse can read their payout.");

        var nurseId = await unitOfWork.NurseProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (nurseId is not { } nid)
            return OperationResult<NursePayoutDetailDto>.NotFoundResult("Payout not found.");

        var detail = await unitOfWork.PayoutRepository.GetNursePayoutDetailAsync(request.PayoutId, nid, cancellationToken);
        return detail is null
            ? OperationResult<NursePayoutDetailDto>.NotFoundResult("Payout not found.")
            : OperationResult<NursePayoutDetailDto>.SuccessResult(detail);
    }
}
