<?php

namespace Drupal\acquia_contenthub_subscriber\Commands;

use Acquia\ContentHubClient\ContentHubClient;
use Drupal\acquia_contenthub\Client\ClientFactory;
use Drupal\acquia_contenthub\Exception\ContentHubClientException;
use Drupal\acquia_contenthub\Exception\ContentHubException;
use Drupal\acquia_contenthub\Libs\Traits\ResponseCheckerTrait;
use Drupal\acquia_contenthub_subscriber\Libs\InterestList\InterestListHandler;
use Drupal\Component\Uuid\Uuid;
use Drush\Commands\DrushCommands;

/**
 * Drush command for Acquia ContentHub Subscriber syndication functionality.
 */
class AcquiaContentHubSubscriberSyndicationCommands extends DrushCommands {

  use ResponseCheckerTrait;

  /**
   * Content Hub Client.
   *
   * @var \Acquia\ContentHubClient\ContentHubClient|bool
   */
  protected $client;

  /**
   * Interest list handler.
   *
   * @var \Drupal\acquia_contenthub_subscriber\Libs\InterestList\InterestListHandler
   */
  protected InterestListHandler $interestListHandler;

  /**
   * AcquiaContentHubSubscriberSyndicationCommands constructor.
   *
   * @param \Drupal\acquia_contenthub\Client\ClientFactory $factory
   *   Client Factory.
   * @param \Drupal\acquia_contenthub_subscriber\Libs\InterestList\InterestListHandler $interest_list_handler
   *   Interest list handler.
   */
  public function __construct(ClientFactory $factory, InterestListHandler $interest_list_handler) {
    $this->client = $factory->getClient();
    $this->interestListHandler = $interest_list_handler;
  }

  /**
   * Enables syndication for the list entities.
   *
   * @option uuids
   *   Comma-separated list of entity uuids.
   * @default uuids
   *
   * @command acquia:contenthub:enable-syndication
   * @aliases ach-es
   *
   * @usage drush acquia:contenthub:enable-syndication --uuids="1fff24a4-2a71-4e39-b2a2-80a6251eed36,3aaa24a4-2a71-4e39-b2a2-20b6251ffe47"
   *   Enables syndication for given entities.
   *
   * @throws \Exception
   */
  public function enableSyndication(): void {
    $webhook_uuid = $this->getWebhookUuid();
    $uuids = $this->getUuidsFromOption();

    try {
      $this->updateInterestList($uuids, $webhook_uuid, FALSE);
    }
    catch (\Exception $e) {
      $this->io()->error(
        sprintf('Could not enable syndication for the given uuids. Reason: %s',
          $e->getMessage()
        )
      );
    }
  }

  /**
   * Disables syndication for the list entities.
   *
   * @option uuids
   *   Comma-separated list of entity uuids.
   * @default uuids
   *
   * @command acquia:contenthub:disable-syndication
   * @aliases ach-ds
   *
   * @usage drush acquia:contenthub:disable-syndication --uuids="1fff24a4-2a71-4e39-b2a2-80a6251eed36,3aaa24a4-2a71-4e39-b2a2-20b6251ffe47"
   *   Disables syndication for given entities.
   *
   * @throws \Exception
   */
  public function disableSyndication(): void {
    $webhook_uuid = $this->getWebhookUuid();
    $uuids = $this->getUuidsFromOption();

    try {
      $this->updateInterestList($uuids, $webhook_uuid, TRUE);
    }
    catch (\Exception $e) {
      $this->io()->error(
        sprintf('Could not disable syndication for the given uuids. Reason: %s',
          $e->getMessage()
        )
      );
    }
  }

  /**
   * Provides webhook uuid.
   *
   * @return string
   *   Webhook uuid.
   *
   * @throws \Drupal\acquia_contenthub\Exception\ContentHubClientException
   * @throws \Drupal\acquia_contenthub\Exception\ContentHubException
   */
  protected function getWebhookUuid(): string {
    if (!$this->client instanceof ContentHubClient) {
      throw new ContentHubClientException('Error trying to connect to the Content Hub. Make sure this site is registered to Content hub.');
    }
    $settings = $this->client->getSettings();
    $webhook_uuid = $settings ? $settings->getWebhook('uuid') : '';
    if (!$webhook_uuid) {
      throw new ContentHubException('Webhook not available, unable to fetch interest list.');
    }
    return $webhook_uuid;
  }

  /**
   * Fetches uuids and validates them.
   *
   * @return array
   *   Array of Uuids.
   *
   * @throws \Exception
   */
  protected function getUuidsFromOption(): array {
    $uuids = $this->input->getOption('uuids');
    $uuids = explode(',', $uuids);
    foreach ($uuids as $uuid) {
      if (!Uuid::isValid($uuid)) {
        throw new \Exception(sprintf('Invalid uuid %s. Please enter valid uuids.', $uuid));
      }
    }
    return $uuids;
  }

  /**
   * Updates interest list.
   *
   * @param array $uuids
   *   List of uuids to be updated.
   * @param string $webhook_uuid
   *   Webhook uuid.
   * @param bool $disable_syndication
   *   Enable/disable syndication flag.
   */
  protected function updateInterestList(array $uuids, string $webhook_uuid, bool $disable_syndication): void {
    $resp = $this->interestListHandler->updateInterestList(
      $uuids,
      $webhook_uuid,
      $disable_syndication
    );
    if ($this->isSuccessful($resp)) {
      $success_message = sprintf(
        'All the entities (%s) that were set to %s syndication have been marked as %s for syndication in interest list.',
        implode(', ', $uuids),
        $disable_syndication ? 'disable' : 'enable',
        $disable_syndication ? 'disabled' : 'enabled'
      );
      $this->io()->info(
        sprintf(
          $success_message,
          implode(', ', $uuids)
        )
      );
    }
    else {
      $error_message = sprintf(
        'There was some error updating interest list for %s entities. Message: %s.',
        $disable_syndication ? 'disabling' : 'enabling',
        $resp->getBody()
      );
      $this->io()->error($error_message);
    }
  }

}
