<?php

namespace Drupal\acquia_contenthub_subscriber\EventSubscriber\UnserializeContentEntityField;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Event\UnserializeCdfEntityFieldEvent;
use Drupal\acquia_contenthub_subscriber\Libs\UserSyndicationSettingsInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Replaces author with the configured proxy user if conditions are met.
 */
class ReplaceAuthorWithProxyUser implements EventSubscriberInterface {

  /**
   * The user syndication settings.
   *
   * @var \Drupal\acquia_contenthub_subscriber\Libs\UserSyndicationSettingsInterface
   */
  private UserSyndicationSettingsInterface $userSettings;

  /**
   * Constructs this object.
   *
   * @param \Drupal\acquia_contenthub_subscriber\Libs\UserSyndicationSettingsInterface $user_settings
   *   The user syndication settings.
   */
  public function __construct(UserSyndicationSettingsInterface $user_settings) {
    $this->userSettings = $user_settings;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    return [
      AcquiaContentHubEvents::UNSERIALIZE_CONTENT_ENTITY_FIELD => [
        'onUnserializeContentEntityField', 1000,
      ],
    ];
  }

  /**
   * Replaces incoming content's author to configured proxy user.
   *
   * @param \Drupal\acquia_contenthub\Event\UnserializeCdfEntityFieldEvent $event
   *   The unserialize field event.
   */
  public function onUnserializeContentEntityField(UnserializeCdfEntityFieldEvent $event): void {
    $uid_field = (string) $event->getEntityType()->getKey('owner');
    $current_field_name = $event->getFieldName();
    if ($this->shouldSkip($current_field_name, $uid_field)) {
      return;
    }
    $proxy = $this->userSettings->getProxyUser();
    $values = [];
    $field = $event->getField();
    if (!empty($field['value'])) {
      foreach (array_keys($field['value']) as $langcode) {
        $values[$langcode][$event->getFieldName()] = $proxy->id();
      }
      $event->setValue($values);
    }
    $event->stopPropagation();
  }

  /**
   * Checks if the field is user reference field.
   *
   * Uid in particular. Also checks if user syndication is disabled and proxy
   * user is configured.
   *
   * @param string $field_name
   *   The field name to check.
   * @param string $uid_field
   *   The name of the field where user id is stored.
   *
   * @return bool
   *   True if the field should be skipped.
   */
  protected function shouldSkip(string $field_name, string $uid_field): bool {
    return $field_name !== $uid_field ||
      !$this->userSettings->isUserSyndicationDisabled() ||
      is_null($this->userSettings->getProxyUser());
  }

}
