<?php

namespace Drupal\eb\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\eb\Entity\EbRollbackInterface;
use Drupal\eb\Service\RollbackManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Controller for entity builder rollback operations.
 */
class EbRollbackController extends ControllerBase {

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter
   *   The date formatter service.
   * @param \Drupal\eb\Service\RollbackManagerInterface $rollbackManager
   *   The rollback manager service.
   */
  public function __construct(
    EntityTypeManagerInterface $entityTypeManager,
    protected DateFormatterInterface $dateFormatter,
    protected RollbackManagerInterface $rollbackManager,
  ) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    // @phpstan-ignore new.static
    return new static(
      $container->get('entity_type.manager'),
      $container->get('date.formatter'),
      $container->get('eb.rollback_manager'),
    );
  }

  /**
   * View a single rollback entity.
   *
   * @param \Drupal\eb\Entity\EbRollbackInterface $eb_rollback
   *   The rollback entity.
   *
   * @return array<string, mixed>
   *   Render array.
   */
  public function view(EbRollbackInterface $eb_rollback): array {
    $rollback = $eb_rollback;
    $rollback_id = (int) $rollback->id();

    // Get owner.
    $owner = $rollback->getOwner();

    // Get operations for this rollback.
    $operations = $this->rollbackManager->getOperationsForRollback($rollback_id);

    // Sort by sequence.
    usort($operations, fn($a, $b) => $a->getSequence() <=> $b->getSequence());

    // Build operations table.
    $rows = [];
    foreach ($operations as $op) {
      $rows[] = [
        $op->getSequence(),
        $op->getOperationType(),
        $op->getDescription(),
      ];
    }

    $build = [];

    // Rollback details.
    $build['details'] = [
      '#type' => 'details',
      '#title' => $this->t('Rollback Details'),
      '#open' => TRUE,
    ];

    $build['details']['info'] = [
      '#type' => 'table',
      '#rows' => [
        [$this->t('ID'), $rollback->id()],
        [$this->t('Label'), $rollback->label()],
        [$this->t('Definition ID'), $rollback->getDefinitionId() ?: '-'],
        [$this->t('Status'), $rollback->getStatus()],
        [$this->t('Operation Count'), $rollback->getOperationCount()],
        [$this->t('Owner'), $owner ? $owner->getDisplayName() : $this->t('Unknown')],
        [$this->t('Created'), $this->dateFormatter->format((int) $rollback->get('created')->value, 'medium')],
        [
          $this->t('Completed'),
          $rollback->getCompletedTime()
            ? $this->dateFormatter->format($rollback->getCompletedTime(), 'medium')
            : '-',
        ],
      ],
    ];

    // Operations list.
    $build['operations'] = [
      '#type' => 'details',
      '#title' => $this->t('Operations (@count)', ['@count' => count($operations)]),
      '#open' => TRUE,
    ];

    $build['operations']['table'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('Sequence'),
        $this->t('Type'),
        $this->t('Description'),
      ],
      '#rows' => $rows,
      '#empty' => $this->t('No operations recorded.'),
    ];

    // Actions.
    $build['actions'] = [
      '#type' => 'actions',
    ];

    if ($rollback->isPending()) {
      $build['actions']['execute'] = [
        '#type' => 'link',
        '#title' => $this->t('Execute Rollback'),
        '#url' => Url::fromRoute('eb.rollback_execute', ['rollback_id' => $rollback_id]),
        '#attributes' => ['class' => ['button', 'button--primary']],
      ];
    }

    $build['actions']['back'] = [
      '#type' => 'link',
      '#title' => $this->t('Back to List'),
      '#url' => Url::fromRoute('entity.eb_rollback.collection'),
      '#attributes' => ['class' => ['button']],
    ];

    return $build;
  }

  /**
   * List available rollbacks.
   *
   * @return array<string, mixed>
   *   Render array.
   */
  public function listRollbacks(): array {
    $rollbacks = $this->rollbackManager->listRollbacks();

    if (empty($rollbacks)) {
      return [
        '#markup' => $this->t('No rollback operations available.'),
      ];
    }

    $rows = [];
    foreach ($rollbacks as $rollback) {
      $owner = $rollback->getOwner();

      // Build operation links.
      $operations = [];
      $operations[] = Link::createFromRoute(
        $this->t('View'),
        'entity.eb_rollback.canonical',
        ['eb_rollback' => $rollback->id()]
      )->toString();

      // Only show execute if status is pending.
      if ($rollback->isPending()) {
        $operations[] = Link::createFromRoute(
          $this->t('Execute Rollback'),
          'eb.rollback_execute',
          ['rollback_id' => $rollback->id()]
        )->toString();
      }

      $operations[] = Link::createFromRoute(
        $this->t('Delete'),
        'entity.eb_rollback.delete_form',
        ['eb_rollback' => $rollback->id()]
      )->toString();

      $created = $rollback->get('created')->value;

      $rows[] = [
        'id' => $rollback->id(),
        'label' => $rollback->label(),
        'definition' => $rollback->getDefinitionId() ?: '-',
        'status' => $rollback->getStatus(),
        'operations_count' => $rollback->getOperationCount(),
        'created' => $created ? $this->t('@time ago', [
          '@time' => $this->dateFormatter->formatInterval(
            time() - (int) $created
          ),
        ]) : '-',
        'user' => $owner ? $owner->getDisplayName() : $this->t('Unknown'),
        'operations' => [
          'data' => [
            '#markup' => implode(' | ', $operations),
          ],
        ],
      ];
    }

    $build['table'] = [
      '#type' => 'table',
      '#header' => [
        $this->t('ID'),
        $this->t('Label'),
        $this->t('Definition'),
        $this->t('Status'),
        $this->t('Operations'),
        $this->t('Created'),
        $this->t('User'),
        $this->t('Actions'),
      ],
      '#rows' => $rows,
      '#empty' => $this->t('No rollback operations available.'),
    ];

    return $build;
  }

}
