<?php

declare(strict_types=1);

namespace Plugin\tnt_stabila_shop\src\Helper;

/**
 * Pure decision helper that rate-limits how often an error event is forwarded
 * to Sentry.
 *
 * Each forward is a synchronous, in-request HTTP POST, so an unthrottled burst
 * (e.g. many errors raised while saving one form) blocks the shop request for
 * seconds per event. To bound that, at most one event per session is forwarded
 * within a rolling window: any event whose timestamp is within
 * $windowSeconds of the last forwarded event is dropped.
 *
 * The first event of a session (no previous timestamp) is always allowed.
 *
 * NOTE: the historic implementation only dropped events 2..window seconds after
 * the last one, which let same-request bursts (events ~0s apart) through — the
 * exact case that stalled the request. This helper closes that gap by dropping
 * everything from 0 up to and including the window.
 */
class EventThrottleDecider
{
    /** Default rolling window (seconds) during which a further event is suppressed. */
    public const DEFAULT_WINDOW_SECONDS = 60;

    /**
     * Whether an event at $eventTimeStamp should be dropped given the last
     * forwarded event's timestamp.
     *
     * @param float|null $lastEventTimeStamp Timestamp of the last forwarded event, or null if none yet.
     * @param float      $eventTimeStamp     Timestamp of the event under consideration.
     * @param int        $windowSeconds      Rolling suppression window in seconds.
     * @return bool True when the event is within the window and must be dropped.
     */
    public static function shouldDrop(
        ?float $lastEventTimeStamp,
        float $eventTimeStamp,
        int $windowSeconds = self::DEFAULT_WINDOW_SECONDS
    ): bool {
        if ($lastEventTimeStamp === null) {
            return false;
        }
        $secondsSinceLastEvent = $eventTimeStamp - $lastEventTimeStamp;

        return $secondsSinceLastEvent >= 0 && $secondsSinceLastEvent <= $windowSeconds;
    }
}
