<?php

namespace KupShop\MessengerBundle\Util;

use KupShop\MessengerBundle\Message\Envelope\EnvelopeInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
use Symfony\Component\Messenger\Stamp\RedeliveryStamp;

class EnvelopeRetryStrategy implements RetryStrategyInterface
{
    public function __construct(protected int $maxRetries = 5, protected int $delayMilliseconds = 60000, protected float $multiplier = 4)
    {
    }

    public function isRetryable(Envelope $message, ?\Throwable $throwable = null): bool
    {
        $retries = RedeliveryStamp::getRetryCountFromEnvelope($message);

        $retryCount = $this->maxRetries;

        $message = $message->getMessage();
        if ($message instanceof EnvelopeInterface) {
            $retryCount = $message->getRetryCount();
        }

        return $retries < $retryCount;
    }

    /**
     * @param \Throwable|null $throwable The cause of the failed handling
     */
    public function getWaitingTime(Envelope $message, ?\Throwable $throwable = null): int
    {
        $retries = RedeliveryStamp::getRetryCountFromEnvelope($message);

        $delay = $this->delayMilliseconds * $this->multiplier ** $retries;

        return (int) ceil($delay);
    }
}
