<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media_ui\Hook;

use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface;
use Drupal\media\MediaInterface;

/**
 * Entity operation hook implementations for FFmpeg Media UI.
 */
final class EntityOperationHooks {

  use StringTranslationTrait;

  /**
   * Constructs an EntityOperationHooks object.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   The current user.
   * @param \Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface $formatterSettingsResolver
   *   Formatter settings resolver service.
   * @param \Drupal\Core\Access\AccessManagerInterface $accessManager
   *   Route access manager.
   */
  public function __construct(
    protected readonly AccountProxyInterface $currentUser,
    protected readonly FormatterSettingsResolverInterface $formatterSettingsResolver,
    protected readonly AccessManagerInterface $accessManager,
  ) {}

  /**
   * Implements hook_entity_operation().
   *
   * @phpstan-return array<string, mixed>
   */
  #[Hook('entity_operation')]
  public function entityOperation(EntityInterface $entity): array {
    $operations = [];

    if (!$entity instanceof MediaInterface) {
      return $operations;
    }

    // Show operations only for media bundles with FFmpeg
    // formatter configuration.
    if ($this->formatterSettingsResolver->getContextsForEntity($entity) === []) {
      return $operations;
    }

    $routeParameters = ['media' => $entity->id()];

    if ($this->isRouteAccessible('ffmpeg_media_ui.transcode', $routeParameters)) {
      $operations['transcode'] = [
        'title' => $this->t('Transcode'),
        'url' => Url::fromRoute('ffmpeg_media_ui.transcode', $routeParameters),
        'weight' => 50,
      ];
    }

    if ($this->isRouteAccessible('ffmpeg_media_ui.status', $routeParameters)) {
      $operations['conversion_status'] = [
        'title' => $this->t('Status'),
        'url' => Url::fromRoute('ffmpeg_media_ui.status', $routeParameters),
        'weight' => 51,
      ];
    }

    return $operations;
  }

  /**
   * Checks whether the current user may access a named route.
   *
   * @param string $routeName
   *   Route name to evaluate.
   * @param array<string, mixed> $parameters
   *   Route parameters.
   *
   * @return bool
   *   TRUE when access is allowed.
   */
  #[\NoDiscard]
  protected function isRouteAccessible(string $routeName, array $parameters): bool {
    return $this->accessManager->checkNamedRoute($routeName, $parameters, $this->currentUser);
  }

}
