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

namespace Baya.Application.Features.Identity.Commands.SetNurseAcceptingBookings;

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

        if (currentUser.Roles?.Contains(RoleNames.Nurse) != true)
            return OperationResult<bool>.ForbiddenResult("Only a nurse can manage a nurse profile.");

        var profile = await unitOfWork.NurseProfileRepository.GetByUserIdAsync(userId, cancellationToken);
        if (profile is null)
            return OperationResult<bool>.NotFoundResult("No nurse profile exists yet. Create your profile first.");

        profile.SetAcceptingBookings(request.Accepting);

        // Pausing/resuming bookings flips every one of the nurse's index rows' is_searchable in the same
        // transaction (verification status is unchanged here, so it is read from the committed record).
        await searchIndex.ReindexNurseAsync(profile, null, cancellationToken);
        await unitOfWork.CommitAsync();

        return OperationResult<bool>.SuccessResult(true);
    }
}
