<?php

declare(strict_types=1);

namespace Drupal\flowdrop_interrupt\Controller;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\flowdrop_interrupt\Form\CancelInterruptForm;
use Drupal\flowdrop_interrupt\Form\ResolveInterruptForm;
use Drupal\flowdrop_interrupt\Service\InterruptManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Controller for individual interrupt detail and cancel pages.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
final class InterruptDetailController extends ControllerBase {

  public function __construct(
    protected readonly InterruptManagerInterface $interruptManager,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    return new static($container->get('flowdrop_interrupt.manager'));
  }

  /**
   * Renders the respond form for an interrupt.
   *
   * @param string $interrupt_id
   *   The interrupt UUID.
   *
   * @return array<string, mixed>
   *   A render array with the resolve form.
   */
  public function page(string $interrupt_id): array {
    $interrupt = $this->interruptManager->getInterrupt($interrupt_id);

    if (!$interrupt) {
      throw new NotFoundHttpException();
    }

    if (!$interrupt->isPending()) {
      return [
        '#markup' => '<p>' . $this->t('This interrupt is no longer pending.') . '</p>',
        '#cache' => ['max-age' => 0],
      ];
    }

    return $this->formBuilder()->getForm(ResolveInterruptForm::class, $interrupt_id);
  }

  /**
   * Access callback for the respond page.
   *
   * @param string $interrupt_id
   *   The interrupt UUID.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(string $interrupt_id, AccountInterface $account): AccessResultInterface {
    $interrupt = $this->interruptManager->getInterrupt($interrupt_id);
    if (!$interrupt) {
      return AccessResult::forbidden()->setCacheMaxAge(0);
    }
    /** @var \Drupal\Core\Access\AccessResult $result */
    $result = $interrupt->access('resolve', $account, TRUE);
    return $result->setCacheMaxAge(0);
  }

  /**
   * Renders the cancel confirmation form for an interrupt.
   *
   * @param string $interrupt_id
   *   The interrupt UUID.
   *
   * @return array<string, mixed>
   *   A render array with the cancel form.
   */
  public function cancelPage(string $interrupt_id): array {
    $interrupt = $this->interruptManager->getInterrupt($interrupt_id);

    if (!$interrupt) {
      throw new NotFoundHttpException();
    }

    if (!$interrupt->isPending()) {
      return [
        '#markup' => '<p>' . $this->t('This interrupt is no longer pending.') . '</p>',
        '#cache' => ['max-age' => 0],
      ];
    }

    return $this->formBuilder()->getForm(CancelInterruptForm::class, $interrupt_id);
  }

  /**
   * Access callback for the cancel page.
   *
   * @param string $interrupt_id
   *   The interrupt UUID.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The current user account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function cancelAccess(string $interrupt_id, AccountInterface $account): AccessResultInterface {
    $interrupt = $this->interruptManager->getInterrupt($interrupt_id);
    if (!$interrupt) {
      return AccessResult::forbidden()->setCacheMaxAge(0);
    }
    /** @var \Drupal\Core\Access\AccessResult $result */
    $result = $interrupt->access('cancel', $account, TRUE);
    return $result->setCacheMaxAge(0);
  }

}
