<?php

namespace Drupal\acquia_contenthub_subscriber\Form;

use Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface;
use Drupal\acquia_contenthub\Client\ClientFactory;
use Drupal\acquia_contenthub\Libs\Common\EnsureContentHubClientTrait;
use Drupal\acquia_contenthub\Libs\Traits\ResponseCheckerTrait;
use Drupal\acquia_contenthub\Settings\ConnectionDetailsInterface;
use Drupal\acquia_contenthub_subscriber\ContentHubImportQueue;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Purge queue confirmation form.
 */
class ContentHubPurgeQueueConfirmForm extends ConfirmFormBase {

  use EnsureContentHubClientTrait;
  use ResponseCheckerTrait;

  /**
   * The Import Queue Service.
   *
   * @var \Drupal\acquia_contenthub_subscriber\ContentHubImportQueue
   */
  protected ContentHubImportQueue $importQueue;

  /**
   * Client factory.
   *
   * @var \Drupal\acquia_contenthub\Client\ClientFactory
   */
  protected ClientFactory $clientFactory;

  /**
   * The Acquia Content Hub connection details service.
   *
   * @var \Drupal\acquia_contenthub\Settings\ConnectionDetailsInterface
   */
  protected ConnectionDetailsInterface $achConnectionDetails;

  /**
   * The Subscriber Tracker Service.
   *
   * @var \Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface
   */
  protected AcquiaContentHubEntityTrackerInterface $tracker;

  /**
   * ContentHubPurgeQueueConfirmForm constructor.
   *
   * @param \Drupal\acquia_contenthub_subscriber\ContentHubImportQueue $import_queue
   *   The Import Queue Service.
   * @param \Drupal\acquia_contenthub\Client\ClientFactory $client_factory
   *   Acquia Content Hub Client factory.
   * @param \Drupal\acquia_contenthub\Settings\ConnectionDetailsInterface $ach_connection_details
   *   The Acquia Content Hub connection details service.
   * @param \Drupal\acquia_contenthub\AcquiaContentHubEntityTrackerInterface $tracker
   *   Acquia Content Hub Subscriber Tracker.
   */
  public function __construct(ContentHubImportQueue $import_queue, ClientFactory $client_factory, ConnectionDetailsInterface $ach_connection_details, AcquiaContentHubEntityTrackerInterface $tracker) {
    $this->importQueue = $import_queue;
    $this->clientFactory = $client_factory;
    $this->achConnectionDetails = $ach_connection_details;
    $this->tracker = $tracker;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('acquia_contenthub_subscriber.acquia_contenthub_import_queue'),
      $container->get('acquia_contenthub.client.factory'),
      $container->get('acquia_contenthub.connection_details_config'),
      $container->get('acquia_contenthub_subscriber.tracker')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'acquia_contenthub_purge_queue_confirm';
  }

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {
    return $this->t('Select queue to purge');
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    return new Url('acquia_contenthub_subscriber.import_queue');
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    return '';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);
    $options = [];

    $options['local'] = $this->t('Purge local import queue');
    $default_values = ['local'];

    $is_pull_enabled = $this->achConnectionDetails->getSyndicationMode() === ConnectionDetailsInterface::SYNDICATION_MODE_PULL;
    if ($is_pull_enabled) {
      $options['service'] = $this->t('Purge Content Hub Service Queue');
      $default_values = ['service'];
    }

    $form['queue_types'] = [
      '#type' => 'checkboxes',
      '#options' => $options,
      '#default_value' => $default_values,
      '#ajax' => [
        'callback' => '::updateSubmitButton',
        'wrapper' => 'submit-button-wrapper',
        'disable-refocus' => TRUE,
        'progress' => [
          'type' => 'none',
        ],
      ],
    ];

    $form['actions']['#prefix'] = '<div id="submit-button-wrapper">';
    $form['actions']['#suffix'] = '</div>';

    // Check if any queue type is selected.
    $queue_types = $form_state->getValue('queue_types', $default_values);
    $has_selection = !empty(array_filter($queue_types));

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Confirm'),
      '#button_type' => 'primary',
      '#disabled' => !$has_selection,
    ];

    $form['actions']['cancel'] = [
      '#type' => 'submit',
      '#value' => $this->t('Cancel'),
      '#name' => 'cancel',
    ];

    return $form;
  }

  /**
   * AJAX callback to update submit button state.
   *
   * @return array
   *   Returns form array.
   */
  public function updateSubmitButton(array &$form, FormStateInterface $form_state):array {
    return $form['actions'];
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    if ($form_state->getTriggeringElement()['#name'] === 'cancel') {
      $form_state->setRedirectUrl($this->getCancelUrl());
      return;
    }
    $queue_types = array_filter($form_state->getValue('queue_types'));

    $purged_queues = [];
    $messenger = $this->messenger();

    foreach ($queue_types as $queue_type) {
      try {
        if ($queue_type === 'local') {
          $this->purgeLocalQueue();
          $purged_queues[] = $this->t('Local import queue');
        }
        elseif ($queue_type === 'service') {
          $this->purgeServiceQueue();
          $purged_queues[] = $this->t('Content Hub Service queue');
        }
      }
      catch (\Exception $e) {

        $this->getLogger('acquia_contenthub_subscriber')->error('Error purging @type queue: @error', [
          '@type' => $queue_type,
          '@error' => $e->getMessage(),
        ]);

        $messenger->addError($this->t('Failed to purge @queue: @error', [
          '@queue' => $queue_type === 'local' ? $this->t('Local import queue') : $this->t('Content Hub Service queue'),
          '@error' => $e->getMessage(),
        ]));
      }
    }

    if (!empty($purged_queues)) {
      $messenger->addStatus($this->t('Successfully purged: @queues', [
        '@queues' => implode(', ', $purged_queues),
      ]));
    }

    $form_state->setRedirectUrl($this->getCancelUrl());
  }

  /**
   * Purges the local import queue.
   */
  protected function purgeLocalQueue(): void {
    $this->importQueue->purgeQueues();
    $this->tracker->delete('status', AcquiaContentHubEntityTrackerInterface::QUEUED);
    $this->getLogger('acquia_contenthub_subscriber')->info('Local import queue has been purged.');
  }

  /**
   * Purges the Content Hub service queue.
   *
   * @throws \Exception
   *   If an error occurs during purging.
   */
  protected function purgeServiceQueue(): void {
    $client = $this->getClient();
    $response = $client->purgeQueue();

    if (!$this->isResponseSuccessful($response)) {
      $error_message = $response['error']['message'] ?? 'Unknown error occurred';
      $this->getLogger('acquia_contenthub_subscriber')->error('Content Hub Service queue purge failed: @error', [
        '@error' => $error_message,
      ]);
      throw new \Exception($error_message);
    }

    $this->getLogger('acquia_contenthub_subscriber')->info('Content Hub Service queue has been purged.');
  }

}
