<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\ValueObjects;

/**
 * Value Object representing a component update response
 *
 * Contains the rendered HTML, updated state, and any events to dispatch.
 */
final readonly class ComponentUpdate
{
    /**
     * @param string $html Rendered component HTML
     * @param array<ComponentEvent> $events Events to dispatch
     * @param LiveComponentState|null $state Updated component state
     */
    public function __construct(
        public string $html,
        public array $events = [],
        public ?LiveComponentState $state = null
    ) {
    }

    /**
     * Add a ComponentEvent to this update
     */
    public function withEvent(ComponentEvent $event): self
    {
        return new self(
            html: $this->html,
            events: [...$this->events, $event],
            state: $this->state
        );
    }

    /**
     * Add multiple ComponentEvents to this update
     *
     * @param array<ComponentEvent> $events
     */
    public function withEvents(array $events): self
    {
        return new self(
            html: $this->html,
            events: [...$this->events, ...$events],
            state: $this->state
        );
    }

    /**
     * Convert to array for JSON serialization
     */
    public function toArray(): array
    {
        return [
            'html' => $this->html,
            'events' => array_map(
                fn (ComponentEvent $event) => $event->toArray(),
                $this->events
            ),
            'state' => $this->state?->toJson(),
        ];
    }
}
