import express from 'express';
import cors from 'cors';
import rateLimit from 'express-rate-limit';
import { registerRoutes } from './routes';
import { getCorsAllowlist } from './config/variables';

const authRateLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many authentication attempts', errorCode: 'RATE_LIMITED' }
});
const joinRateLimiter = rateLimit({
  windowMs: 60 * 1000,
  max: 30,
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many join attempts', errorCode: 'RATE_LIMITED' }
});

function buildCorsOptions() {
  const allowlist = getCorsAllowlist();

  if (allowlist.length === 0) {
    return {};
  }

  return {
    origin(origin: string | undefined, callback: (error: Error | null, allow?: boolean) => void) {
      if (!origin || allowlist.includes(origin)) {
        callback(null, true);
        return;
      }

      callback(new Error('CORS origin not allowed'));
    }
  };
}

export function createApp(): express.Express {
  const app = express();

  // Trust loopback proxies only - avoids express-rate-limit ERR_ERL_PERMISSIVE_TRUST_PROXY.
  app.set('trust proxy', 'loopback');
  app.use(cors(buildCorsOptions()));
  app.use(express.json());
  app.use('/api/users/login', authRateLimiter);
  app.use('/api/users/register', authRateLimiter);
  app.use('/api/servers/:id/join', joinRateLimiter);

  registerRoutes(app);

  return app;
}
