<?php

namespace Drupal\image_replace\Plugin\ImageEffect;

use Drupal\Core\Image\ImageFactory;
use Drupal\Core\Image\ImageInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\image\Attribute\ImageEffect;
use Drupal\image\ImageEffectBase;
use Drupal\image_replace\ImageReplaceStorageInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Rotates an image resource.
 */
#[ImageEffect(
  id: "image_replace",
  label: new TranslatableMarkup("Replace image"),
  description: new TranslatableMarkup("Swap the original image if a replacement image was configured."),
)]
class ImageReplaceEffect extends ImageEffectBase {

  /**
   * The image factory service.
   */
  protected ImageFactory $imageFactory;

  /**
   * The image replace storage service.
   */
  protected ImageReplaceStorageInterface $imageReplaceStorage;

  /**
   * {@inheritdoc}
   *
   * @phpstan-param mixed[] $configuration
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger, ImageFactory $image_factory, ImageReplaceStorageInterface $image_replace_storage) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $logger);

    $this->setConfiguration($configuration);
    $this->imageFactory = $image_factory;
    $this->imageReplaceStorage = $image_replace_storage;
  }

  /**
   * {@inheritdoc}
   *
   * @phpstan-param mixed[] $configuration
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get(LoggerChannelFactoryInterface::class)->get('image'),
      $container->get(ImageFactory::class),
      $container->get(ImageReplaceStorageInterface::class)
    );
  }

  /**
   * {@inheritdoc}
   */
  public function applyEffect(ImageInterface $image): bool {
    $configuration = $this->getConfiguration();
    $replacement_file = $this->imageReplaceStorage->get($configuration['data']['image_style'], $image->getSource());
    if ($replacement_file) {
      $toolkit_id = $image->getToolkitId();
      $replacement_image = $this->imageFactory->get($replacement_file, $toolkit_id);
      $image->apply('image_replace', ['replacement_image' => $replacement_image]);
    }
    return TRUE;
  }

}
