import "dotenv/config";
import express from "express";
import swaggerUi from "swagger-ui-express";
import cors from "cors";
import { createServer } from "http";
import { Server } from "socket.io";

import { RegisterRoutes } from "./routes";
import errorHandler from "./middlewares/exception";
import rabbitmq from "./rabbitmq";

import swaggerSpecs from "./swagger.json";
import { handler as amqHandler } from "./rabbitmq/handler";
import { setInstance } from "./lib/websocket";

const PORT = +(process.env.PORT || 80);

const app = express();
const router = express.Router();

if (process.env.NODE_ENV !== "production") app.use(cors());

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpecs, { explorer: false }));

RegisterRoutes(router);

app.use(swaggerSpecs.basePath, router);
app.use(errorHandler);

app.use(express.static("static"));
app.use((_req, res, _next) => {
  res.sendFile(`${process.cwd()}/static/index.html`);
});

const server = createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*",
  },
});

setInstance(io);
io.on("connection", () => console.log("[Socket.IO] User connected."));
io.on("disconnected", () => console.log("[Socket.IO] User disconnected."));

server.listen(PORT, "0.0.0.0", () =>
  console.log(`[APP] Application is running on http://localhost:${PORT}`),
);

rabbitmq.init(amqHandler).catch((e) => console.error(e));
