<?php

namespace App\Core\RealTime;

/**
 * Server-Sent Events (SSE) Implementation
 * لإرسال updates في الوقت الفعلي
 */
class ServerSentEvents
{
    private bool $started = false;

    /**
     * بدء SSE connection
     */
    public function start(): void
    {
        if ($this->started) {
            return;
        }

        // تعطيل output buffering
        while (ob_get_level() > 0) {
            ob_end_clean();
        }

        // إعداد headers
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('Connection: keep-alive');
        header('X-Accel-Buffering: no'); // Nginx

        $this->started = true;
    }

    /**
     * إرسال event
     */
    public function send(string $event, $data, ?string $id = null): void
    {
        if (!$this->started) {
            $this->start();
        }

        if ($id !== null) {
            echo "id: {$id}\n";
        }

        echo "event: {$event}\n";
        echo "data: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n";

        // Flush output
        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }

    /**
     * إرسال data فقط
     */
    public function sendData($data, ?string $id = null): void
    {
        if (!$this->started) {
            $this->start();
        }

        if ($id !== null) {
            echo "id: {$id}\n";
        }

        echo "data: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n";

        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }

    /**
     * إرسال comment (لـ keep-alive)
     */
    public function sendComment(string $comment): void
    {
        if (!$this->started) {
            $this->start();
        }

        echo ": {$comment}\n\n";

        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }

    /**
     * إرسال retry interval
     */
    public function setRetry(int $milliseconds): void
    {
        if (!$this->started) {
            $this->start();
        }

        echo "retry: {$milliseconds}\n\n";

        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }

    /**
     * إرسال keep-alive ping
     */
    public function ping(): void
    {
        $this->sendComment('ping ' . time());
    }

    /**
     * إغلاق connection
     */
    public function close(): void
    {
        if ($this->started) {
            $this->sendComment('close');
            exit;
        }
    }
}
