<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Service;

/**
 * Interface for managing conversion retry logic with exponential backoff.
 *
 * @internal Runtime service, not part of the supported contrib extension API.
 */
interface RetryManagerInterface {

  /**
   * Default base delay in seconds.
   */
  public const int DEFAULT_BASE_DELAY = 60;

  /**
   * Default maximum delay in seconds.
   */
  public const int DEFAULT_MAX_DELAY = 3600;

  /**
   * Default maximum retry attempts.
   */
  public const int DEFAULT_MAX_RETRIES = 5;

  /**
   * Determines if a media conversion should be retried.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   *
   * @return bool
   *   TRUE if retry should be attempted, FALSE if max retries exceeded.
   */
  #[\NoDiscard]
  public function shouldRetry(int $mediaId, string $fieldName = ''): bool;

  /**
   * Gets the next retry time as Unix timestamp.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   *
   * @return int
   *   Unix timestamp for next retry attempt.
   */
  #[\NoDiscard]
  public function getNextRetryTime(int $mediaId, string $fieldName = ''): int;

  /**
   * Gets the delay before next retry in seconds.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   *
   * @return int
   *   Delay in seconds.
   */
  #[\NoDiscard]
  public function getRetryDelay(int $mediaId, string $fieldName = ''): int;

  /**
   * Records a retry attempt for a media entity.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string|null $errorMessage
   *   Optional error message from the failed attempt.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   */
  public function recordRetry(int $mediaId, ?string $errorMessage = NULL, string $fieldName = ''): void;

  /**
   * Gets the current retry count for a media entity.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   *
   * @return int
   *   Number of retry attempts.
   */
  #[\NoDiscard]
  public function getRetryCount(int $mediaId, string $fieldName = ''): int;

  /**
   * Resets retry tracking for a media entity.
   *
   * Called when conversion succeeds.
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name. Empty string resets all retry rows
   *   for the media entity.
   */
  public function resetRetries(int $mediaId, string $fieldName = ''): void;

  /**
   * Checks if retry is currently due (delay has elapsed).
   *
   * @param int $mediaId
   *   The media entity ID.
   * @param string $fieldName
   *   Optional source field name for field-scoped retry tracking.
   *
   * @return bool
   *   TRUE if retry is due, FALSE if still in delay period.
   */
  #[\NoDiscard]
  public function isRetryDue(int $mediaId, string $fieldName = ''): bool;

  /**
   * Gets all items pending retry.
   *
   * @return array<int, array{media_id: int, field_name: string, retry_count: int, next_retry: int}>
   *   Array of pending retry items.
   */
  #[\NoDiscard]
  public function getPendingRetries(): array;

  /**
   * Cleans up old retry records.
   *
   * @param int $maxAge
   *   Maximum age in seconds for retry records.
   *
   * @return int
   *   Number of records cleaned up.
   */
  public function cleanup(int $maxAge = 604800): int;

}
