const express = require("express");
const cors = require("cors");
const axios = require("axios");
const config = require("./config/config.js");
const initSockets = require("./sockets/socket.js");
const { Server } = require("socket.io");
const http = require("http");
const sequelize = require("./config/db.js");
const DatapackLoader = require("./game/DatapackLoader.js");
const path = require("path");
const app = express();
const economyService = require("./game/EconomyService.js");
const NotificationManager = require("./game/NotificationManager.js");
const AdminManager = require("./game/AdminManager.js");
const SocialManager = require("./game/SocialManager.js");

app.use(
  cors({
    origin: "*",
    methods: ["GET", "POST"],
    credentials: true,
  }),
);
app.use("/static", express.static(path.join(__dirname, "../datapacks")));
app.use(express.json());

const server = http.createServer(app);

const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"],
    credentials: true,
  },
  transports: ["websocket", "polling"],
  allowEIO3: true,
});

app.get("/api/game-metadata", (req, res) => {
  try {
    const gameData = DatapackLoader.getStaticData();
    res.json(gameData);
  } catch (error) {
    res.status(500).json({ error: "Failed to load game metadata" });
  }
});

app.get("/status", (req, res) => {
  res.json({ status: "online", players: io.engine.clientsCount });
});

const registerInApi = async () => {
  try {
    await axios.post(`${config.apiBaseUrl}/servers/register`, {
      name: config.serverName,
      url: config.host,
      secret: config.serverSecret,
      isModded: false,
      description: config.serverDescription,
      region: config.serverRegion,
    });
  } catch (error) {
    console.log(`Error: API server not found at ${config.apiBaseUrl}`);
    console.log("Please configure API_SERVER_URL= in your .env file");
    process.exit(1);
  }
};

const HEARTBEAT_INTERVAL = 1000;
const sendHeartbeat = async () => {
  try {
    await axios.post(`${config.apiBaseUrl}/servers/heartbeat`, {
      name: config.serverName,
      secret: config.serverSecret,
      playersOnline: io.engine.clientsCount,
    });
  } catch (error) {}
};

server.listen(config.port, async () => {
  try {
    const datapacksPath = path.join(__dirname, "../datapacks");
    DatapackLoader.init(datapacksPath, io);
    await sequelize.initDatabase();
    initSockets(io);
    NotificationManager.init(io);
    AdminManager.init(io);
    economyService.init(io);
    SocialManager.init(io);
    await registerInApi();
    setInterval(sendHeartbeat, HEARTBEAT_INTERVAL);
    console.log(`Server running on ${config.host}. PORT: ${config.port}`);
  } catch (error) {
    console.log(error);
    process.exit(1);
  }
});
