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

namespace Baya.Application.Features.Identity.Queries.GetPatient;

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

        // A patient outside the caller's tenancy is indistinguishable from a non-existent one.
        var customerId = await unitOfWork.CustomerProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (customerId is not { } cid)
            return OperationResult<PatientDto>.NotFoundResult("Patient not found.");

        var dto = await unitOfWork.PatientRepository.GetOwnedProjectedAsync(request.Id, cid, cancellationToken);
        return dto is null
            ? OperationResult<PatientDto>.NotFoundResult("Patient not found.")
            : OperationResult<PatientDto>.SuccessResult(dto);
    }
}
