<?php

namespace Drupal\pagedesigner\Plugin\pagedesigner;

use Drupal\pagedesigner\Entity\Element;
use Drupal\ui_patterns\Definition\PatternDefinitionField;

/**
 * Povides the interface for defining handlers of pagedesigner elements.
 */
interface HandlerPluginInterface {

  /**
   * Collect attachments needed for editing inside the pagedesigner.
   *
   * @param array $attachments
   *   The list of attachments.
   */
  public function collectAttachments(array &$attachments);

  /**
   * Allows to alter the list of patterns generated by the ui_pattern module.
   *
   * @param \Drupal\ui_patterns\Definition\PatternDefinition[] $patterns
   *   The list of patterns.
   * @param bool $render_markup
   *   Whether the patterns should provide pagedesigner editor markup.
   */
  public function collectPatterns(array &$patterns, bool $render_markup = FALSE);

  /**
   * Allows to alter the pattern definitons sent to the frontend.
   *
   * @param array $patterns
   *   The list of patterns.
   */
  public function adaptPatterns(array &$patterns);

  /**
   * Processes a pattern field.
   *
   * @param \Drupal\ui_patterns\Definition\PatternDefinitionField $field
   *   The field definition.
   * @param array $fieldArray
   *   The field description to be sent to the frontend.
   */
  public function prepare(PatternDefinitionField &$field, array &$fieldArray);

  /**
   * Get a textual representation of the entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to process.
   * @param string $result
   *   The resulting text representation (inout).
   *
   * @return string
   *   The resulting text representation. Void if inout parameter is used.
   */
  public function get(Element $entity, string &$result = '');

  /**
   * Get a textual representation of the tree starting at entity.
   *
   * Each entity's textual representation will be in the array.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to process.
   * @param array $list
   *   The resulting text representation (inout).
   * @param bool $published
   *   Whether to return the published content, or edit version.
   *
   * @return array
   *   The resulting text representation. Void if inout parameter is used.
   */
  public function getContent(Element $entity, array &$list = [], $published = TRUE);

  /**
   * Serialize the content of an entity for edit mode.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to process.
   * @param array $result
   *   The resulting serialized representation (inout).
   *
   * @return array|void
   *   The resulting serialized representation. Void if inout parameter is used.
   */
  public function serialize(Element $entity, array &$result = []);

  /**
   * Describe the structure of an entity for edit mode.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to process.
   * @param array $result
   *   The resulting serialized representation (inout).
   *
   * @return array|void
   *   The resulting serialized representation. Void if inout parameter is used.
   */
  public function describe(Element $entity, array &$result = []);

  /**
   * Generate a new entity.
   *
   * @param \Drupal\ui_patterns\Definition\PatternDefinition|array $definition
   *   The definition of the new entity.
   * @param array $data
   *   The data to create the entity with.
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The created entity (inout).
   *
   * @return \Drupal\pagedesigner\Entity\Element
   *   The created entity. Void if inout parameter is used.
   */
  public function generate($definition, array $data, ?Element &$entity = NULL);

  /**
   * Update the entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to update.
   * @param array $data
   *   The data to update the entity with.
   */
  public function patch(Element $entity, array $data);

  /**
   * Copy an entity and return the cloned entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to copy.
   * @param \Drupal\pagedesigner\Entity\Element $container
   *   The container for the cloned entity.
   * @param \Drupal\pagedesigner\Entity\Element $clone
   *   The clone of the entity (inout).
   *
   * @return \Drupal\pagedesigner\Entity\Element|void
   *   The clone of the entity. Void if inout parameter is used.
   */
  public function copy(Element $entity, ?Element $container = NULL, ?Element &$clone = NULL);

  /**
   * Delete an entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to delete.
   * @param bool $remove
   *   Whether to delete the information from the database.
   */
  public function delete(Element $entity, bool $remove = FALSE);

  /**
   * Restore an entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to restore.
   */
  public function restore(Element $entity);

  /**
   * Builds the render array for the provided entity.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to render.
   * @param string $view_mode
   *   The view mode that should be used to render the entity.
   * @param array $build
   *   The render array (inout).
   *
   * @return array
   *   A render array for the entity.
   */
  public function view(Element $entity, string $view_mode, array &$build = []);

  /**
   * Builds the render array for the provided entity.
   *
   * This is called if the HandlerPluginInterface::view registers a
   * #pre_render or #lazy_builder hook.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to render.
   * @param string $view_mode
   *   The view mode that should be used to render the entity.
   * @param array $build
   *   The render array (inout).
   *
   * @return array
   *   A render array for the entity.
   */
  public function build(Element $entity, string $view_mode, array &$build = []);

  /**
   * Publish the entity and all referenced elements.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to publish.
   */
  public function publish(Element $entity);

  /**
   * Unpublish the entity and all referenced elements.
   *
   * @param \Drupal\pagedesigner\Entity\Element $entity
   *   The entity to unpublish.
   */
  public function unpublish(Element $entity);

}
