<?php

namespace Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook;

use Drupal\acquia_contenthub\AcquiaContentHubEvents;
use Drupal\acquia_contenthub\Event\HandleWebhookEvent;
use Drupal\acquia_contenthub_subscriber\EntityDeletionHandlerBase;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Deletes multiple assets based on a webhook v2.
 *
 * @package Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook
 */
class DeleteMultipleAssets extends EntityDeletionHandlerBase implements EventSubscriberInterface {

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

  /**
   * Handles webhook events.
   *
   * @param \Drupal\acquia_contenthub\Event\HandleWebhookEvent $event
   *   The HandleWebhookEvent object.
   *
   * @throws \Exception
   */
  public function onHandleWebhook(HandleWebhookEvent $event): void {
    $payload = $event->getPayload();
    $assets = $payload['assets'] ?? [];
    $client = $event->getClient();
    $settings = $client->getSettings();

    if (!$event->isWebhookV2() || !$this->isValidRequestPayload($payload)) {
      return;
    }

    $entity_uuids = [];
    $entity_uuids_to_cleanup = [];
    foreach ($assets as $asset) {
      if ($this->shouldSkipAsset($asset, $settings->getUuid())) {
        continue;
      }
      $entity_uuids[] = $asset['uuid'];
    }

    $this->processMultipleEntityDeletions($entity_uuids, $entity_uuids_to_cleanup);
    $this->cleanupMissingEntities($entity_uuids_to_cleanup, $client);
  }

  /**
   * Checks if asset needs to be skipped.
   *
   * @param array $asset
   *   Payload asset.
   * @param string $client_uuid
   *   Client uuid.
   *
   * @return bool
   *   True if asset to be skipped otherwise False.
   */
  protected function shouldSkipAsset(array $asset, string $client_uuid): bool {
    return (empty($asset['origin']) || $asset['origin'] === $client_uuid ||
      !$this->isSupportedType($asset['type']));
  }

  /**
   * Validates request payload.
   *
   * A valid payload should be successful, an event about deletion, and cannot
   * come from the same origin.
   *
   * @param array $payload
   *   The payload to validate.
   *
   * @return bool
   *   True if the payload is applicable.
   */
  protected function isValidRequestPayload(array $payload): bool {
    $assets = $payload['assets'] ?? [];
    if (!isset($payload['status'], $payload['crud'])) {
      return FALSE;
    }
    return 'successful' === $payload['status'] &&
      'delete' === $payload['crud'] &&
      !empty($assets);
  }

}
