import express, { type Request, Response, NextFunction } from "express";
import compression from "compression";
import { registerRoutes } from "./routes";
import { setupVite, serveStatic, log } from "./vite";
import { registerDebugRoutes, debugMiddleware, errorHandler, addErrorLog } from "./debug-routes";
import { initializeWebSocket } from "./websocket";
import { initializeQueues } from "./queue";
import { getRedisClient } from "./redis";

const app = express();

// Enable gzip compression for better performance
app.use(compression());

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// Add debug middleware for performance monitoring
app.use(debugMiddleware);

app.use((req, res, next) => {
  const start = Date.now();
  const path = req.path;
  let capturedJsonResponse: Record<string, any> | undefined = undefined;

  const originalResJson = res.json;
  res.json = function (bodyJson, ...args) {
    capturedJsonResponse = bodyJson;
    return originalResJson.apply(res, [bodyJson, ...args]);
  };

  res.on("finish", () => {
    const duration = Date.now() - start;
    if (path.startsWith("/api")) {
      let logLine = `${req.method} ${path} ${res.statusCode} in ${duration}ms`;
      if (capturedJsonResponse) {
        logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`;
      }

      if (logLine.length > 80) {
        logLine = logLine.slice(0, 79) + "…";
      }

      log(logLine);
    }
  });

  next();
});

(async () => {
  const server = await registerRoutes(app);
  
  // Initialize Redis client
  try {
    getRedisClient();
    log('Redis client initialized');
  } catch (error) {
    log('Warning: Redis connection failed, caching disabled');
  }

  // Initialize WebSocket server for real-time features
  try {
    initializeWebSocket(server);
    log('WebSocket server initialized');
  } catch (error) {
    log('Warning: WebSocket initialization failed');
  }

  // Initialize Bull queues for background jobs
  try {
    initializeQueues();
    log('Background job queues initialized');
  } catch (error) {
    log('Warning: Background queues initialization failed');
  }
  
  // Register debug routes for system monitoring
  registerDebugRoutes(app);

  // Replace default error handler with debug-aware version
  app.use(errorHandler);

  // importantly only setup vite in development and after
  // setting up all the other routes so the catch-all route
  // doesn't interfere with the other routes
  if (app.get("env") === "development") {
    await setupVite(app, server);
  } else {
    serveStatic(app);
  }

  // ALWAYS serve the app on port 5000
  // this serves both the API and the client.
  // It is the only port that is not firewalled.
  const port = 5000;
  server.listen({
    port,
    host: "0.0.0.0",
    reusePort: true,
  }, () => {
    log(`serving on port ${port}`);
  });
})();
