<?php

namespace Drupal\pagedesigner_duplication\Service;

use Drupal\Core\Entity\ContentEntityBase;
use Drupal\pagedesigner\PagedesignerServiceInterface;
use Drupal\pagedesigner\Service\StateChanger;

/**
 * Service for duplicating pagedesigner content.
 */
class DuplicationService {

  /**
   * Create a new instance.
   *
   * @param \Drupal\pagedesigner\PagedesignerServiceInterface $pagedesignerService
   *   The pagedesigner service.
   * @param \Drupal\pagedesigner\Service\StateChanger $statechanger
   *   The state changer.
   */
  public function __construct(
    protected PagedesignerServiceInterface $pagedesignerService,
    protected StateChanger $statechanger,
  ) {

  }

  /**
   * Clone the element tree.
   *
   * Clone the elements from on entity to another entity.
   * Only matching pagedesigner fields are taken into account.
   *
   * @param \Drupal\Core\Entity\ContentEntityBase $source
   *   The source entity.
   * @param \Drupal\Core\Entity\ContentEntityBase $target
   *   The target entity.
   */
  public function duplicate(ContentEntityBase $source, ContentEntityBase $target) {
    $sourceFields = $this->pagedesignerService->getPagedesignerFields($source);
    $targetFields = $this->pagedesignerService->getPagedesignerFields($target);
    foreach ($sourceFields as $field) {
      if (!empty($targetFields[$field->getName()])) {
        $sourceContainer = $this->pagedesignerService->getContainer($source, $field->getName());
        $targetContainer = $this->pagedesignerService->getContainer($target, $field->getName());

        // Make sure that target entity is set.
        $targetContainer->entity->entity = $target;

        foreach ($sourceContainer->children as $item) {
          $clone = $this->statechanger->copy($item->entity, $targetContainer)->getOutput();
          $clone->parent->entity = $targetContainer;
          $clone->langcode->value = $target->langcode->value;
          $clone->save();
          $targetContainer->children->appendItem($clone);
        }
        $targetContainer->save();
      }
    }
  }

}
