<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents;

use App\Framework\LiveComponents\ValueObjects\ComponentId;

/**
 * Event Dispatcher for Nested LiveComponents
 *
 * Specialized event dispatcher that handles event bubbling through
 * component hierarchies. Events dispatched by child components
 * bubble up to their parents.
 *
 * Features:
 * - Event bubbling from child to parent
 * - Integration with NestedComponentManager
 * - Event tracking for debugging
 */
final class NestedComponentEventDispatcher
{
    /** @var array<array{component_id: string, event_name: string, payload: array}> */
    private array $dispatchedEvents = [];

    /**
     * Dispatch an event that will bubble up to parent components
     *
     * @param ComponentId $componentId Source component that dispatches the event
     * @param string $eventName Event name (e.g., 'todo-completed')
     * @param array $payload Event payload data
     */
    public function dispatch(ComponentId $componentId, string $eventName, array $payload): void
    {
        $this->dispatchedEvents[] = [
            'component_id' => $componentId->toString(),
            'event_name' => $eventName,
            'payload' => $payload,
            'timestamp' => microtime(true),
        ];
    }

    /**
     * Get all dispatched events
     *
     * @return array<array{component_id: string, event_name: string, payload: array}>
     */
    public function getEvents(): array
    {
        return $this->dispatchedEvents;
    }

    /**
     * Clear all events (used after processing)
     */
    public function clear(): void
    {
        $this->dispatchedEvents = [];
    }

    /**
     * Check if any events were dispatched
     */
    public function hasEvents(): bool
    {
        return ! empty($this->dispatchedEvents);
    }

    /**
     * Get events count
     */
    public function count(): int
    {
        return count($this->dispatchedEvents);
    }
}
