<?php

namespace Drupal\acquia_contenthub_publisher;

use Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface;
use Drupal\acquia_contenthub\Exception\ContentHubClientException;
use Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\depcalc\Cache\DepcalcCacheBackend;
use Psr\Log\LoggerInterface;

/**
 * Trait to add entities to export queue.
 *
 * @package Drupal\acquia_contenthub_publisher
 */
trait AddToChExportQueueTrait {

  /**
   * CH configurations.
   *
   * @var \Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface
   */
  protected ContentHubConfigurationInterface $achConfigurations;

  /**
   * Content Hub entity enqueuer.
   *
   * @var \Drupal\acquia_contenthub_publisher\ContentHubEntityEnqueuer
   */
  protected ContentHubEntityEnqueuer $entityEnqueuer;

  /**
   * Logger Channel.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected LoggerInterface $logger;

  /**
   * The Depcalc Cache backend.
   *
   * @var \Drupal\depcalc\Cache\DepcalcCacheBackend
   */
  protected DepcalcCacheBackend $depcalcCache;

  /**
   * The Entity Tracker.
   *
   * @var \Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface
   */
  protected AcquiaContentHubEntityTrackerInterface $entityTracker;

  /**
   * Enqueues entities to export queue.
   *
   * @param \Drupal\Core\Entity\EntityInterface ...$entities
   *   Entities.
   *
   * @return array|null
   *   List of ineligible entity uuids.
   */
  public function enqueueEntities(EntityInterface ...$entities): ?array {
    if (!$this->achConfigurations->isConfigurationSet()) {
      return NULL;
    }

    $interest_list_entities = [];
    $in_eligible_entities = [];
    $entities_data_to_queue = [];
    foreach ($entities as $entity) {
      if (!$entity instanceof EntityInterface) {
        continue;
      }
      $event = $this->entityEnqueuer->dispatchChEntityEligibilityEvent($entity, 'update');
      if (!$event->getEligibility()) {
        $reason = $event->getReason();
        $this->logger->info('Cannot add ineligible entity to export queue. Entity (UUID: {uuid}, Entity type: {entity_type}). Reason: {reason}', [
          'uuid' => $entity->uuid(),
          'entity_type' => $entity->getEntityTypeId(),
          'reason' => $reason,
        ]);
        $in_eligible_entities[] = $entity->uuid();
        continue;
      }

      $this->logger->info(
        'Attempting to add Entity with (UUID: {uuid}, Entity type: {entity_type}) to the export queue and to the tracking table.',
        [
          'uuid' => $entity->uuid(),
          'entity_type' => $entity->getEntityTypeId(),
        ]
      );
      $entities_data_to_queue[$entity->uuid()] = [
        'entity' => $entity,
        'hash' => '',
        'queue_id' => $this->entityEnqueuer->addItemsToExportQueue($entity, $event),
      ];
      $interest_list_entities[$entity->uuid()] = $entity->getEntityTypeId() . ' : ' . $entity->uuid();
    }
    if (!empty($entities_data_to_queue)) {
      $this->entityTracker->queueMultiple($entities_data_to_queue);
    }

    if (!empty($interest_list_entities)) {
      try {
        $this->entityEnqueuer->sendUpdatesToInterestList($interest_list_entities);
      }
      catch (ContentHubClientException $e) {
        $this->logger->error("Enqueuing: Could not add the following entities to the site's interest list: {entities}",
          ['entities' => implode(', ', $interest_list_entities)]
        );
      }
    }

    return $in_eligible_entities;
  }

  /**
   * Clears depcalc cache and nullifies hashes.
   */
  public function clearCacheAndNullifyHashes(): void {
    $this->depcalcCache->deleteAllPermanent();
    $this->entityTracker->nullifyHashes();
  }

  /**
   * Adds status messages in messenger.
   *
   * @param array $selected
   *   Total selected entities.
   * @param array|null $in_eligible_entities
   *   Ineligible entities.
   */
  public function addStatusMessages(array $selected, ?array $in_eligible_entities): void {
    if ($in_eligible_entities === NULL) {
      $this->messenger->addError($this->t('Invalid CH configurations.'));
    }
    elseif (!empty($in_eligible_entities)) {
      $in_eligible_entities_count = count($in_eligible_entities);
      $enqueued_count = count($selected) - $in_eligible_entities_count;
      if ($enqueued_count > 0) {
        $this->messenger->addStatus($this->formatPlural(
          $enqueued_count,
          '@count entity enqueued.',
          '@count entities enqueued.',
        ));
      }
      $this->messenger->addWarning($this->formatPlural(
        $in_eligible_entities_count,
        '@count ineligible entity was skipped. <a href=":url">Know more</a>',
        '@count ineligible entities were skipped. <a href=":url">Know more</a>',
        [':url' => 'https://docs.acquia.com/acquia-cms/add-ons/content-hub/manage/developing/eligibile-and-ineligible-entities']
      ));
    }
    else {
      $this->messenger->addStatus($this->formatPlural(
        count($selected),
        '@count entity enqueued.',
        '@count entities enqueued.',
      ));
    }
  }

}
