<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media_ui\Service;

use Drupal\media\MediaInterface;

/**
 * Interface for media transcoding operations from UI.
 *
 * @internal
 */
interface MediaOperationsServiceInterface {

  /**
   * Resolves a requested field name to the canonical configured context field.
   *
   * Invalid or empty field names fall back to the preferred configured
   * context, then finally to the media source field.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   The requested field name.
   *
   * @return string
   *   The canonical field name to use for UI operations.
   */
  #[\NoDiscard]
  public function resolveFieldName(MediaInterface $media, string $fieldName = ''): string;

  /**
   * Queues a media item for transcoding.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string|null $profileId
   *   Optional profile ID override.
   * @param array{selected_outputs?: array<int, string>, streaming_options?: array<string, mixed>} $options
   *   Additional options.
   * @param string $fieldName
   *   Source field name. Empty string for auto-detection.
   *
   * @return bool
   *   TRUE if queued successfully.
   */
  public function queueForTranscode(
    MediaInterface $media,
    ?string $profileId = NULL,
    array $options = [],
    string $fieldName = '',
  ): bool;

  /**
   * Gets the conversion status for a media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return array{status: string, progress: int, message: string|null, started: int|null, updated: int|null}
   *   Status information.
   */
  #[\NoDiscard]
  public function getStatus(MediaInterface $media, string $fieldName = ''): array;

  /**
   * Checks if a media item is currently being processed.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return bool
   *   TRUE if processing.
   */
  #[\NoDiscard]
  public function isProcessing(MediaInterface $media): bool;

  /**
   * Checks if a media item has completed transcoding.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return bool
   *   TRUE if completed.
   */
  #[\NoDiscard]
  public function isCompleted(MediaInterface $media): bool;

  /**
   * Gets the outputs for a media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return array<string, array{type: string, label: string, values: array<int, array{fid: int|string|null, filename: string|null, size: int|null, url: string}>}>
   *   Array of output information keyed by output type.
   */
  #[\NoDiscard]
  public function getOutputs(MediaInterface $media, string $fieldName = ''): array;

  /**
   * Clears all transcoded outputs for a media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param bool $deleteFiles
   *   Whether to delete the actual files.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return bool
   *   TRUE if cleared successfully.
   */
  public function clearOutputs(MediaInterface $media, bool $deleteFiles = TRUE, string $fieldName = ''): bool;

  /**
   * Re-queues a media item for transcoding (refresh).
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param bool $clearFirst
   *   Whether to clear existing outputs first.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return bool
   *   TRUE if re-queued successfully.
   */
  public function refresh(MediaInterface $media, bool $clearFirst = TRUE, string $fieldName = ''): bool;

  /**
   * Gets video information for a media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return array{duration: float, width: int, height: int, codec: string, format: string, bitrate: int|null, framerate: float|null}|null
   *   Video info or NULL if not available.
   */
  #[\NoDiscard]
  public function getVideoInfo(MediaInterface $media, string $fieldName = ''): ?array;

  /**
   * Gets the source file path for a media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return string|null
   *   File path or NULL.
   */
  #[\NoDiscard]
  public function getSourceFile(MediaInterface $media, string $fieldName = ''): ?string;

  /**
   * Checks if a media item is currently queued for transcoding.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   *
   * @return bool
   *   TRUE if queued.
   */
  #[\NoDiscard]
  public function isQueued(MediaInterface $media, string $fieldName = ''): bool;

  /**
   * Cancels a queued transcoding for a media item.
   *
   * Removes the item from the queue and clears any progress tracking.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name override.
   */
  public function cancelQueuedTranscoding(MediaInterface $media, string $fieldName = ''): void;

}
