<?php

declare(strict_types=1);

namespace Drupal\acquia_dam\Plugin\Field\FieldType;

use Drupal\acquia_dam\TypedData\AssetDerivativeWithParametrizedWidth;
use Drupal\canvas\Plugin\DataType\ComputedUrlWithQueryString;
use Drupal\canvas\Plugin\Validation\Constraint\UriConstraint;
use Drupal\canvas\Plugin\Validation\Constraint\UriSchemeConstraint;
use Drupal\canvas\Plugin\Validation\Constraint\UriTargetMediaTypeConstraint;
use Drupal\canvas\Plugin\Validation\Constraint\UriTemplateWithVariablesConstraint;
use Drupal\canvas\PropExpressions\StructuredData\FieldTypePropExpression;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Class AssetFieldItem.
 */
class ImageFieldType extends AssetFieldType {

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array {
    $properties['alt'] = DataDefinition::create('string')
      ->setLabel('Asset Alt')
      ->setRequired(FALSE)
      ->setReadOnly(TRUE);

    $properties['width'] = DataDefinition::create('integer')
      ->setLabel('Asset width')
      ->setRequired(FALSE)
      ->setReadOnly(TRUE);

    $properties['height'] = DataDefinition::create('integer')
      ->setLabel('Asset height')
      ->setRequired(FALSE)
      ->setReadOnly(TRUE);

    // If the Canvas module is enabled, add additional computed properties to
    // facilitate responsive images, otherwise these properties are not needed.
    // @see \Drupal\canvas\Plugin\Field\FieldTypeOverride\ImageItemOverride::propertyDefinitions()
    if (\Drupal::moduleHandler()->moduleExists('canvas')) {
      // A computed URI template to populate `<img srcset>` using a parametrized
      // width.
      // @todo Remove in favor of adapters in https://www.drupal.org/project/canvas/issues/3464003.
      $properties['srcset_candidate_uri_template'] = DataDefinition::create('string')
        ->setLabel('srcset template')
        ->setComputed(TRUE)
        ->setReadOnly(TRUE)
        ->addConstraint(UriTemplateWithVariablesConstraint::PLUGIN_ID, [
          'requiredVariables' => ['width'],
        ])
        ->setClass(AssetDerivativeWithParametrizedWidth::class);

      $properties['src_with_alternate_widths'] = DataDefinition::create('uri')
        ->setLabel('Asset URL')
        ->setComputed(TRUE)
        ->setReadOnly(TRUE)
        ->setSettings([
          'url' => (string)(new FieldTypePropExpression('acquia_dam:image', 'src')),
          'query_parameters' => [
            'alternateWidths' => (string)(new FieldTypePropExpression('acquia_dam:image', 'srcset_candidate_uri_template')),
          ],
        ])
        ->addConstraint(UriTargetMediaTypeConstraint::PLUGIN_ID, ['mimeType' => 'image/*'])
        // The ComputedFileUrl data type generates a browser-accessible URL (root-
        // relative, absolute using HTTP, absolute using HTTPs or relative).
        ->addConstraint(UriConstraint::PLUGIN_ID, ['allowReferences' => TRUE])
        ->addConstraint(UriSchemeConstraint::PLUGIN_ID, ['http', 'https'])
        ->setClass(ComputedUrlWithQueryString::class);
    }

    return $properties + parent::propertyDefinitions($field_definition);
  }

}
