<?php

declare(strict_types=1);

namespace Drupal\animated_gif\Hook;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\animated_gif\Service\AnimatedGifInterface;
use Drupal\file\FileInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;

/**
 * Hook preprocess.
 */
class Preprocess {

  public function __construct(
    protected EntityTypeManagerInterface $entityTypeManager,
    protected AnimatedGifInterface $animatedGif,
  ) {}

  /**
   * Implements template_preprocess_image_formatter().
   */
  #[Hook('preprocess_image_formatter')]
  public function preprocessImageFormatter(array &$variables): void {
    $file = $this->preprocessFormattersGetFile($variables);
    if (!($file instanceof FileInterface)) {
      return;
    }

    if ($this->animatedGif->isFileAnAnimatedGif($file)) {
      $variables['image']['#theme'] = 'image';
      unset($variables['image']['#style_name'], $variables['image_style']);
    }
  }

  /**
   * Implements template_preprocess_responsive_image_formatter().
   */
  #[Hook('preprocess_responsive_image_formatter')]
  public function preprocessResponsiveImageFormatter(array &$variables): void {
    $file = $this->preprocessFormattersGetFile($variables);
    if (!($file instanceof FileInterface)) {
      return;
    }

    if ($this->animatedGif->isFileAnAnimatedGif($file)) {
      $variables['responsive_image']['#theme'] = 'image';
      unset($variables['image']['#responsive_image_style_id'], $variables['image_style']);
    }
  }

  /**
   * Implements template_preprocess_image_style().
   */
  #[Hook('preprocess_image_style')]
  public function preprocessImageStyle(array &$variables): void {
    $file = $this->preprocessGetFile($variables);
    if (!($file instanceof FileInterface)) {
      return;
    }

    if ($this->animatedGif->isFileAnAnimatedGif($file)) {
      $variables['image']['#uri'] = $variables['uri'];
      unset($variables['image']['#style_name'], $variables['image_style'], $variables['style_name']);
    }
  }

  /**
   * Implements template_preprocess_responsive_image().
   */
  #[Hook('preprocess_responsive_image')]
  public function preprocessResponsiveImage(array &$variables): void {
    $file = $this->preprocessGetFile($variables);
    if (!($file instanceof FileInterface)) {
      return;
    }

    if ($this->animatedGif->isFileAnAnimatedGif($file)) {
      unset($variables['img_element']['#attributes']['srcset']);
      $variables['img_element']['#uri'] = $variables['uri'];
    }
  }

  /**
   * Get file entity from preprocess variables.
   *
   * @param array $variables
   *   Preprocess variables.
   *
   * @return \Drupal\file\FileInterface|null
   *   A file entity if existing.
   */
  protected function preprocessGetFile(array $variables): ?FileInterface {
    if (!\array_key_exists('uri', $variables)) {
      return NULL;
    }

    // File entity ID is not available here, so we need to load it by URI.
    /** @var \Drupal\file\FileInterface[] $files */
    $files = $this->entityTypeManager->getStorage('file')
      ->loadByProperties(['uri' => $variables['uri']]);

    if (empty($files)) {
      return NULL;
    }

    return \reset($files);
  }

  /**
   * Get file entity from preprocess formatter variables.
   *
   * @param array $variables
   *   Preprocess variables.
   *
   * @return \Drupal\file\FileInterface|null
   *   A file entity if existing.
   */
  protected function preprocessFormattersGetFile(array $variables): ?FileInterface {
    $file = NULL;
    $image = $variables['item'];
    if (!($image instanceof ImageItem)) {
      return $file;
    }

    $imageValues = $image->getValue();
    if (isset($imageValues['entity'])) {
      /** @var \Drupal\file\FileInterface $file */
      $file = $imageValues['entity'];
    }
    elseif (isset($imageValues['target_id'])) {
      /** @var \Drupal\file\FileInterface|null $file */
      $file = $this->entityTypeManager->getStorage('file')
        // @phpstan-ignore-next-line
        ->load($imageValues['target_id']);
    }
    return $file;
  }

}
