
// server.js
const dotenv = require("dotenv");
dotenv.config();
const { connectPostgres } = require("./config/db");
const { connectRedis, redisClient } = require("./config/redis");
const http = require("http");
const { initSocket } = require("./socket");

const PORT = process.env.PORT || 8002;

const startServer = async () => {
  try {
    console.log("🔌 Connecting to databases...");
    
    // Connect to PostgreSQL first
    await connectPostgres();
    console.log("✅ PostgreSQL connected");
    
    // Connect to Redis second (required for sessions)
    await connectRedis();
    console.log("✅ Redis connected");
    
    // Verify Redis connection
    if (!redisClient.isOpen) {
      throw new Error("Redis connection failed to open");
    }
    await redisClient.set("health-check", "ok");
    const healthCheck = await redisClient.get("health-check");
    if (healthCheck !== "ok") {
      throw new Error("Redis read/write test failed");
    }
    console.log("✅ Redis health check passed");
    
    // Now import app (session will have connected Redis)
    console.log("📦 Loading application...");
    const app = require("./app");
    
    // Create HTTP server
    const server = http.createServer(app);
    
    // 👇 INITIALIZE SOCKET.IO
    initSocket(server);
    
    // Start server
    server.listen(PORT, () => {
      console.log(`\n🚀 Server running on http://localhost:${PORT}`);
      console.log(`📖 Swagger docs available at http://localhost:${PORT}/api-docs`);
      console.log(`🔍 Health check available at http://localhost:${PORT}/health`);
      console.log(`\n✨ Ready to accept requests!\n`);
    });
    
    // Graceful shutdown
    const gracefulShutdown = async (signal) => {
      console.log(`\n⚠️ Received ${signal}, shutting down gracefully...`);
      server.close(async () => {
        console.log("HTTP server closed");
        
        if (redisClient && redisClient.isOpen) {
          await redisClient.quit();
          console.log("Redis connection closed");
        }
        
        console.log("✅ Graceful shutdown completed");
        process.exit(0);
      });
    };
    
    process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
    process.on("SIGINT", () => gracefulShutdown("SIGINT"));
    
  } catch (err) {
    console.error("❌ Failed to start server:", err);
    console.error("Error details:", err.message);
    
    // Cleanup on failure
    if (redisClient && redisClient.isOpen) {
      await redisClient.quit().catch(console.error);
    }
    
    process.exit(1);
  }
};

// Handle uncaught exceptions
process.on("uncaughtException", (err) => {
  console.error("❌ Uncaught Exception:", err);
  process.exit(1);
});

// Handle unhandled promise rejections
process.on("unhandledRejection", (reason, promise) => {
  console.error("❌ Unhandled Rejection at:", promise, "reason:", reason);
  process.exit(1);
});

startServer();