<?php

declare(strict_types=1);

namespace Drupal\acquia_dam\Plugin\Field\FieldType;

use Drupal\acquia_dam\Plugin\media\acquia_dam\MediaSourceTypeBase;
use Drupal\acquia_dam\Plugin\media\acquia_dam\MediaSourceTypeInterface;
use Drupal\acquia_dam\Plugin\media\Source\Asset;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Field type for storing reference to an asset in the DAM.
 *
 * @FieldType(
 *   id = "acquia_dam_asset",
 *   label = @Translation("Asset"),
 *   description = @Translation("Targets an asset in the Acquia DAM."),
 *   no_ui = TRUE,
 *   default_formatter = "acquia_dam_embed_code",
 *   default_widget = "acquia_dam_asset_item"
 * )
 *
 * @property string $asset_id
 * @property string $version_id
 * @property string $external_id
 */
final class AssetItem extends FieldItemBase {

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array {
    $properties = [];
    $properties['asset_id'] = DataDefinition::create('string')
      ->setLabel('Asset ID')
      ->setDescription('The asset identifier.')
      ->setRequired(TRUE);
    $properties['version_id'] = DataDefinition::create('string')
      ->setLabel('Version ID')
      ->setDescription('The version ID for the asset.')
      ->setRequired(FALSE);
    $properties['external_id'] = DataDefinition::create('string')
      ->setLabel('External ID')
      ->setDescription('The external ID for the asset.')
      ->setRequired(FALSE);
    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition): array {
    return [
      'columns' => [
        'asset_id' => [
          'type' => 'varchar_ascii',
          'length' => 255,
        ],
        'version_id' => [
          'type' => 'varchar_ascii',
          'length' => 255,
        ],
        'external_id' => [
          'type' => 'varchar_ascii',
          'length' => 255,
        ],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function mainPropertyName(): string {
    return 'asset_id';
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty(): bool {
    $value = $this->get('asset_id')->getValue();
    return $value === NULL || $value === '';
  }

  /**
   * {@inheritdoc}
   */
  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
    if (!$field_definition->getTargetBundle()) {
      return [];
    }
    $media_type = \Drupal::entityTypeManager()->getStorage('media_type')->load($field_definition->getTargetBundle());
    $media_source = $media_type->getSource();
    assert($media_source instanceof Asset);
    $asset_class = $media_source->getPluginDefinition()['asset_class'] ?? MediaSourceTypeBase::class;
    assert(class_exists($asset_class) && is_subclass_of($asset_class, MediaSourceTypeInterface::class));
    // Each media source plugin should implement its own logic to generate
    // a sample value.
    if (method_exists($asset_class, 'generateSampleValue')) {
      return $asset_class::generateSampleValue($field_definition);
    }
    return MediaSourceTypeBase::generateSampleValue($field_definition);
  }

}
