<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Commands;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\ffmpeg_media\Service\FFmpegExecutorInterface;
use Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface;
use Drupal\ffmpeg_media\Service\SourceFileResolverInterface;
use Drupal\ffmpeg_media\Service\VideoConverterInterface;
use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;

/**
 * Drush commands for FFmpeg Media video information and status inspection.
 */
final class StatusCommands extends DrushCommands {

  use CommandHelperTrait;

  /**
   * Constructs a StatusCommands instance.
   *
   * @param \Drupal\ffmpeg_media\Service\VideoConverterInterface $videoConverter
   *   Video converter service.
   * @param \Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface $formatterSettingsResolver
   *   Formatter settings resolver service.
   * @param \Drupal\ffmpeg_media\Service\SourceFileResolverInterface $sourceFileResolver
   *   Source file resolver service.
   * @param \Drupal\ffmpeg_media\Service\FFmpegExecutorInterface $ffmpegExecutor
   *   FFmpeg executor service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   */
  public function __construct(
    protected readonly VideoConverterInterface $videoConverter,
    protected readonly FormatterSettingsResolverInterface $formatterSettingsResolver,
    protected readonly SourceFileResolverInterface $sourceFileResolver,
    protected readonly FFmpegExecutorInterface $ffmpegExecutor,
    protected readonly EntityTypeManagerInterface $entityTypeManager,
  ) {
    parent::__construct();
  }

  /**
   * Show video metadata using ffprobe.
   *
   * @param int $media_id
   *   The media entity ID.
   */
  #[CLI\Command(name: 'ffmpeg:info', aliases: ['ffi'])]
  #[CLI\Argument(name: 'media_id', description: 'The media entity ID to inspect.')]
  #[CLI\Usage(name: 'ffmpeg:info 123', description: 'Show video metadata for media ID 123.')]
  public function showInfo(int $media_id): void {
    $media = $this->loadMedia($media_id, $this->entityTypeManager, $this->formatterSettingsResolver);
    if ($media === NULL) {
      return;
    }

    $contexts = $this->formatterSettingsResolver->getContextsForEntity($media);
    $context = $contexts[0] ?? NULL;
    if ($context === NULL) {
      $this->logger()?->error('No FFmpeg formatter configuration found for this media type.');
      return;
    }

    $sourcePath = $this->sourceFileResolver->getSourcePath($media, $context->fieldName);
    if ($sourcePath === NULL) {
      $this->logger()?->error('Source file not found for media {id}.', ['id' => $media_id]);
      return;
    }

    $videoInfo = $this->ffmpegExecutor->getVideoInfo($sourcePath);
    if ($videoInfo === NULL) {
      $this->logger()?->error('Could not probe video file: {path}', ['path' => $sourcePath]);
      return;
    }

    $this->io()->title("Video Information for Media {$media_id}");

    $this->io()->section('Source File');
    $this->io()->definitionList(
      ['Path' => $sourcePath],
      ['Format' => $videoInfo->format],
      ['Duration' => $this->formatDuration((int) $videoInfo->duration)],
      ['Resolution' => "{$videoInfo->width}x{$videoInfo->height}"],
      ['Aspect Ratio' => $videoInfo->aspectRatio],
      ['Resolution Tier' => $videoInfo->resolutionTier],
    );

    $this->io()->section('Video Stream');
    $this->io()->definitionList(
      ['Codec' => $videoInfo->codec],
      ['Bitrate' => $this->formatBitrate($videoInfo->bitrate)],
      ['Frame Rate' => round($videoInfo->frameRate, 2) . ' fps'],
      ['Rotation' => $videoInfo->rotation ? "{$videoInfo->rotation} degrees" : 'None'],
    );

    if ($videoInfo->hasAudio) {
      $this->io()->section('Audio Stream');
      $this->io()->definitionList(
        ['Codec' => $videoInfo->audioCodec ?? 'N/A'],
        ['Bitrate' => $this->formatBitrate($videoInfo->audioBitrate ?? 0)],
        ['Channels' => $videoInfo->audioChannels ?? 'N/A'],
      );
    }

    // Show conversion status.
    $status = $this->videoConverter->getStatus($media);
    $this->io()->section('Conversion Status');
    $this->io()->definitionList(
      ['Has Source' => $status['has_source'] ? 'Yes' : 'No'],
      ['Is Queued' => $status['is_queued'] ? 'Yes' : 'No'],
      ['Is Converting' => $status['is_converting'] ? 'Yes' : 'No'],
      ['Is Converted' => $status['is_converted'] ? 'Yes' : 'No'],
    );

    if (!empty($status['outputs'])) {
      $this->io()->section('Converted Outputs');
      foreach ($status['outputs'] as $format => $uri) {
        $this->io()->writeln("  {$format}: {$uri}");
      }
    }

    if ($status['error']) {
      $this->io()->error("Last Error: {$status['error']}");
    }
  }

}
