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

namespace Baya.Application.Features.Verification.Commands.RequestDocumentUploadUrl;

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

        if (currentUser.Roles?.Contains(RoleNames.Nurse) != true)
            return OperationResult<UploadUrlResult>.ForbiddenResult("Only a nurse can upload verification documents.");

        var nurseId = await unitOfWork.NurseProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (nurseId is not { } id)
            return OperationResult<UploadUrlResult>.NotFoundResult("No nurse profile exists yet.");

        var step = await unitOfWork.VerificationRepository.GetTrackedStepForNurseAsync(request.StepId, id, cancellationToken);
        if (step is null)
            return OperationResult<UploadUrlResult>.NotFoundResult("Verification step not found.");

        if (step.IsAutomated)
            return OperationResult<UploadUrlResult>.FailureResult("This step is verified automatically and does not accept document uploads.");

        // Opaque, tenant-scoped key; the mock stores on local disk, a real provider presigns a PUT URL.
        var key = $"verification/{id}/{step.Id}/{Guid.NewGuid():N}";
        var uploadUrl = objectStorage.GetUrl(key);

        return OperationResult<UploadUrlResult>.SuccessResult(new UploadUrlResult(key, uploadUrl));
    }
}
