<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

require '/mnt/www-live/TechOdyssey_Designs_Dashboard/vendor/autoload.php';
require '/mnt/www-live/TechOdyssey_Designs_Dashboard/src/db.php';
require_once '/mnt/www-live/TechOdyssey_Designs_Dashboard/src/envLoader.php';
loadEnv(__DIR__ . '/../../.env');

use PhpMqtt\Client\MqttClient;
use PhpMqtt\Client\ConnectionSettings;

session_start();

// Enable asynchronous signal handling
pcntl_async_signals(true);

// MQTT Configuration from .env
$mqttPort = $_ENV['MQTT_PORT'];
$mqttUsername = $_ENV['MQTT_USERNAME'];
$clientId = 'printer_monitor_' . uniqid();

// Fetch printers associated with the logged-in user
try {
    $stmt = $pdo->prepare("SELECT * FROM bambuPrinters");
    $stmt->execute();
    $printers = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    die(json_encode(['status' => 'error', 'message' => 'Failed to fetch printers.']));
}

// Process 2 messages per printer
$maxMessagesPerPrinter = 2;

try {
    foreach ($printers as $printer) {
        echo "Connecting to " . $printer['printerName'] . " (" . $printer['serialNumber'] . ")...\n";
        echo "IP Address: " . $printer['printerIp'] . "\n";
        echo "MQTT Password: " . $printer['mqttPassword'] . "\n";

        $mqttPassword = $printer['mqttPassword'];  // Use mqttPassword from DB
        $printerIp = $printer['printerIp'];        // Printer IP from DB
        $messageCount = 0;                         // Reset counter per printer

        $mqtt = new MqttClient($printerIp, $mqttPort, $clientId);

        // Handle SIGINT (CTRL + C) to gracefully exit
        pcntl_signal(SIGINT, function () use ($mqtt) {
            echo "Interrupt received. Disconnecting MQTT...\n";
            $mqtt->interrupt();
        });

        $connectionSettings = (new ConnectionSettings())
            ->setUsername($mqttUsername)
            ->setPassword($mqttPassword)
            ->setKeepAliveInterval(60)
            ->setUseTls(true)
            ->setTlsVerifyPeer(false)
            ->setTlsVerifyPeerName(false);

        // Establish Connection
        $mqtt->connect($connectionSettings, true);

        // Subscribe to the printer's report topic
        $topic = "device/{$printer['serialNumber']}/report";
        
        $mqtt->subscribe($topic, function (string $topic, string $message) use (
            $printer, $pdo, &$messageCount, $maxMessagesPerPrinter, $mqtt
        ) {
            echo "[" . $printer['printerName'] . "] [$topic] $message\n";

            // Store full JSON telemetry report
            try {
                $stmt = $pdo->prepare("
                    INSERT INTO printerTelemetry 
                    (printerId, telemetry) 
                    VALUES 
                    (:printerId, :telemetry)
                ");
                $stmt->execute([
                    ':printerId' => $printer['id'],
                    ':telemetry' => $message
                ]);
            } catch (PDOException $e) {
                error_log("Failed to insert telemetry: " . $e->getMessage());
            }

            $messageCount++;

            // Stop loop after 2 messages for this printer
            if ($messageCount >= $maxMessagesPerPrinter) {
                echo "Processed $maxMessagesPerPrinter messages for " . $printer['printerName'] . ". Disconnecting...\n";
                $mqtt->interrupt();
            }
        }, 0);

        // Start Listening for Messages
        $mqtt->loop(true);  // Loop until interrupted after processing 2 messages
        $mqtt->disconnect();
    }
} catch (Exception $e) {
    die(json_encode(['status' => 'error', 'message' => 'MQTT connection failed. ' . $e->getMessage()]));
}
?>
