<?php

namespace Drupal\pagedesigner_layout\Plugin\pagedesigner\Handler;

use Drupal\pagedesigner\Entity\Element;
use Drupal\pagedesigner\Plugin\FieldHandlerBase;
use Drupal\pagedesigner\Plugin\HandlerUserTrait;
use Drupal\ui_patterns\Definition\PatternDefinition;

/**
 * Process entities of type "layout".
 *
 * @PagedesignerHandler(
 *   id = "layout",
 *   name = @Translation("Layout handler"),
 *   types = {
 *      "layout"
 *   },
 * )
 */
class Layout extends FieldHandlerBase {

  use HandlerUserTrait;

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

  /**
   * {@inheritdoc}
   */
  public function collectAttachments(array &$attachments) {
    if ($this->currentUser->hasPermission('restful get pagedesigner_layout')) {
      $attachments['library'][] = 'pagedesigner_layout/insert';
    }
    if ($this->currentUser->hasPermission('restful post pagedesigner_layout')) {
      $attachments['library'][] = 'pagedesigner_layout/add';
    }
    if ($this->currentUser->hasPermission('restful delete pagedesigner_layout')) {
      $attachments['library'][] = 'pagedesigner_layout/delete';
    }
  }

  /**
   * {@inheritdoc}
   *
   * Add valid layouts as patterns.
   */
  public function collectPatterns(array &$patterns, bool $render_markup = FALSE) {
    if ($this->currentUser->hasPermission('restful get pagedesigner_layout')) {
      // Get available layouts.
      $query = $this->entityTypeManager->getStorage('pagedesigner_element')
        ->getQuery()
        ->accessCheck(FALSE)
        ->condition('type', 'layout');

      // Simulate COALESCE with OR condition.
      $deleted_condition = $query->orConditionGroup()
        ->condition('deleted', NULL, 'IS NULL')
        ->condition('deleted', 0);
      $query->condition($deleted_condition);

      $ids = $query->execute();
      $definitions = $this->patternManager->getDefinitions();
      foreach ($ids as $id) {
        $layout = $this->entityTypeManager->getStorage('pagedesigner_element')->load($id);
        if ($layout != NULL) {
          // The first child of a layout is the root element to process.
          $root = $layout->children->entity;
          $validDefinition = FALSE;
          if (!empty($root)) {
            // If no field_pattern, it must be a configuration based element
            // e.g. webform, block.
            if (!$root->hasField('field_pattern')) {
              $validDefinition = TRUE;
            }
            // If field_pattern is available, check if we have a definition and
            // whether the definition is available in the current theme.
            elseif (!empty($definitions[$root->field_pattern->value])) {
              $validDefinition = TRUE;
            }
          }
          // If the definition is valid, add it to the patterns array.
          if ($validDefinition) {
            $definition = $this->definition;
            $definition['id'] .= $id;
            $definition['layout'] = $id;
            $definition['markup'] = '<div></div>';
            $definition['root'] = $root->id();
            $definition['label'] = $layout->name->value;
            if ($root->hasField('field_pattern')) {
              $definition['provider'] = $definitions[$root->field_pattern->value]->getProvider();
            }
            $patterns[$definition['id']] = new PatternDefinition($definition);
          }
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function view(Element $entity, string $view_mode, array &$build = []) {
  }

  /**
   * {@inheritdoc}
   */
  public function build(Element $entity, string $view_mode, array &$build = []) {
  }

  /**
   * {@inheritdoc}
   */
  public function delete(Element $entity, bool $remove = FALSE) {
    if ($remove) {
      $entity->delete();
    }
    else {
      $entity->deleted->value = TRUE;
      $entity->save();
    }
  }

}
