// server.js
const { createServer } = require("http");
const next = require("next");
const { Server } = require("socket.io");
const path = require("path");
const fs = require("fs");
const fetch = (...args) => import("node-fetch").then(({ default: fetch }) => fetch(...args));

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();
const PORT = 3000;

// Hilfsfunktion zum Schreiben von JSON-Dateien bei Änderung
const writeJsonFile = (filename, data) => {
  const dir = path.join(process.cwd(), "websocketDump");
  if (!fs.existsSync(dir)) fs.mkdirSync(dir);
  const fullPath = path.join(dir, filename);
  fs.writeFileSync(fullPath, JSON.stringify(data, null, 2), "utf-8");
};

// Extrahiert relevante Datenstruktur aus Antwort
const extractData = (json, name) => {
  return (
    json?.Statis || json?.Points || json?.Systems || json?.Rights || json?.[name] || json || []
  );
};

app.prepare().then(() => {
  const server = createServer((req, res) => {
    handle(req, res);
  });

  const io = new Server(server);

  io.on("connection", socket => {
    const { m: idMap, u: idUser } = socket.handshake.query;
    console.log(`🔌 WebSocket verbunden (idMap=${idMap}, idUser=${idUser})`);

    const endpoints = [
      {
        name: "GisLinesStatus",
        getUrl: () => `WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`,
        mock: "GisLinesStatus.json",
      },
      {
        name: "GisStationsMeasurements",
        getUrl: () => `WebServiceMap.asmx/GisStationsMeasurements?idMap=${idMap}`,
        mock: "GisStationsMeasurements.json",
      },
      {
        name: "GisStationsStaticDistrict",
        getUrl: () =>
          `WebServiceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`,
        mock: "GisStationsStaticDistrict.json",
      },
      {
        name: "GisStationsStatusDistrict",
        getUrl: () =>
          `WebServiceMap.asmx/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`,
        mock: "GisStationsStatusDistrict.json",
      },
      {
        name: "GisSystemStatic",
        getUrl: () => `WebServiceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`,
        mock: "GisSystemStatic.json",
      },
    ];

    const lastDataMap = {};

    const fetchData = async () => {
      for (const { name, getUrl, mock } of endpoints) {
        try {
          let statis;

          if (dev) {
            const mockPath = path.join(process.cwd(), "mockData", mock);
            const jsonStr = fs.readFileSync(mockPath, "utf-8");
            const json = JSON.parse(jsonStr);
            statis = extractData(json, name);
            console.log(`🧪 [Mock] ${name}`);
          } else {
            const fetchUrl = `http://localhost/talas5/ClientData/${getUrl()}`;
            const res = await fetch(fetchUrl);
            const text = await res.text();

            let json;
            try {
              json = JSON.parse(text);
            } catch (err) {
              console.error(`❌ ${name}: JSON Parsing fehlgeschlagen:`, err.message);
              console.error(`🔍 Antwort war:`, text.slice(0, 300));
              continue;
            }

            statis = extractData(json, name);
            console.log(`📡 Webservice-Daten empfangen für ${name}`);
          }

          const newDataStr = JSON.stringify(statis);
          if (newDataStr !== lastDataMap[name]) {
            lastDataMap[name] = newDataStr;
            socket.emit(`${name}Updated`, statis);
            console.log(`✅ Änderung bei ${name} erkannt → gesendet`);
            writeJsonFile(`${name}.json`, statis);
          } else {
            // console.log(`🔁 ${name}: Keine Änderung`);
          }
        } catch (error) {
          console.error(`❌ Fehler bei ${name}:`, error.message);
        }
      }
    };

    // fetchData immer ausführen – unabhängig vom Modus
    fetchData();
    const interval = setInterval(fetchData, 5000); // 5 Sekunden ,TALAS.web nutzt  12 Sekunden
    socket.on("disconnect", () => {
      clearInterval(interval);
      console.log("❌ WebSocket getrennt");
    });
  });

  server.listen(PORT, () => {
    console.log(`🚀 App + WebSocket läuft auf http://localhost:${PORT}`);
  });
});
