<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Sourcing\Domain;

final class DomainEventListenerRegistry
{
    /** @var array<string, DomainEventListener> */
    private array $listeners = [];

    public static function fromArray(array $items): self
    {
        $registry = new self();

        foreach ($items as $item) {
            if (is_array($item)) {
                $registry->register(DomainEventListener::fromArray($item));
            }
        }

        return $registry;
    }

    public function register(DomainEventListener $listener): DomainEventListener
    {
        $this->listeners[$listener->listenerId()] = $listener;
        return $listener;
    }

    public function matching(DomainEventEnvelope $event): array
    {
        return array_values(array_filter(
            $this->listeners,
            static fn (DomainEventListener $listener): bool => $listener->listensTo($event)
        ));
    }

    public function all(): array
    {
        return array_values($this->listeners);
    }

    public function count(): int
    {
        return count($this->listeners);
    }

    public function toArray(): array
    {
        return array_map(static fn (DomainEventListener $listener): array => $listener->toArray(), $this->all());
    }
}
