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

namespace Baya.Application.Features.Bookings.Queries.GetVisitVerification;

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

        var gate = await unitOfWork.BookingRepository.GetEvvForSessionAsync(request.SessionId, cancellationToken);
        if (gate is null)
            return OperationResult<VisitVerificationDto>.NotFoundResult("Session not found.");

        var isAdmin = currentUser.Roles?.Any(BookingRoles.Admin.Contains) == true;
        var nurseId = await unitOfWork.NurseProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);

        // Raw GPS detail is gated to the owning nurse + admin only.
        if (nurseId != gate.NurseId && !isAdmin)
            return OperationResult<VisitVerificationDto>.NotFoundResult("Session not found.");

        if (gate.Evv is null)
            return OperationResult<VisitVerificationDto>.NotFoundResult("No EVV record exists for this session yet.");

        return OperationResult<VisitVerificationDto>.SuccessResult(gate.Evv);
    }
}
