import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
import cors from 'cors';

export const setupSecurity = (app) => {
  // Helmet for security headers
  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        scriptSrc: ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com'],
        scriptSrcElem: ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com'],
        imgSrc: ["'self'", 'data:', 'https:'],
        connectSrc: ["'self'", 'https:', 'wss:'],
        workerSrc: ["'self'", 'blob:'],
        fontSrc: ["'self'", 'https:', 'data:'],
      },
    },
    crossOriginEmbedderPolicy: false,
    crossOriginResourcePolicy: { policy: 'cross-origin' },
  }));

  // CORS
  // In development, allow all localhost origins for flexibility
  // In production, use the configured CORS_ORIGIN
  const corsOptions = {
    credentials: true,
    origin: (origin, callback) => {
      // Allow requests with no origin (like mobile apps or curl requests)
      if (!origin) return callback(null, true);
      
      // If CORS_ORIGIN is explicitly set, use it (supports comma-separated list)
      if (process.env.CORS_ORIGIN) {
        const allowedOrigins = process.env.CORS_ORIGIN.split(',').map(o => o.trim());
        if (allowedOrigins.includes(origin)) {
          return callback(null, true);
        }
      }
      
      // In development, allow all localhost origins for convenience
      if (process.env.NODE_ENV !== 'production') {
        if (origin.startsWith('http://localhost:') || origin.startsWith('http://127.0.0.1:')) {
          return callback(null, true);
        }
      }
      
      // Default fallback: allow if it matches our expected production domains
      // or if we just want to be permissive when CORS_ORIGIN isn't configured
      if (origin.includes('market.applaude.net') || origin.includes('localhost')) {
        return callback(null, true);
      }
      
      // If none matched, we still don't want to throw a 500 for static assets.
      // We'll allow it but CORS headers might not be optimal for true cross-origin.
      callback(null, true);
    }
  };
  
  app.use(cors(corsOptions));

  // Rate limiting
  // More lenient rate limiter for options flow endpoint (frequently polled)
  const optionsFlowLimiter = rateLimit({
    windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || '15') * 60 * 1000,
    max: parseInt(process.env.RATE_LIMIT_MAX_OPTIONS_FLOW || '500'), // Higher limit for data endpoint
    message: 'Too many requests from this IP',
    standardHeaders: true,
    legacyHeaders: false,
    // Skip rate limiting in development for localhost
    skip: (req) => {
      if (process.env.NODE_ENV !== 'production') {
        const ip = req.ip || req.connection.remoteAddress;
        return ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1' || req.hostname === 'localhost';
      }
      return false;
    }
  });

  // General rate limiter for other endpoints
  const generalLimiter = rateLimit({
    windowMs: parseInt(process.env.RATE_LIMIT_WINDOW || '15') * 60 * 1000,
    max: parseInt(process.env.RATE_LIMIT_MAX || '100'),
    message: 'Too many requests from this IP',
    standardHeaders: true,
    legacyHeaders: false,
    // Skip rate limiting in development for localhost, and skip options flow endpoint
    skip: (req) => {
      // Skip options flow endpoint (has its own limiter)
      if (req.path === '/api/options/flow' || req.path.startsWith('/api/options/flow')) {
        return true;
      }
      // Skip rate limiting in development for localhost
      if (process.env.NODE_ENV !== 'production') {
        const ip = req.ip || req.connection.remoteAddress;
        return ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1' || req.hostname === 'localhost';
      }
      return false;
    }
  });

  // Apply more lenient limiter to options flow endpoint (must be before general limiter)
  app.use('/api/options/flow', optionsFlowLimiter);
  
  // Apply general limiter to all other API endpoints
  app.use('/api/', generalLimiter);

  // Request logging
  if (process.env.NODE_ENV === 'production') {
    app.use((req, res, next) => {
      console.log(`${new Date().toISOString()} ${req.method} ${req.url}`);
      next();
    });
  }
};
