<?php

namespace Drupal\pagedesigner\Plugin\pagedesigner\Handler;

use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\pagedesigner\Entity\Element;
use Drupal\pagedesigner\Plugin\FieldHandlerBase;

/**
 * Process entities of type "cell".
 *
 * @PagedesignerHandler(
 *   id = "cell",
 *   name = @Translation("Cell renderer"),
 *   types = {
 *     "cell",
 *   },
 * )
 */
class Cell extends FieldHandlerBase {

  /**
   * {@inheritdoc}
   */
  public function view(Element $entity, string $view_mode, array &$build = []) {
    foreach ($entity->children as $delta => $item) {
      if ($item->entity != NULL) {
        $build[$delta] = $this->viewBuilder->view($item->entity, $view_mode) + ['#weight' => $delta];
      }
    }
    $build['#sorted'] = TRUE;
  }

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

  /**
   * {@inheritdoc}
   */
  public function getContent(Element $entity, array &$list = [], $published = TRUE) {
    foreach ($entity->children as $item) {
      if ($item->entity != NULL) {
        $child = ($published) ? $item->entity->loadNewestPublished() : $item->entity;
        if ($child != NULL) {
          $this->elementHandler->getContent($child, $list, $published);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function serialize(Element $entity, array &$result = []) {
    $data = [];
    foreach ($entity->children as $item) {
      if ($item->entity != NULL) {
        $data[] = $item->entity->id();
      }
    }
    $result = $data + $result;
  }

  /**
   * {@inheritdoc}
   */
  public function patch(Element $entity, array $data) {
    if (isset($data['order'])) {
      $storageManager = $this->entityTypeManager->getStorage('pagedesigner_element');
      $entity->children->setValue([]);
      foreach ($data['order'] as $target_id) {
        /** @var \Drupal\pagedesigner\Entity\Element $child */
        $child = $storageManager->load($target_id);
        if ($child) {
          $entity->children->appendItem($child);
          $child->parent->entity = $entity;
          $child->saveEdit();
        }
      }
      $entity->saveEdit();

      if (!empty($data['order'])) {
        /** @var \Drupal\pagedesigner\Entity\Element[] $parents */
        $parents = $storageManager->loadByProperties(['children' => $data['order']]);
        foreach ($parents as $parent) {
          if (!empty($parent) && $parent->id() != $entity->id()) {
            $parent->get('children')->filter(function (EntityReferenceItem $entry) use ($data) {
              return !empty($entry->entity) && !in_array($entry->entity->id(), $data['order']);
            });
            $parent->saveEdit();
          }
        }
      }
    }
  }

}
