<?php

namespace Drupal\acquia_contenthub\EventSubscriber\PreEntitySave;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Event\PreEntitySaveEvent;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Loads the path field for content entities.
 *
 * As we are not serializing path field as path_alias entity is syndicated
 * separately. This event subscriber would load the latest path_alias entity
 * and set the value of alias to the respective node, taxonomy_term and media
 * entity. Currently path field is set to computed inside drupal core and is
 * associated with taxonomy_term, node and media entities.
 *
 * @package Drupal\acquia_contenthub\EventSubscriber\PreEntitySave
 */
class LoadPathField implements EventSubscriberInterface {

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected ModuleHandlerInterface $moduleHandler;

  /**
   * LoadPathField constructor.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $handler
   *   The module handler.
   */
  public function __construct(ModuleHandlerInterface $handler) {
    $this->moduleHandler = $handler;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    $events[AcquiaContentHubEvents::PRE_ENTITY_SAVE] = 'onPreEntitySave';
    return $events;
  }

  /**
   * Loads the path field for content entities.
   *
   * @param \Drupal\acquia_contenthub\Event\PreEntitySaveEvent $event
   *   The pre entity save event.
   */
  public function onPreEntitySave(PreEntitySaveEvent $event): void {
    $entity = $event->getEntity();
    if (!$entity instanceof ContentEntityInterface ||
      $entity->isNew() ||
      !$entity->hasField('path') ||
      !$this->moduleHandler->moduleExists('path_alias')
    ) {
      return;
    }
    $translations = array_keys($entity->getTranslationLanguages());
    foreach ($translations as $entity_language) {
      $translated_entity = $entity->getTranslation($entity_language);
      $path_field = $translated_entity->get('path')->getValue();
      $language = $path_field[0]['langcode'] ?? '';
      $path_entity_id = $path_field[0]['pid'] ?? '';
      if (empty($path_entity_id) || empty($language)) {
        continue;
      }
      $path_entity = $this->getEntityTypeManager()->getStorage('path_alias')->load($path_entity_id);
      if (empty($path_entity)) {
        return;
      }
      $alias = $path_entity->getTranslation($language)->getAlias();
      $path_field[0]['alias'] = $alias;
      $translated_entity->set('path', $path_field);
    }
  }

  /**
   * Returns uncached entity type manager.
   *
   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
   *   The entity type manager.
   */
  public function getEntityTypeManager(): EntityTypeManagerInterface {
    return \Drupal::entityTypeManager();
  }

}
