<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Streaming\Replay;

final class StreamEventLog
{
    private array $events = [];
    public static function fromArray(array $items): self { $log = new self(); foreach ($items as $item) { if (is_array($item)) { $event = StreamPersistedEvent::fromArray($item); $log->events[$event->sequence()] = $event; } } ksort($log->events); return $log; }
    public function append(array $message): StreamPersistedEvent { $event = StreamPersistedEvent::create($this->nextSequence(), $message); $this->events[$event->sequence()] = $event; return $event; }
    public function appendMany(array $messages): array { $events=[]; foreach ($messages as $message) { if (is_array($message)) { $events[]=$this->append($message); } } return $events; }
    public function replay(string $topic = '', int $fromSequence = 1, int $limit = 100): array { $events=[]; foreach ($this->events as $event) { if ($event->sequence() < $fromSequence) continue; if ($topic !== '' && $event->topic() !== $topic) continue; $events[]=$event; if (count($events) >= max(1,$limit)) break; } return $events; }
    public function all(): array { return array_values($this->events); }
    public function count(): int { return count($this->events); }
    public function nextSequence(): int { return $this->events === [] ? 1 : max(array_keys($this->events)) + 1; }
    public function toArray(): array { return array_map(static fn(StreamPersistedEvent $event): array => $event->toArray(), $this->all()); }
}
