<?php

declare(strict_types=1);

namespace App\Framework\Router\Result;

use App\Framework\Http\Status;
use App\Framework\Router\ActionResult;
use Closure;

final class SseResult implements ActionResult
{
    /**
     * @var array<SseEvent> Enthält die SSE-Events, die beim initialen Verbindungsaufbau gesendet werden
     */
    private array $initialEvents = [];

    /**
     * @param Status $status HTTP-Status-Code der Antwort
     * @param int|null $retryInterval Zeit in Millisekunden, nach der der Client bei Verbindungsverlust neu verbinden soll
     * @param array<string, string> $headers Zusätzliche HTTP-Header für die Response
     */
    public function __construct(
        public readonly Status $status = Status::OK,
        public readonly ?int $retryInterval = 3000,
        public readonly array $headers = [],
        public readonly ?Closure $callback = null,
        public readonly int $maxDuration = 0,
        public readonly int $heartbeatInterval = 30,
    ) {
    }

    /**
     * Fügt ein Event hinzu, das beim initialen Verbindungsaufbau gesendet wird
     */
    public function addEvent(
        string $data,
        ?string $event = null,
        ?string $id = null,
        ?int $retry = null
    ): self {
        $this->initialEvents[] = new SseEvent($data, $event, $id, $retry);

        return $this;
    }

    /**
     * Fügt ein JSON-formatiertes Event hinzu
     */
    public function addJsonEvent(
        array $data,
        ?string $event = null,
        ?string $id = null,
        ?int $retry = null
    ): self {
        return $this->addEvent(json_encode($data), $event, $id, $retry);
    }

    /**
     * Gibt alle initialen Events zurück
     *
     * @return array<SseEvent>
     */
    public function getInitialEvents(): array
    {
        return $this->initialEvents;
    }

    public function hasCallback(): bool
    {
        return $this->callback !== null;
    }
}
