<?php

namespace Drupal\disign_formatters\Plugin\Field\FieldFormatter;

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\link\LinkItemInterface;
use Drupal\text_formatters\Plugin\Field\FieldFormatter\AttributesTrait;
use Drupal\text_formatters\Plugin\Field\FieldFormatter\ClassesTrait;
use Drupal\text_formatters\Plugin\Field\FieldFormatter\OuterWrapperTrait;
use Drupal\text_formatters\Plugin\Field\FieldFormatter\WrapperTrait;

/**
 * Plugin implementation of the "QR Code" formatter.
 */
#[FieldFormatter(
  id: 'qr_code',
  label: new TranslatableMarkup('QR Code'),
  field_types: [
    'link',
  ],
  weight: 10,
)]
class QrCodeFormatter extends FormatterBase {
  use OuterWrapperTrait;
  use WrapperTrait;
  use ClassesTrait;
  use AttributesTrait;

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return self::defaultOuterWrapperSettings() +
      self::defaultWrapperSettings() +
      parent::defaultSettings() +
      self::defaultClassSettings() +
      self::defaultAttributeSettings() + [
        'settings' => [
          'quiet_zone' => TRUE,
        ],
      ];
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $elements = parent::settingsForm($form, $form_state);
    $this->updateOuterWrapperSettingsForm($elements);
    $this->updateWrapperSettingsForm($elements, TRUE);
    $this->updateClassSettingsForm($elements);
    $this->updateAttributeSettingsForm($elements);
    $elements['settings'] = [
      '#type' => 'details',
      '#title' => $this->t('QR code generation settings'),
      '#tree' => TRUE,
    ];
    $elements['settings']['quiet_zone'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Quiet zone'),
      '#default_value' => $this->getSetting('settings')['quiet_zone'] ?? TRUE,
    ];

    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = parent::settingsSummary();
    $this->updateOuterWrapperSettingsSummary($summary);
    $this->updateWrapperSettingsSummary($summary);
    $this->updateClassSettingsSummary($summary);
    $this->updateAttributeSettingsSummary($summary);
    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    $qr = new QRCode();
    $quietZone = $this->getSetting('settings')['quiet_zone'] ?? TRUE;
    $options = [
      'connectPaths' => TRUE,
      'addQuietzone' => $quietZone,
    ];
    if ($quietZone) {
      $options['quietzoneSize'] = 2;
    }
    $options = new QROptions($options);
    $qr->setOptions($options);
    foreach ($items as $delta => $item) {
      if ($item instanceof LinkItemInterface) {
        $url = $item->getUrl();
        $url->setAbsolute();
        $elements[$delta] = [
          '#theme' => 'image',
          '#uri' => $qr->render($url->toString()),
          '#alt' => $url->toString(),
        ];
      }
    }
    $this->addElementClasses($items, $elements, ['#attributes']);
    $this->addElementAttributes($items, $elements, ['#attributes']);
    $this->wrapElements($items, $elements);

    return $this->outerWrapElements($items, $elements);
  }

}
