const mqtt = require('mqtt');
const express = require('express');
const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3001;

const brokerUrl = 'mqtt://localhost'; // Replace with your broker's URL
const client = mqtt.connect(brokerUrl);

const mainTopic = 'apu_tb';
let nodeData = Array.from({ length: 5 }, () => Array(5).fill(null));
const nodeLastActive = {}; // Track the last active timestamp for each node

app.post('public/index.html')
// Serve static files from the template's public folder
app.use(express.static(path.join(__dirname, 'public')));
// app.use(express.static(__dirname));

// Route to serve the main dashboard HTML file
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public/index.html'));
});

// Example API endpoint for dashboard data
app.get('/api/data', (req, res) => {
    res.json({
        users: 150,
        sales: 2500,
        revenue: 50000,
        active_sessions: 45
    });
});


const server = require('http').createServer(app);
const ws = new WebSocket.Server({ server });

// Start the server
server.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
});

function broadcastNodeData() {
  const data = {
    nodeData,
    nodeStatus: Object.keys(nodeLastActive).reduce((acc, key) => {
      const [y, x] = key.split(',').map(Number);
      const isActive = Date.now() - nodeLastActive[key] <= 10000;
      acc[y] = acc[y] || [];
      acc[y][x] = isActive ? 'lightgreen' : 'lightcoral';
      return acc;
    }, []),
  };
  // console.log('Broadcasting data:', JSON.stringify(data)); // Log the broadcasted data
  ws.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify(data));
    }
  });
}

client.on('connect', () => {
    console.log('Connected to MQTT broker');
    client.subscribe(`${mainTopic}/#`, (err) => {
      if (!err) {
        console.log(`Subscribed to all subtopics of: ${mainTopic}`);
      } else {
        console.error('Subscription error:', err);
      }
    });
  });
  
client.on('message', (topic, message) => {
try {
    const payload = JSON.parse(message.toString());

    if (Array.isArray(payload) && payload.length === 2) {
    const data = payload[0];
    const metadata = payload[1];

    const { uptime, cpu_temp, mem_util, cpu_util, XPosition, YPosition } = data;
    const { id } = metadata;

    if (XPosition >= 0 && XPosition < 5 && YPosition >= 0 && YPosition < 5) {
        nodeData[YPosition][XPosition] = `ID: ${id}<br>Temp: ${cpu_temp}°C<br>CUtil: ${cpu_util}<br>MUtil: ${mem_util}<br>UpTime: ${uptime}`;

        // Update the last active timestamp for the node
        nodeLastActive[`${YPosition},${XPosition}`] = Date.now();

        // console.log(`Node data updated for ID ${id} at position (${XPosition}, ${YPosition})`);

        // Broadcast updated data and statuses
        // broadcastNodeData();
        // console.log("Checkboxes known:", checkedNodeInfo); // Use this array in your app
    }
    } else {
    console.error('Unexpected payload format:', payload);
    }
} catch (err) {
    console.error('Failed to process message:', err);
}
});

// Periodically broadcast the node status
setInterval(() => {
broadcastNodeData();
}, 1000);