<?php

declare(strict_types=1);

namespace Drupal\ffmpeg_media\Plugin\Action;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Action\Attribute\Action;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface;
use Drupal\ffmpeg_media\Service\QueueManagerInterface;
use Drupal\ffmpeg_media\Service\VideoConverterInterface;
use Drupal\media\MediaInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * Action to queue media for video conversion.
 */
#[Action(
  id: 'ffmpeg_media_convert',
  label: new TranslatableMarkup('Convert video'),
  type: 'media',
)]
final class ConvertVideoAction extends ActionBase implements ContainerFactoryPluginInterface {

  /**
   * Constructs a ConvertVideoAction object.
   *
   * @param array $configuration
   *   Plugin configuration.
   * @param string $plugin_id
   *   Plugin ID.
   * @param mixed $plugin_definition
   *   Plugin definition.
   * @param \Drupal\ffmpeg_media\Service\QueueManagerInterface $queueManager
   *   Queue manager service.
   * @param \Drupal\ffmpeg_media\Service\VideoConverterInterface $videoConverter
   *   Video converter service.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   Current user.
   * @param \Drupal\ffmpeg_media\Service\FormatterSettingsResolverInterface $formatterSettingsResolver
   *   Formatter settings resolver for multi-context field discovery.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    #[Autowire(service: QueueManagerInterface::class)]
    protected readonly QueueManagerInterface $queueManager,
    #[Autowire(service: VideoConverterInterface::class)]
    protected readonly VideoConverterInterface $videoConverter,
    #[Autowire(service: 'current_user')]
    protected readonly AccountProxyInterface $currentUser,
    #[Autowire(service: FormatterSettingsResolverInterface::class)]
    protected readonly FormatterSettingsResolverInterface $formatterSettingsResolver,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   *
   * @param object|null $object
   *   Object to execute this action on.
   */
  #[\Override]
  public function execute($object = NULL): void {
    if (!$object instanceof MediaInterface) {
      return;
    }

    if (!$this->videoConverter->isEligibleForConversion($object)) {
      return;
    }

    $contexts = $this->formatterSettingsResolver->getContextsForEntity($object);
    if ($contexts === []) {
      return;
    }

    foreach ($contexts as $context) {
      $this->queueManager->queueForConversion($object, 'convert', fieldName: $context->fieldName);
    }
  }

  /**
   * {@inheritdoc}
   */
  #[\Override]
  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE): AccessResultInterface|bool {
    if (!$object instanceof MediaInterface) {
      return $return_as_object ? AccessResult::forbidden() : FALSE;
    }

    $access = $object->access('update', $account, TRUE)
      ->andIf($this->accessControlHandler($account));

    return $return_as_object ? $access : $access->isAllowed();
  }

  /**
   * Checks permission access.
   *
   * @param \Drupal\Core\Session\AccountInterface|null $account
   *   The account.
   *
   * @return \Drupal\Core\Access\AccessResult
   *   Access result.
   */
  protected function accessControlHandler(?AccountInterface $account): AccessResult {
    return AccessResult::allowedIfHasPermission(
      $account ?? $this->currentUser,
      'convert media',
    );
  }

}
