<?php

namespace Drupal\pagedesigner_webform\Plugin\pagedesigner\Handler;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\LanguageInterface;
use Drupal\pagedesigner\ElementViewBuilder;
use Drupal\pagedesigner\Entity\Element;
use Drupal\pagedesigner\Plugin\HandlerCacheTrait;
use Drupal\pagedesigner\Plugin\HandlerPluginBase;
use Drupal\ui_patterns\Definition\PatternDefinition;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * Process entities of type "webform".
 *
 * @PagedesignerHandler(
 *   id = "webform",
 *   name = @Translation("Webform handler"),
 *   types = {
 *      "webform",
 *      "form"
 *   },
 * )
 */
class Webform extends HandlerPluginBase {

  use HandlerCacheTrait;

  /**
   * The definition of the webform pattern.
   *
   * @var array
   */
  protected $definition = [
    "id" => 'webform:',
    "pagedesigner" => 1,
    "icon" => "far fa-edit",
    "type" => "webform",
    "category" => 'Forms',
    "label" => '',
    "description" => '',
  ];

  /**
   * {@inheritdoc}
   */
  public function collectAttachments(array &$attachments) {
    $attachments['library'][] = 'pagedesigner_webform/pagedesigner';
  }

  /**
   * {@inheritdoc}
   *
   * Create patterns from webforms.
   */
  public function collectPatterns(array &$patterns, bool $render_markup = FALSE) {
    $formIds = $this->entityTypeManager->getStorage('webform')->getQuery()
      ->accessCheck(FALSE)
      ->execute();
    $cache_bin = $this->cacheFactory->get('discovery');
    $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE)->getId();
    foreach ($formIds as $formId) {
      if (!str_starts_with($formId, 'example_') && !str_starts_with($formId, 'template_')) {
        $definition = $this->definition;
        $id = $definition['id'] . $formId;
        // Get cached definition if available.
        $cid = $this->createCid('webform', $formId, $langcode, $render_markup);
        if ($item = $cache_bin->get($cid)) {
          $patterns[$id] = new PatternDefinition($item->data);
        }
        else {
          // Pattern definition not yet cached.
          /** @var \Drupal\webform\Entity\Webform $form */
          $form = $this->entityTypeManager->getStorage('webform')->load($formId);
          if ($form != NULL) {
            $definition['webform'] = $formId;
            $definition['markup'] = '<div data-gjs-type="webform">' . $form->label() . '<div>';
            $definition['remote_load'] = TRUE;
            $definition['label'] = (string) $form->label();
            $patterns[$id] = new PatternDefinition($definition);
            // Cache definition for reuse.
            $cache_bin->set($cid, $definition, Cache::PERMANENT, $form->getCacheTags());
          }
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function get(Element $entity, string &$result = '') {
  }

  /**
   * {@inheritdoc}
   */
  public function serialize(Element $entity, array &$result = []) {
    $result['webform_id'] = $entity->field_webform->target_id;
  }

  /**
   * {@inheritdoc}
   */
  public function view(Element $entity, string $view_mode, array &$build = []) {
    if ($entity->field_webform->entity == NULL) {
      return;
    }
    $this->viewBuilder->addLazyBuilder($entity, $view_mode, $build);
  }

  /**
   * {@inheritdoc}
   */
  public function build(Element $entity, string $view_mode, array &$build = []) {
    $sub_build = $this->entityTypeManager
      ->getViewBuilder('webform')
      ->view($entity->field_webform->entity);
    if ($view_mode == ElementViewBuilder::RENDER_MODE_EDIT) {
      $sub_build['#prefix'] = '<div data-gjs-type="webform:' . $entity->field_webform->target_id . '" data-entity-id="' . $entity->id() . '" id="pd-cp-' . $entity->id() . '">';
      $sub_build['#suffix'] = '</div>';
    }
    $build = [
      'pagedesigner_webform' => $build = $sub_build + $build,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function describe(Element $entity, array &$result = []) {
    parent::describe($entity, $result);
    $result['type'] = 'webform';
  }

  /**
   * {@inheritdoc}
   */
  public function generate($definition, array $data, Element &$entity = NULL) {
    $formId = $definition['additional']['webform'];
    $form = $this->entityTypeManager->getStorage('webform')->load($formId);
    if ($form == NULL) {
      throw new BadRequestHttpException('The given form does not exist.');
    }
    parent::generate(['type' => 'webform', 'name' => 'webform'], $data, $entity);
    $entity->field_webform->entity = $form;
    $entity->saveEdit();

    // Adding entity to parent cell if provided.
    $cell = $entity->parent->entity;
    if ($cell != NULL) {
      $cell = $cell->getTranslation($entity->langcode->value);
      $cell->children->appendItem($entity);
      $cell->saveEdit();
    }
  }

}
