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

namespace Baya.Application.Features.Verification.Queries.GetTrustBadge;

internal sealed class GetVerifiedTrustBadgeQueryHandler(
    IUnitOfWork unitOfWork,
    ICacheService cache,
    IDateTimeProvider dateTimeProvider)
    : IRequestHandler<GetVerifiedTrustBadgeQuery, OperationResult<TrustBadgeDto>>
{
    public async ValueTask<OperationResult<TrustBadgeDto>> Handle(GetVerifiedTrustBadgeQuery request, CancellationToken cancellationToken)
    {
        var key = VerificationCache.BadgeKey(request.NurseId);

        var cached = await cache.GetAsync<TrustBadgeDto>(key, cancellationToken);
        if (cached is not null)
            return OperationResult<TrustBadgeDto>.SuccessResult(cached);

        var today = DateOnly.FromDateTime(dateTimeProvider.UtcNow.UtcDateTime);
        var badge = await unitOfWork.VerificationRepository.GetTrustBadgeAsync(request.NurseId, today, cancellationToken);
        if (badge is null)
            return OperationResult<TrustBadgeDto>.NotFoundResult("Nurse not found.");

        // Only found badges are cached; a suspension/expiry evicts this key so it is never stale-verified.
        await cache.SetAsync(key, badge, VerificationCache.BadgeTtl, cancellationToken);
        return OperationResult<TrustBadgeDto>.SuccessResult(badge);
    }
}
