<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents;

use App\Framework\LiveComponents\ValueObjects\ComponentEvent;
use App\Framework\LiveComponents\ValueObjects\EventPayload;

/**
 * Event Dispatcher for LiveComponents
 *
 * Components can use this to dispatch events during action execution.
 * Events are collected and returned in the ComponentUpdate.
 */
final class ComponentEventDispatcher
{
    /** @var array<ComponentEvent> */
    private array $events = [];

    /**
     * Dispatch a broadcast event (to all components)
     */
    public function dispatch(string $eventName, ?EventPayload $payload = null): void
    {
        $this->events[] = ComponentEvent::broadcast($eventName, $payload);
    }

    /**
     * Dispatch a targeted event (to specific component)
     */
    public function dispatchTo(string $eventName, string $targetComponentId, ?EventPayload $payload = null): void
    {
        $this->events[] = ComponentEvent::target($eventName, $targetComponentId, $payload);
    }

    /**
     * Add a ComponentEvent directly
     */
    public function add(ComponentEvent $event): void
    {
        $this->events[] = $event;
    }

    /**
     * Get all dispatched events
     *
     * @return array<ComponentEvent>
     */
    public function getEvents(): array
    {
        return $this->events;
    }

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

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