<?php
declare(strict_types=1);

namespace App\Application\Http\Controllers;

use App\Framework\Attributes\Route;
use App\Framework\Auth\Auth;
use App\Framework\Http\Method;
use App\Framework\Http\SseStream;
use App\Framework\Http\Status;
use App\Framework\Router\Result\SseResult;
use App\Framework\Router\Result\SseResultWithCallback;

/**
 * Controller für Echtzeit-Benachrichtigungen über Server-Sent Events
 */
final class NotificationController
{
    /**
     * Stellt einen SSE-Stream für allgemeine Benachrichtigungen bereit
     */
    #[Auth]
    #[Route(path: '/api/notifications/stream', method: Method::GET)]
    public function notificationStream(): SseResult
    {
        // SSE-Result mit 3 Sekunden Retry-Intervall
        $result = new SseResult(Status::OK, 3000);

        // Initiale Verbindungsbestätigung
        $result->addJsonEvent(
            ['message' => 'Verbunden mit dem Benachrichtigungsstream'],
            'connected',
            'conn-' . uniqid()
        );

        // Einige Beispiel-Benachrichtigungen beim Start senden
        $result->addJsonEvent(
            [
                'type' => 'info',
                'title' => 'Willkommen',
                'message' => 'Sie sind jetzt mit Echtzeit-Updates verbunden.',
                'timestamp' => time()
            ],
            'notification',
            'notif-' . uniqid()
        );

        return $result;
    }

    /**
     * Stellt einen benutzer-spezifischen SSE-Stream bereit
     */
    #[Auth]
    #[Route(path: '/api/notifications/user/{userId}', method: Method::GET)]
    public function userNotifications(int $userId): SseResult
    {
        // SSE-Result mit benutzerdefinierten Headern
        $result = new SseResult(Status::OK, 3000, [
            'X-User-ID' => (string)$userId
        ]);

        // Verbindungsbestätigung mit Benutzer-ID
        $result->addJsonEvent(
            [
                'message' => 'Verbunden mit dem Benutzer-Stream',
                'userId' => $userId,
                'timestamp' => time()
            ],
            'connected',
            'conn-user-' . $userId
        );

        // Aktuelle Benachrichtigungen für den Benutzer laden
        $notifications = $this->getUserNotifications($userId);

        // Benachrichtigungen zum Stream hinzufügen
        foreach ($notifications as $notification) {
            $result->addJsonEvent($notification, 'notification', $notification['id']);
        }

        return $result;
    }

    /**
     * Gibt Benachrichtigungen für einen bestimmten Benutzer zurück
     * In einer realen Anwendung würde diese Methode Daten aus einer Datenbank laden
     */
    private function getUserNotifications(int $userId): array
    {
        // Beispiel-Benachrichtigungen
        return [
            [
                'id' => 'notif-' . uniqid(),
                'type' => 'message',
                'title' => 'Neue Nachricht',
                'message' => 'Sie haben eine neue Nachricht erhalten',
                'timestamp' => time() - 300 // Vor 5 Minuten
            ],
            [
                'id' => 'notif-' . uniqid(),
                'type' => 'system',
                'title' => 'System-Update',
                'message' => 'Das System wurde aktualisiert',
                'timestamp' => time() - 3600 // Vor 1 Stunde
            ]
        ];
    }

    /**
     * Stellt einen Live-Stream mit dynamischen Updates bereit
     */
    #[Auth]
    #[Route(path: '/api/notifications/live', method: Method::GET)]
    public function liveNotifications(): SseResult
    {
        // Erweiterte SSE-Konfiguration mit Callback
        #$result = new SseResultWithCallback(Status::OK, 3000);

        // Callback für dynamische Updates festlegen
        $callback = function(SseStream $stream) {
            // Simuliere neue Benachrichtigungen (mit 10% Wahrscheinlichkeit)
            if (rand(1, 10) === 1) {
                $notificationTypes = ['info', 'warning', 'update', 'message'];
                $type = $notificationTypes[array_rand($notificationTypes)];

                $notification = [
                    'id' => 'live-notif-' . uniqid(),
                    'type' => $type,
                    'title' => 'Neue ' . ucfirst($type) . '-Benachrichtigung',
                    'message' => 'Dies ist eine dynamisch generierte Benachrichtigung vom Typ ' . $type,
                    'timestamp' => time()
                ];

                $stream->sendJson($notification, 'notification', $notification['id']);

                // Kleine Pause nach dem Senden, um das Testszenario zu simulieren
                sleep(1);
            }
        };

        $result = new SseResult(
            retryInterval: 500,
            callback: $callback,
            maxDuration: 300,
            heartbeatInterval: 15,
        );

        // Initiale Verbindungsbestätigung
        $result->addJsonEvent(
            ['message' => 'Verbunden mit dem Live-Stream', 'timestamp' => time()],
            'connected',
            'live-' . uniqid()
        );



        return $result;
    }
}
