<?php

declare(strict_types=1);

namespace Drupal\acquia_dam\Plugin\Field;

use Drupal\acquia_dam\Entity\MediaSourceField;
use Drupal\acquia_dam\Plugin\media\Source\Asset;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\file\FileInterface;
use Drupal\media\MediaInterface;
use Drupal\media\MediaSourceInterface;

/**
 * Computed field class to dynamically return asset field values.
 */
class AssetFieldItemList extends FieldItemList {
  use ComputedItemListTrait;

  /**
   * The computed value.
   *
   * @var array
   */
  protected array $computedValue = [];

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    $entity = $this->getEntity();
    if (!$entity instanceof MediaInterface) {
      return;
    }

    $uri = NULL;
    if ($this->isLocalAssetEnabled()) {
      $assetField = $entity->get($this->getSource()->getLocalFileAssetField());
      if ($assetField && !$assetField->isEmpty()) {
        $entity = $assetField->first();
        $file = $assetField->first()->get('entity')?->getTarget()?->getValue();
        if ($file instanceof FileInterface) {
          $uri = $file->getFileUri();
        }
      }
    }

    // Fall back to DAM asset URI if local asset is not available.
    if (!$uri) {
      $assetField = $entity->get(MediaSourceField::SOURCE_FIELD_NAME);
      if ($assetField && !$assetField->isEmpty()) {
        $asset_details = $assetField->first()->getValue();
        $uri = "acquia-dam://" . $asset_details['asset_id'] . "/" . $asset_details['version_id'];
      }
    }

    // Generate the file URL if URI is set.
    if ($uri) {
      /** @var \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator */
      $file_url_generator = \Drupal::service('file_url_generator');
      $this->computedValue = [
        'src' => $file_url_generator->generateString($uri)
      ];
      $this->list[0] = $this->createItem(0, $this->computedValue);
    }
  }

  /**
   * Gets the media source for the current entity.
   *
   * @return \Drupal\media\MediaSourceInterface
   *   The media source object associated with the entity.
   */
  protected function getSource(): MediaSourceInterface {
    $entity = $this->getEntity();
    assert($entity->getSource() instanceof Asset);
    return $entity->getSource();
  }

  /**
   * Determines if assets should be served from the local Drupal filesystem.
   *
   * Checks the media source configuration for the 'download_assets' setting.
   *
   * @return bool
   *   TRUE if local asset serving is enabled; FALSE otherwise.
   */
  protected function isLocalAssetEnabled(): bool {
    $entity = $this->getEntity();
    $source_configuration = $entity->bundle->entity->get('source_configuration');
    return $source_configuration['download_assets'] ?? FALSE;
  }

}
