<?php

namespace Drupal\acquia_contenthub_publisher\Controller;

use Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface;
use Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface;
use Drupal\acquia_contenthub_publisher\AddToChExportQueueTrait;
use Drupal\acquia_contenthub_publisher\ContentHubEntityEnqueuer;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Controller\ControllerBase;
use Drupal\depcalc\Cache\DepcalcCacheBackend;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Controller for ContentHub Export Queue.
 */
class ContentHubExportQueueController extends ControllerBase {

  use AddToChExportQueueTrait;

  /**
   * The ContentHubExportQueueController constructor.
   *
   * @param \Drupal\acquia_contenthub_publisher\ContentHubEntityEnqueuer $entity_enqueuer
   *   Entity enqueuer.
   * @param \Drupal\acquia_contenthub\Settings\ContentHubConfigurationInterface $ach_configurations
   *   CH configurations.
   * @param \Psr\Log\LoggerInterface $logger_channel
   *   Logger channel.
   * @param \Drupal\depcalc\Cache\DepcalcCacheBackend $depcalc_cache
   *   Depcalc cache backend.
   * @param \Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface $entity_tracker
   *   Entity tracker.
   */
  public function __construct(ContentHubEntityEnqueuer $entity_enqueuer, ContentHubConfigurationInterface $ach_configurations, LoggerInterface $logger_channel, DepcalcCacheBackend $depcalc_cache, AcquiaContentHubEntityTrackerInterface $entity_tracker) {
    $this->entityEnqueuer = $entity_enqueuer;
    $this->achConfigurations = $ach_configurations;
    $this->logger = $logger_channel;
    $this->depcalcCache = $depcalc_cache;
    $this->entityTracker = $entity_tracker;
    $this->messenger = $this->messenger();
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('acquia_contenthub_publisher.entity_enqueuer'),
      $container->get('acquia_contenthub.configuration'),
      $container->get('acquia_contenthub.logger_channel'),
      $container->get('cache.depcalc'),
      $container->get('acquia_contenthub_publisher.tracker'),
    );
  }

  /**
   * Adds entity to the export queue.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   A Symfony request object.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   The redirect response.
   */
  public function addEntity(Request $request): RedirectResponse {
    $referer_url = $request->headers->get('referer');

    $entity_type = $request->get('entity_type');
    $entity_uuid = $request->get('entity_uuid');

    if (empty($entity_type) || !Uuid::isValid($entity_uuid)) {
      $this->messenger()->addError($this->t('Invalid entity type or entity uuid.'));
      return new RedirectResponse($referer_url);
    }

    $entity = $this->getEntity($entity_type, $entity_uuid);
    if (!$entity) {
      $this->messenger()->addError($this->t('Cannot retrieve entity.'));
      return new RedirectResponse($referer_url);
    }

    $item_id = $this->entityTracker->getQueueId($entity_uuid);
    if ($item_id) {
      $this->messenger()->addWarning($this->t('Entity already enqueued.'));
      return new RedirectResponse($referer_url);
    }

    $this->clearCacheAndNullifyHashes();
    $in_eligible_entities = $this->enqueueEntities($entity);
    $this->addStatusMessages([$entity], $in_eligible_entities);

    return new RedirectResponse($referer_url);
  }

  /**
   * Retrieves entity using entity uuid.
   *
   * @param string $entity_type
   *   Entity type.
   * @param string $entity_uuid
   *   Entity uuid.
   *
   * @return \Drupal\Core\Entity\EntityInterface|bool
   *   False if entity not found.
   */
  protected function getEntity(string $entity_type, string $entity_uuid) {
    $storage = $this->entityTypeManager()->getStorage($entity_type);
    $entity = $storage->loadByProperties(['uuid' => $entity_uuid]);
    return reset($entity);
  }

}
