const { createProxyMiddleware } = require('http-proxy-middleware');
const { logProxyRequest, logProxyResponse, logProxyError } = require('../middleware/requestLogger');

// Create service proxy with enhanced logging and error handling
const createServiceProxy = (targetUrl, serviceName, options = {}) => {
  return createProxyMiddleware({
    target: targetUrl,
    changeOrigin: true,
    ws: true,
    timeout: parseInt(process.env.PROXY_TIMEOUT) || 30000,
    proxyTimeout: parseInt(process.env.PROXY_TIMEOUT) || 30000,
    pathRewrite: options.pathRewrite || {},
    onProxyReq: logProxyRequest(serviceName, targetUrl),
    onProxyRes: logProxyResponse(serviceName),
    onError: (err, req, res) => {
      logProxyError(serviceName)(err, req, res);
      
      if (!res.headersSent) {
        // Handle different types of proxy errors
        if (err.code === 'ECONNREFUSED' || err.code === 'ENOTFOUND') {
          return res.status(503).json({
            success: false,
            message: 'Service temporarily unavailable',
            service: serviceName,
            error: 'The requested service is currently unavailable',
            request_id: req.requestId,
            retry_after: 30
          });
        }

        if (err.code === 'ETIMEDOUT' || err.message.includes('timeout')) {
          return res.status(504).json({
            success: false,
            message: 'Service timeout',
            service: serviceName,
            error: 'The service took too long to respond',
            request_id: req.requestId,
            retry_after: 60
          });
        }

        // Generic proxy error
        res.status(502).json({
          success: false,
          message: 'Bad Gateway',
          service: serviceName,
          error: 'Unable to connect to the service',
          request_id: req.requestId
        });
      }
    }
  });
};

// Create auth-specific proxy (no authentication required for login/register)
const createAuthProxy = () => {
  const targetUrl = process.env.USER_AUTH_URL || 'http://localhost:8011';
  
  console.log(`🔧 [PROXY CREATION] Creating auth proxy targeting: ${targetUrl}`);
  
  return createProxyMiddleware({
    target: targetUrl,
    changeOrigin: true,
    ws: true,
    timeout: 30000,
    proxyTimeout: 30000,
    // Don't parse body - let it pass through
    parseReqBody: false,
    // Strip /api/auth prefix before forwarding to service
    pathRewrite: {
      '^/api/auth': ''
    },
    onProxyReq: (proxyReq, req, res) => {
      console.log(`🔥 [PROXY MIDDLEWARE TRIGGERED!] This means the proxy is working!`);
      
      // Calculate the rewritten path
      const rewrittenPath = req.url.replace(/^\/api\/auth/, '');
      const finalUrl = `${targetUrl}${rewrittenPath}`;
      
      console.log(`🔐 [AUTH PROXY DEBUG]`);
      console.log(`   Original URL: ${req.originalUrl}`);
      console.log(`   Request URL: ${req.url}`);
      console.log(`   Target URL: ${targetUrl}`);
      console.log(`   Rewritten Path: ${rewrittenPath}`);
      console.log(`   FINAL URL HITTING: ${finalUrl}`);
      console.log(`   Method: ${req.method}`);
      console.log(`   Headers: ${JSON.stringify(req.headers, null, 2)}`);
      
      // Add gateway headers
      proxyReq.setHeader('X-Gateway-Request-ID', req.requestId);
      proxyReq.setHeader('X-Gateway-Timestamp', new Date().toISOString());
      proxyReq.setHeader('X-Forwarded-By', 'api-gateway');
      proxyReq.setHeader('X-Forwarded-For', req.ip);
      proxyReq.setHeader('X-Forwarded-Proto', req.protocol);
      proxyReq.setHeader('X-Forwarded-Host', req.get('host'));
      
      // Ensure content-type and content-length are preserved
      if (req.headers['content-type']) {
        proxyReq.setHeader('Content-Type', req.headers['content-type']);
      }
      if (req.headers['content-length']) {
        proxyReq.setHeader('Content-Length', req.headers['content-length']);
      }
    },
    onProxyRes: (proxyRes, req, res) => {
      console.log(`🔐 [AUTH RESPONSE] ${proxyRes.statusCode} for ${req.method} ${req.originalUrl}`);
      
      // Add CORS headers
      proxyRes.headers['Access-Control-Allow-Origin'] = req.headers.origin || '*';
      proxyRes.headers['Access-Control-Allow-Credentials'] = 'true';
    },
    onError: (err, req, res) => {
      console.error(`❌ [AUTH PROXY ERROR] ${req.method} ${req.originalUrl}:`, err.message);
      
      if (!res.headersSent) {
        res.status(502).json({
          success: false,
          message: 'Authentication service unavailable',
          error: 'Unable to connect to authentication service',
          request_id: req.requestId
        });
      }
    }
  });
};

module.exports = {
  createServiceProxy,
  createAuthProxy
};
