<?php
/**
 * passenger_socket.php
 * =====================
 * WebSocket Server للركاب   — بورت 3030
 * Internal HTTP Server      — بورت 3031
 */

use Workerman\Worker;
use PHPSocketIO\SocketIO;

require_once __DIR__ . '/vendor/autoload.php';

// ---------------------------------------------------------
// نظام تسجيل الأحداث (Logging System)
// ---------------------------------------------------------
$LOG_FILE = __DIR__ . '/socket_debug.log';

function socket_log($message, $data = null) {
    global $LOG_FILE;
    $date = date('Y-m-d H:i:s');
    $logMsg = "[$date] $message";
    if ($data !== null) {
        $logMsg .= " | DATA: " . (is_string($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE));
    }
    $logMsg .= PHP_EOL;
    
    echo $logMsg; // للطباعة في الكونسول إذا كان يعمل في الـ Foreground
    @file_put_contents($LOG_FILE, $logMsg, FILE_APPEND); // الكتابة في الملف
}

// ---------------------------------------------------------

socket_log("=== STARTING PASSENGER SOCKET SERVER ===");

$INTERNAL_KEY = trim((string) @file_get_contents('/home/intaleq-rides/.internal_socket_key'));

if (empty($INTERNAL_KEY)) {
    socket_log("[CRITICAL_ERROR] Internal key missing! Exiting.");
    exit(1);
}

$PORT          = 3030;
$INTERNAL_PORT = 3031;

$io = new SocketIO($PORT);

$io->on('workerStart', function () use ($io, $INTERNAL_KEY, $INTERNAL_PORT) {

    $innerHttp = new Worker("http://0.0.0.0:$INTERNAL_PORT");

    $innerHttp->onMessage = function ($connection, $request) use ($io, $INTERNAL_KEY) {

        $headers = $request->header();
        $clientIp = $connection->getRemoteIp();
        
        if (($headers['x-internal-key'] ?? '') !== $INTERNAL_KEY) {
            socket_log("[HTTP_ERROR] Unauthorized internal request from IP: $clientIp");
            $connection->send('Unauthorized');
            return;
        }

        $post   = $request->post();
        $action = trim($post['action'] ?? '');

        if ($action === 'update_ride_status') {

            $passengerId = $post['passenger_id'] ?? null;
            $rawPayload  = $post['payload']       ?? null;

            if (!$passengerId || !$rawPayload) {
                socket_log("[HTTP_ERROR] Missing passenger_id or payload for action: update_ride_status", $post);
                $connection->send('Error: Missing passenger_id or payload');
                return;
            }

            $payload = is_string($rawPayload)
                ? (json_decode($rawPayload, true) ?? $rawPayload)
                : $rawPayload;

            socket_log("[HTTP_SUCCESS] Emitting 'ride_status_change' to Passenger #$passengerId", $payload);
            $io->to('passenger_' . $passengerId)->emit('ride_status_change', $payload);

            $connection->send('OK');

        } elseif ($action === 'update_driver_location') {

            $passengerId = $post['passenger_id'] ?? null;
            $rawPayload  = $post['payload']       ?? null;

            if (!$passengerId || !$rawPayload) {
                socket_log("[HTTP_ERROR] Missing passenger_id or payload for action: update_driver_location", $post);
                $connection->send('Error: Missing passenger_id or payload');
                return;
            }

            $payload = is_string($rawPayload)
                ? (json_decode($rawPayload, true) ?? $rawPayload)
                : $rawPayload;

            socket_log("[HTTP_SUCCESS] Emitting 'driver_location_update' to Passenger #$passengerId", $payload);
            $io->to('passenger_' . $passengerId)->emit('driver_location_update', $payload);

            $connection->send('OK');

        } else {
            socket_log("[HTTP_WARNING] Unknown action received: $action", $post);
            $connection->send('Unknown action: ' . $action);
        }
    };

    $innerHttp->listen();
    socket_log("[INFO] Internal HTTP started on port $INTERNAL_PORT");
});

$io->on('connection', function ($socket) {

    $query       = $socket->handshake['query'] ?? [];
    $passengerId = $query['id'] ?? null;
    $clientIp    = $socket->conn->remoteAddress ?? 'Unknown';

    if (!$passengerId) {
        socket_log("[SOCKET_REJECTED] Connection rejected (No passenger ID) from IP: $clientIp");
        $socket->disconnect();
        return;
    }

    $socket->join('passenger_' . $passengerId);
    socket_log("[SOCKET_CONNECTED] Passenger Connected: #$passengerId (IP: $clientIp)");

    $socket->on('heartbeat', function ($data) {
        // يمكن تفعيل السطر التالي للتأكد من النبضات إذا أردت دقة شديدة، لكنه قد يملأ ملف الـ log
        // socket_log("[SOCKET_HEARTBEAT] Received from Passenger #$passengerId");
    });

    $socket->on('disconnect', function () use ($passengerId, $clientIp) {
        socket_log("[SOCKET_DISCONNECTED] Passenger Disconnected: #$passengerId (IP: $clientIp)");
    });
});

Worker::runAll();