<?php

namespace Drupal\image_replace\Plugin\ImageToolkit\Operation\imagemagick;

use Drupal\Core\Image\ImageInterface;
use Drupal\Core\ImageToolkit\Attribute\ImageToolkitOperation;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit;
use Drupal\imagemagick\Plugin\ImageToolkit\Operation\imagemagick\ImagemagickImageToolkitOperationBase;

/**
 * Defines ImageMagick image_replace operation.
 */
#[ImageToolkitOperation(
  id: "image_replace_imagemagick",
  toolkit: "imagemagick",
  operation: "image_replace",
  label: new TranslatableMarkup("Replace"),
  description: new TranslatableMarkup("Swap the original image with a replacement image.")
)]
class Replace extends ImagemagickImageToolkitOperationBase {

  /**
   * {@inheritdoc}
   *
   * @phpstan-return array<string, array<string, string>>
   */
  protected function arguments(): array {
    return [
      'replacement_image' => [
        'description' => 'The replacement image',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   *
   * @phpstan-param array<string, mixed> $arguments
   * @phpstan-return array<string, mixed>
   */
  protected function validateArguments(array $arguments): array {
    if (!($arguments['replacement_image'] instanceof ImageInterface && $arguments['replacement_image']->getToolkit() instanceof ImagemagickToolkit)) {
      throw new \InvalidArgumentException("Invalid replacement image specified for the 'image_replace' operation.");
    }
    return $arguments;
  }

  /**
   * {@inheritdoc}
   *
   * @phpstan-param array<string, mixed> $arguments
   */
  protected function execute(array $arguments = []): bool {
    $replacement_image = $arguments['replacement_image'];
    assert($replacement_image instanceof ImageInterface);
    $replacement = $replacement_image->getToolkit();
    assert($replacement instanceof ImagemagickToolkit);

    // Replace original image's source with replacement image's source.
    $this->getToolkit()->arguments()
      ->setSource($replacement->arguments()->getSource());
    $this->getToolkit()
      ->setWidth($replacement->getWidth())
      ->setHeight($replacement->getHeight());

    return TRUE;
  }

}
