<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Service;

use Drupal\ffmpeg_media\ValueObject\ConversionResult;
use Drupal\media\MediaInterface;

/**
 * Interface for the main video conversion orchestrator service.
 *
 * @internal Runtime service, not part of the supported contrib extension API.
 */
interface VideoConverterInterface {

  /**
   * Converts a media entity's video to configured output formats.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity to convert.
   * @param string|null $profileId
   *   Optional conversion profile ID. If NULL, uses default profile.
   * @param bool $synchronous
   *   If TRUE, runs conversion synchronously without progress updates.
   *   Useful for immediate/inline conversion needs. Default FALSE.
   * @param array{selected_outputs?: array<int, string>, streaming_options?: array<string, mixed>} $options
   *   Optional conversion options:
   *   - selected_outputs: array of output formats (e.g., ['mp4', 'hls'])
   *   - streaming_options: array of streaming config overrides.
   *
   * @return \Drupal\ffmpeg_media\ValueObject\ConversionResult
   *   Result of the conversion.
   *
   * @throws \Drupal\ffmpeg_media\Exception\FFmpegException
   *   If conversion fails.
   * @throws \Drupal\ffmpeg_media\Exception\InvalidConfigurationException
   *   If no conversion context exists for the media type.
   */
  #[\NoDiscard]
  public function convert(MediaInterface $media, ?string $profileId = NULL, bool $synchronous = FALSE, array $options = []): ConversionResult;

  /**
   * Checks if a media entity can be reconverted.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity to check.
   * @param string $fieldName
   *   Optional source field name. Empty string uses the preferred context.
   *
   * @return array{
   *   can_reconvert: bool,
   *   reason?: string|null,
   *   existing_outputs: array<string, string>
   *   }
   *   Result including reconvert flag, optional reason, and existing outputs
   *   keyed by format.
   */
  #[\NoDiscard]
  public function canReconvert(MediaInterface $media, string $fieldName = ''): array;

  /**
   * Deletes converted files for a media entity.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name. Empty string uses the preferred context.
   *
   * @return array<int, string>
   *   Array of deleted file paths.
   */
  public function deleteConvertedFiles(MediaInterface $media, string $fieldName = ''): array;

  /**
   * Gets the conversion status for a media entity.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   Optional source field name. Empty string uses the preferred context.
   *
   * @return array{
   *   has_source: bool,
   *   is_queued: bool,
   *   is_converting: bool,
   *   is_converted: bool,
   *   outputs: array<string, string>,
   *   error: string|null
   *   }
   *   Status info with outputs keyed by format.
   */
  #[\NoDiscard]
  public function getStatus(MediaInterface $media, string $fieldName = ''): array;

  /**
   * Checks if a media entity is eligible for conversion.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity to check.
   * @param string $fieldName
   *   Optional source field name. Empty string uses the preferred context.
   *
   * @return bool
   *   TRUE if eligible for conversion.
   */
  #[\NoDiscard]
  public function isEligibleForConversion(MediaInterface $media, string $fieldName = ''): bool;

  /**
   * Converts a media entity to adaptive streaming format (HLS or DASH).
   *
   * Creates multi-bitrate streaming output with multiple representations
   * suitable for adaptive bitrate delivery.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity to convert.
   * @param string $format
   *   The streaming format: 'hls' or 'dash'.
   * @param string|null $profileId
   *   Optional conversion profile ID. If NULL, uses default profile.
   * @param string $fieldName
   *   Source field name for multi-field scoping. Empty string uses
   *   the preferred-context fallback.
   *
   * @return \Drupal\ffmpeg_media\ValueObject\ConversionResult
   *   Result of the conversion.
   *
   * @throws \Drupal\ffmpeg_media\Exception\FFmpegException
   *   If conversion fails.
   * @throws \Drupal\ffmpeg_media\Exception\InvalidConfigurationException
   *   If no conversion context exists for the media type or format is invalid.
   */
  #[\NoDiscard]
  public function convertAdaptive(MediaInterface $media, string $format, ?string $profileId = NULL, string $fieldName = ''): ConversionResult;

}
