<?php

namespace App\Http\Controllers;

use App\Models\RealtimeNotification;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

class RealtimeNotificationController extends Controller
{
    public function stream(Request $request): StreamedResponse
    {
        $lastId = (int) ($request->header('Last-Event-ID') ?: $request->query('last_id', 0));
        $sleepMicroseconds = app()->runningUnitTests() ? 1_000 : 1_000_000;
        $maxIterations = app()->runningUnitTests() || app()->environment('local') ? 1 : 25;

        return response()->stream(function () use ($lastId, $sleepMicroseconds, $maxIterations): void {
            $currentLastId = max(0, $lastId);
            $iteration = 0;

            echo "retry: 2500\n\n";
            if (function_exists('ignore_user_abort')) {
                ignore_user_abort(true);
            }

            while (! connection_aborted() && $iteration < $maxIterations) {
                echo "event: ping\n";
                echo 'data: ' . json_encode([
                    'time' => now()->toISOString(),
                ], JSON_UNESCAPED_UNICODE) . "\n\n";

                $notifications = RealtimeNotification::query()
                    ->where('id', '>', $currentLastId)
                    ->oldest('id')
                    ->limit(10)
                    ->get();

                foreach ($notifications as $notification) {
                    $currentLastId = max($currentLastId, $notification->id);
                    echo 'id: ' . $notification->id . "\n";
                    echo "event: admin-notification\n";
                    echo 'data: ' . json_encode($this->notificationResource($notification), JSON_UNESCAPED_UNICODE) . "\n\n";
                }

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

                flush();
                $iteration++;

                if ($iteration < $maxIterations) {
                    usleep($sleepMicroseconds);
                }
            }
        }, 200, [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache, no-transform',
            'Connection' => 'keep-alive',
            'X-Accel-Buffering' => 'no',
        ]);
    }

    public function latest(Request $request)
    {
        $lastId = (int) $request->query('last_id', 0);
        $notifications = RealtimeNotification::query()
            ->where('id', '>', max(0, $lastId))
            ->oldest('id')
            ->limit(10)
            ->get()
            ->map(fn (RealtimeNotification $notification) => $this->notificationResource($notification));

        return response()->json([
            'data' => [
                'latest_id' => RealtimeNotification::max('id') ?? 0,
                'unread_count' => RealtimeNotification::whereNull('dibaca_pada')->count(),
                'notifications' => $notifications,
            ],
        ]);
    }

    private function notificationResource(RealtimeNotification $notification): array
    {
        return [
            'id' => $notification->id,
            'type' => $notification->jenis,
            'title' => $notification->judul,
            'message' => $notification->pesan,
            'url' => $notification->url,
            'payload' => $notification->data,
            'created_at' => $notification->dibuat_pada?->toISOString(),
            'created_label' => $notification->dibuat_pada?->format('H:i'),
        ];
    }
}
