<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Listener;

use InvalidArgumentException;
use PpPhp\Core\Platform\Event\Contracts\EventListenerInterface;

final class ListenerRepository
{
    private array $queues = [];

    public function add(string $eventName, mixed $listener, int $priority = 0): void
    {
        if (!$listener instanceof EventListenerInterface && !is_callable($listener)) {
            throw new InvalidArgumentException('Event listener must be callable or implement EventListenerInterface.');
        }

        if (!isset($this->queues[$eventName])) {
            $this->queues[$eventName] = new ListenerPriorityQueue();
        }

        $this->queues[$eventName]->add(new EventListenerDefinition($eventName, $listener, $priority));
    }

    public function get(string $eventName): array
    {
        return isset($this->queues[$eventName]) ? $this->queues[$eventName]->all() : [];
    }

    public function has(string $eventName): bool
    {
        return isset($this->queues[$eventName]) && $this->queues[$eventName]->count() > 0;
    }

    public function events(): array { return array_keys($this->queues); }

    public function count(): int
    {
        return array_sum(array_map(static fn (ListenerPriorityQueue $queue): int => $queue->count(), $this->queues));
    }

    public function toArray(): array
    {
        $data = [];
        foreach ($this->queues as $eventName => $queue) {
            $data[$eventName] = $queue->toArray();
        }
        return $data;
    }
}
