<?php

declare(strict_types=1);

namespace Drupal\acquia_dam\Plugin\Field;

use Drupal\acquia_dam\Entity\ImageAltTextField;
use Drupal\file\FileInterface;

/**
 * Computed field class to dynamically return image field values.
 */
final class ImageFieldItemList extends AssetFieldItemList {

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    parent::computeValue();
    if ($this->computedValue) {
      $entity = $this->getEntity();
      $value = [
        // Retrieve alt text from the media entity;
        // use media label without file extension if alt text is unavailable.
        'alt' => $entity->get(ImageAltTextField::IMAGE_ALT_TEXT_FIELD_NAME)->value ?? pathinfo($entity->label(), PATHINFO_FILENAME),
        'width' => $this->getImageSize('width'),
        'height' => $this->getImageSize('height'),
      ];
      $this->list[0] = $this->createItem(0, ($this->computedValue + $value));
    }
  }

  /**
   * Gets the image size for the specified property.
   *
   * Attempts to retrieve the image dimension (width or height) from the local
   * file asset if download & sync option is enabled, fallback to metadata.
   *
   * @param string $property
   *   The image property to retrieve ('width' or 'height').
   */
  protected function getImageSize(string $property): int|null {
    $entity = $this->getEntity();
    if ($this->isLocalAssetEnabled()) {
      $field = $entity->get($this->getSource()->getLocalFileAssetField());
      $file = $field->first()->get('entity')?->getTarget()?->getValue();
      if (!$field->isEmpty() && $file instanceof FileInterface) {
        $image = \Drupal::service('image.factory')->get($file->getFileUri());
        $size = match ($property) {
          'width' => $image->getWidth(),
          'height' => $image->getHeight(),
        };
      }
    }
    if (!isset($size)) {
      $image_properties = $this->getSource()->getMetadata($entity, 'image_properties');
      // Cast value to integer for correct type, as Acquia DAM returns floats.
      // Also, we should return NULL if the value is zero.
      $size = !empty($image_properties[$property]) ? (int) $image_properties[$property] : NULL;
    }
    return $size;
  }

}
