<?php

declare(strict_types=1);

require_once __DIR__ . '/includes/bootstrap.php';

// Server-Sent Events (SSE) stream of sale events for the currently logged-in user.

$user = current_user();
if ($user === null) {
    http_response_code(401);
    header('Content-Type: text/plain; charset=utf-8');
    echo "Unauthorized";
    exit;
}

// IMPORTANT: This SSE connection stays open for up to ~2 minutes.
// If we keep the PHP session open, it will hold an exclusive lock on the session file,
// which blocks *all* other requests from the same browser (api.php clicks feel random/slow).
// We only need the session to read the user id once, so release the lock immediately.
if (session_status() === PHP_SESSION_ACTIVE) {
    session_write_close();
}

@ini_set('output_buffering', 'off');
@ini_set('zlib.output_compression', '0');

while (ob_get_level() > 0) {
    ob_end_flush();
}
ob_implicit_flush(true);

header('Content-Type: text/event-stream; charset=utf-8');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Connection: keep-alive');

$lastId = 0;
if (!empty($_SERVER['HTTP_LAST_EVENT_ID'])) {
    $lastId = (int)$_SERVER['HTTP_LAST_EVENT_ID'];
} elseif (isset($_GET['lastId'])) {
    $lastId = (int)$_GET['lastId'];
}

$uid = (string)($user['id'] ?? '');
$subs = csv_read_assoc(SUBSCRIPTIONS_CSV, subscriptions_headers());
$subBizIds = [];
foreach ($subs as $s) {
    if ((string)($s['user_id'] ?? '') !== $uid) {
        continue;
    }
    $bid = (string)($s['business_id'] ?? '');
    if ($bid !== '') {
        $subBizIds[$bid] = true;
    }
}

// Keep the connection open for a while; the browser will reconnect as needed.
// Pings keep intermediaries (and some browsers) from closing the connection.
$startTime = time();
$maxSeconds = 120;
$pingIntervalSeconds = 15;
$lastPingAt = 0;

while ((time() - $startTime) < $maxSeconds) {
    if (connection_aborted()) {
        break;
    }

    $events = csv_read_assoc(SALE_EVENTS_CSV, ['business_id', 'message', 'end_at', 'created_at']);

    // CSV has a header row; csv_read_assoc returns only data rows. We simulate IDs by row index (1-based).
    $idx = 0;
    foreach ($events as $e) {
        $idx++;
        if ($idx <= $lastId) {
            continue;
        }

        $bid = (string)($e['business_id'] ?? '');
        if ($bid === '' || empty($subBizIds[$bid])) {
            continue;
        }

        $payload = [
            'business_id' => $bid,
            'message' => (string)($e['message'] ?? ''),
            'end_at' => (string)($e['end_at'] ?? ''),
            'created_at' => (string)($e['created_at'] ?? ''),
        ];

        echo "id: {$idx}\n";
        echo "event: sale\n";
        echo 'data: ' . json_encode($payload, JSON_UNESCAPED_SLASHES) . "\n\n";
        $lastId = $idx;
    }

    // Keep-alive ping (not too frequent to reduce chatter)
    $now = time();
    if (($now - $lastPingAt) >= $pingIntervalSeconds) {
        echo "event: ping\n";
        echo 'data: ' . json_encode(['ts' => gmdate('c')]) . "\n\n";
        $lastPingAt = $now;
    }

    @flush();
    @ob_flush();

    usleep(1000 * 1000);
}

exit;
