<?php

declare(strict_types=1);

namespace Drupal\{{ machine_name }}\Plugin\Field\FieldFormatter;

{% apply sort_namespaces %}
  {% if datetime %}
use Drupal\Core\Datetime\DrupalDateTime;
  {% endif %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
  {% if formatter_settings %}
use Drupal\Core\Form\FormStateInterface;
  {% endif %}
  {% if link %}
use Drupal\Core\Url;
  {% endif %}
  {% if list %}
use Drupal\{{ machine_name }}\Plugin\Field\FieldType\{{ type_class }};
  {% endif %}
{% endapply %}

/**
 * Plugin implementation of the '{{ field_id }}_default' formatter.
 *
 * @FieldFormatter(
 *   id = "{{ field_id }}_default",
 *   label = @Translation("Default"),
 *   field_types = {"{{ field_id }}"},
 * )
 */
final class {{ formatter_class }} extends FormatterBase {

{% if formatter_settings %}
  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    return ['foo' => 'bar'] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $element['foo'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Foo'),
      '#default_value' => $this->getSetting('foo'),
    ];
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary(): array {
    return [
      $this->t('Foo: @foo', ['@foo' => $this->getSetting('foo')]),
    ];
  }

{% endif %}
  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode): array {
    $element = [];

    foreach ($items as $delta => $item) {

{% for subfield in subfields %}
  {% if subfield.type == 'boolean' %}
      $element[$delta]['{{ subfield.machine_name }}'] = [
        '#type' => 'item',
        '#title' => $this->t('{{ subfield.name }}'),
        '#markup' => $item->{{ subfield.machine_name }} ? $this->t('Yes') : $this->t('No'),
      ];

  {% else %}
      if ($item->{{ subfield.machine_name }}) {
    {% if subfield.list %}
        $allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
    {% endif %}
    {% set item_value %}
      {% if subfield.list %}$allowed_values[$item->{{ subfield.machine_name }}]{% else %}$item->{{ subfield.machine_name }}{% endif %}
    {% endset %}
    {% if subfield.type == 'datetime' %}
        $date = DrupalDateTime::createFromFormat('{{ subfield.date_storage_format }}', $item->{{ subfield.machine_name }});
        // @DCG: Consider injecting the date formatter service.
        // @codingStandardsIgnoreStart
        $date_formatter = \Drupal::service('date.formatter');
        // @codingStandardsIgnoreStart
        $timestamp = $date->getTimestamp();
      {% if subfield.list %}
        $formatted_date = {{ item_value }};
      {% else %}
        $formatted_date = $date_formatter->format($timestamp, 'long');
      {% endif %}
        $iso_date = $date_formatter->format($timestamp, 'custom', 'Y-m-d\TH:i:s') . 'Z';
        $element[$delta]['{{ subfield.machine_name }}'] = [
          '#type' => 'item',
          '#title' => $this->t('{{ subfield.name }}'),
          'content' => [
            '#theme' => 'time',
            '#text' => $formatted_date,
            '#html' => FALSE,
            '#attributes' => [
              'datetime' => $iso_date,
            ],
            '#cache' => [
              'contexts' => [
                'timezone',
              ],
            ],
          ],
        ];
    {% else %}
        $element[$delta]['{{ subfield.machine_name }}'] = [
          '#type' => 'item',
          '#title' => $this->t('{{ subfield.name }}'),
      {% if subfield.link %}
          'content' => [
            '#type' => 'link',
            '#title' => {{ item_value }},
        {% if subfield.type == 'email' %}
            '#url' => Url::fromUri('mailto:' . $item->{{ subfield.machine_name }}),
        {% elseif subfield.type == 'telephone' %}
            '#url' => Url::fromUri('tel:' . rawurlencode(preg_replace('/\s+/', '', $item->{{ subfield.machine_name }}))),
        {% elseif subfield.type == 'uri' %}
            '#url' => Url::fromUri($item->{{ subfield.machine_name }}),
        {% endif %}
          ],
      {% else %}
          '#markup' => {{ item_value }},
      {% endif %}
        ];
    {% endif %}
      }

  {% endif %}
{% endfor %}
    }

    return $element;
  }

}
