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

namespace Baya.Application.Features.Reviews.Queries.GetMyReview;

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

        var projection = await unitOfWork.ReviewRepository.GetMyReviewForBookingAsync(request.BookingId, cancellationToken);

        // No review yet → a clean "none" state (only for a booking the caller could own). A review owned by a
        // different customer is indistinguishable from "none" — never leak another customer's review.
        if (projection is null || projection.CustomerUserId != userId)
            return OperationResult<MyReviewDto>.SuccessResult(new MyReviewDto(MyReviewDto.StatusNone, null, null, [], null));

        return OperationResult<MyReviewDto>.SuccessResult(projection.Review);
    }
}
