import cors from "cors";
import express, { NextFunction, Request, Response } from "express";
import http from "http";
import { Server } from "socket.io";
import { connectDatabase } from "./config/database.js";
import { env } from "./config/env.js";
import { authenticateSocket } from "./middleware/auth.js";
import { apiRoutes } from "./routes/index.js";
import { handleConnection } from "./socket/socketHandlers.js";
import { AuthenticatedSocket } from "./types/index.js";

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    methods: ["GET", "POST", "PUT", "DELETE"],
    origin: "http://localhost:5173",
  },
});

app.use(
  cors({
    methods: ["GET", "POST", "PUT", "DELETE"],
    origin: "http://localhost:5173",
  }),
);

app.use(express.json({ limit: "5mb" }));

app.use("/api", apiRoutes);

app.get("/health", (_, res) => {
  res.json({ status: "OK", timestamp: new Date().toISOString() });
});

io.use(authenticateSocket);
io.on("connection", async (socket) => {
  await handleConnection(io, socket as AuthenticatedSocket);
});

app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
  console.error("Unhandled error:", err);
  res.status(500).json({
    success: false,
    error: env.NODE_ENV === "production" ? "Internal server error" : err.message,
  });
});

const startServer = async () => {
  try {
    await connectDatabase();

    server.listen(env.PORT, () => {
      console.log(`🚀 Server running on port ${env.PORT}`);
      console.log(`📊 Environment: ${env.NODE_ENV}`);
      console.log(`🔗 CORS Origin: ${env.CORS_ORIGIN}`);
    });
  } catch (error) {
    console.error("Failed to start server:", error);
    process.exit(1);
  }
};

process.on("SIGTERM", () => {
  console.log("SIGTERM received, shutting down gracefully...");
  server.close(() => {
    console.log("HTTP server closed");
    process.exit(0);
  });
});

(async () => {
  await startServer();
})();
