<?php

namespace Drupal\eb\Service;

use Drupal\eb\Entity\EbRollbackInterface;
use Drupal\eb\Entity\EbRollbackOperationInterface;
use Drupal\eb\PluginInterfaces\OperationInterface;
use Drupal\eb\Result\ExecutionResult;
use Drupal\eb\Result\RollbackResult;

/**
 * Interface for the rollback manager service.
 *
 * The rollback manager handles storing and executing operation rollbacks,
 * allowing changes to be undone. Rollbacks are now stored as ContentEntity
 * types (EbRollback and EbRollbackOperation) in the
 * database, not exported with config.
 */
interface RollbackManagerInterface {

  /**
   * Start a new rollback record for a definition application.
   *
   * This creates a new EbRollback entity and stores the reference
   * for subsequent storeRollbackData() calls.
   *
   * @param string $definitionId
   *   The definition ID being applied.
   * @param string $label
   *   A label for this rollback (e.g., "Apply: article_fields").
   *
   * @return \Drupal\eb\Entity\EbRollbackInterface
   *   The created rollback entity.
   */
  public function startRollback(string $definitionId, string $label): EbRollbackInterface;

  /**
   * Finalize the current rollback record after definition apply completes.
   *
   * Updates operation_count and clears internal state.
   */
  public function finalizeRollback(): void;

  /**
   * Store rollback data for a single operation.
   *
   * Creates an EbRollbackOperation entity linked to the current
   * rollback. If no rollback is active, creates an ad-hoc one.
   *
   * @param \Drupal\eb\PluginInterfaces\OperationInterface $operation
   *   The operation that was executed.
   * @param \Drupal\eb\Result\ExecutionResult $result
   *   The execution result containing rollback data.
   * @param string|null $definitionId
   *   Optional source definition ID (used for ad-hoc rollbacks).
   *
   * @return \Drupal\eb\Entity\EbRollbackOperationInterface
   *   The created operation entity.
   *
   * @throws \InvalidArgumentException
   *   If no rollback data is provided in the execution result.
   */
  public function storeRollbackData(
    OperationInterface $operation,
    ExecutionResult $result,
    ?string $definitionId = NULL,
  ): EbRollbackOperationInterface;

  /**
   * Execute a rollback for an entire definition apply.
   *
   * All operations are rolled back in reverse sequence order.
   *
   * @param int $rollbackId
   *   The rollback entity ID.
   *
   * @return \Drupal\eb\Result\RollbackResult
   *   The rollback result.
   *
   * @throws \Drupal\eb\Exception\RollbackException
   *   If rollback fails.
   */
  public function executeRollback(int $rollbackId): RollbackResult;

  /**
   * Load a rollback entity by ID.
   *
   * @param int $rollbackId
   *   The rollback entity ID.
   *
   * @return \Drupal\eb\Entity\EbRollbackInterface|null
   *   The rollback entity or NULL if not found.
   */
  public function loadRollback(int $rollbackId): ?EbRollbackInterface;

  /**
   * Get all operations for a rollback.
   *
   * @param int $rollbackId
   *   The rollback entity ID.
   *
   * @return array<\Drupal\eb\Entity\EbRollbackOperationInterface>
   *   Array of operation entities.
   */
  public function getOperationsForRollback(int $rollbackId): array;

  /**
   * List rollbacks with optional filtering.
   *
   * @param array<string, mixed> $conditions
   *   Optional conditions to filter rollbacks.
   * @param int $limit
   *   Maximum number of results.
   *
   * @return array<\Drupal\eb\Entity\EbRollbackInterface>
   *   Array of rollback entities.
   */
  public function listRollbacks(array $conditions = [], int $limit = 50): array;

  /**
   * List rollbacks for a specific definition.
   *
   * @param string $definitionId
   *   The definition ID.
   * @param string|null $status
   *   Optional status filter (pending, completed, failed).
   *
   * @return array<\Drupal\eb\Entity\EbRollbackInterface>
   *   Array of rollback entities for this definition.
   */
  public function listRollbacksByDefinition(string $definitionId, ?string $status = NULL): array;

  /**
   * Validate that a rollback is possible.
   *
   * @param int $rollbackId
   *   The rollback ID.
   *
   * @return array<string, mixed>
   *   Validation result with 'valid' boolean and 'errors' array.
   */
  public function validateRollback(int $rollbackId): array;

  /**
   * Purge old rollback data.
   *
   * Deletes rollback operations first (referential integrity), then rollbacks.
   *
   * @param int|null $retentionDays
   *   Number of days to retain rollback data. If NULL, uses config default.
   *
   * @return int
   *   Number of rollback entities deleted.
   */
  public function purgeOldRollbacks(?int $retentionDays = NULL): int;

  /**
   * Delete all rollbacks for a specific definition (cascade delete).
   *
   * @param string $definitionId
   *   The definition ID.
   *
   * @return int
   *   Number of rollback entities deleted.
   */
  public function deleteByDefinition(string $definitionId): int;

}
