<?php

namespace Drupal\pagedesigner\Plugin\pagedesigner\Handler;

use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Site\Settings;
use Drupal\pagedesigner\Entity\Element;
use Drupal\pagedesigner\Plugin\PlainFieldHandlerBase;
use Drupal\ui_patterns\Definition\PatternDefinitionField;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Process entities of type "autocomplete".
 *
 * @PagedesignerHandler(
 *   id = "autocomplete",
 *   name = @Translation("Autocomplete processor"),
 *   types = {
 *      "autocomplete",
 *   }
 * )
 */
class Autocomplete extends PlainFieldHandlerBase {

  /**
   * The key value store.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueFactory
   */
  protected $keyValueFactory = NULL;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $instance->setKeyValueFactory($container->get('keyvalue'));
    return $instance;
  }

  /**
   * Set the key value factory.
   *
   * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
   *   The key value factory.
   */
  public function setKeyValueFactory(KeyValueFactoryInterface $key_value_factory) {
    $this->keyValueFactory = $key_value_factory;
  }

  /**
   * {@inheritDoc}
   */
  public function prepare(PatternDefinitionField &$field, &$fieldArray) {
    if ($field->getType() !== 'autocomplete') {
      return;
    }
    if (!isset($fieldArray['additional'])) {
      $fieldArray['additional'] = [];
    }
    parent::prepare($field, $fieldArray);
    $additionalDefinition = $field->getAdditional();
    if (!empty($additionalDefinition['autocomplete']['entity_type'])) {
      $selection_settings = [
        'target_bundles' => ($additionalDefinition['autocomplete']['bundles']) ?: NULL,
        'sort' => ['field' => "_none", 'direction' => 'ASC'],
        'auto_create' => FALSE,
        'auto_create_bundle' => '',
        'match_operator' => 'CONTAINS',
        'match_limit' => 10,
      ];
      $entityType = $additionalDefinition['autocomplete']['entity_type'];
      $data = serialize($selection_settings) . $entityType . 'default:' . $entityType;
      $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());
      $key_value_storage = $this->keyValueFactory->get('entity_autocomplete');
      if (!$key_value_storage->has($selection_settings_key)) {
        $key_value_storage->set($selection_settings_key, $selection_settings);
      }
      $url = '/entity_reference_autocomplete/' . $entityType . '/default:' . $entityType . '/' . $selection_settings_key;
      $fieldArray['additional'] += ['autocomplete_href' => $url];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function patch(Element $entity, array $data) {
    if (!empty($data) && is_array($data)) {
      $entity->field_content->value = Json::encode($data);
    }
    else {
      $entity->field_content->value = '';
    }
    $entity->saveEdit();
  }

  /**
   * {@inheritdoc}
   */
  public function serialize(Element $entity, array &$result = []) {
    $value = $this->elementHandler->get($entity);
    if (!empty($value)) {
      $result = Json::decode($value) + $result;
    }
  }

  /**
   * {@inheritDoc}
   */
  public function generate($definition, array $data, &$entity = NULL) {
    parent::generate(['type' => 'content', 'name' => 'autocomplete'], $data, $entity);
  }

}
