<?php

declare(strict_types=1);

namespace Drupal\flowdrop_stategraph\Iterator;

use Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState;

/**
 * Interface for iterator helper services.
 *
 * Iterator helpers manage the lifecycle of array iteration within
 * the state graph, providing operations to:
 * - Initialize iteration from a source array.
 * - Advance to the next item.
 * - Collect results from all iterations.
 *
 * @api
 */
interface IteratorHelperInterface {

  /**
   * Initializes iterator state from a source array.
   *
   * @param array<mixed> $items
   *   The source array to iterate over.
   *
   * @return \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState
   *   The initialized iterator state.
   */
  public function initialize(array $items): IteratorState;

  /**
   * Advances the iterator to the next item.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState $iterator
   *   The current iterator state.
   *
   * @return \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState
   *   The updated iterator state.
   *
   * @throws \Drupal\flowdrop_stategraph\Exception\IteratorExhaustedException
   *   When attempting to advance past the end.
   */
  public function advance(IteratorState $iterator): IteratorState;

  /**
   * Adds a result to the iterator's result collection.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState $iterator
   *   The current iterator state.
   * @param mixed $result
   *   The result to add.
   *
   * @return \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState
   *   The updated iterator state.
   */
  public function addResult(IteratorState $iterator, mixed $result): IteratorState;

  /**
   * Checks if the iterator can continue.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState $iterator
   *   The current iterator state.
   *
   * @return bool
   *   TRUE if more items remain.
   */
  public function hasMore(IteratorState $iterator): bool;

  /**
   * Gets the current item from the iterator.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState $iterator
   *   The current iterator state.
   *
   * @return mixed
   *   The current item.
   */
  public function getCurrentItem(IteratorState $iterator): mixed;

  /**
   * Gets all collected results.
   *
   * @param \Drupal\flowdrop_orchestration\DTO\Snapshot\IteratorState $iterator
   *   The iterator state.
   *
   * @return array<mixed>
   *   The collected results.
   */
  public function getResults(IteratorState $iterator): array;

}
