require('dotenv').config();

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const { createProxyMiddleware } = require('http-proxy-middleware');
const jwt = require('jsonwebtoken');
const axios = require('axios');

// Import middleware
const corsMiddleware = require('./middleware/cors');
const authMiddleware = require('./middleware/authentication');
const serviceHealthMiddleware = require('./middleware/serviceHealth');
const requestLogger = require('./middleware/requestLogger');
const websocketAuth = require('./middleware/webSocket');

// Import route handlers
const serviceRouter = require('./routes/serviceRouter');
const healthRouter = require('./routes/healthRouter');
const websocketRouter = require('./routes/websocketRouter');

const app = express();
// Apply CORS middleware before other middleware
app.use(corsMiddleware);
// Ensure CORS preflight (OPTIONS) requests are handled globally before any proxies
app.options('*', corsMiddleware);
// Force explicit ACAO for credentialed requests (avoid downstream "*")
app.use((req, res, next) => {
  const origin = req.headers.origin || '*';
  res.setHeader('Access-Control-Allow-Origin', origin);
  res.setHeader('Vary', 'Origin');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  next();
});
const server = http.createServer(app);
const PORT = process.env.PORT || 8000;

// Initialize Socket.IO with CORS
const io = socketIo(server, {
  cors: {
    origin: "*",
    credentials: true,
    methods: ['GET', 'POST']
  },
  transports: ['websocket', 'polling']
});

// Make io available globally for other modules
global.io = io;

// Service targets configuration
const serviceTargets = {
  USER_AUTH_URL: process.env.USER_AUTH_URL || 'http://localhost:8011',
  TEMPLATE_MANAGER_URL: process.env.TEMPLATE_MANAGER_URL || 'http://192.168.1.17:8009',
  GIT_INTEGRATION_URL: process.env.GIT_INTEGRATION_URL || 'http://localhost:8012',
  REQUIREMENT_PROCESSOR_URL: process.env.REQUIREMENT_PROCESSOR_URL || 'http://localhost:8001',
  TECH_STACK_SELECTOR_URL: process.env.TECH_STACK_SELECTOR_URL || 'http://localhost:8002',
  ARCHITECTURE_DESIGNER_URL: process.env.ARCHITECTURE_DESIGNER_URL || 'http://localhost:8003',
  CODE_GENERATOR_URL: process.env.CODE_GENERATOR_URL || 'http://localhost:8004',
  TEST_GENERATOR_URL: process.env.TEST_GENERATOR_URL || 'http://localhost:8005',
  DEPLOYMENT_MANAGER_URL: process.env.DEPLOYMENT_MANAGER_URL || 'http://localhost:8006',
  DASHBOARD_URL: process.env.DASHBOARD_URL || 'http://localhost:8008',
  SELF_IMPROVING_GENERATOR_URL: process.env.SELF_IMPROVING_GENERATOR_URL || 'http://localhost:8007',
  AI_MOCKUP_URL: process.env.AI_MOCKUP_URL || 'http://localhost:8021',
};

// Log service targets for debugging
console.log('🔧 Service Targets Configuration:');
Object.entries(serviceTargets).forEach(([name, url]) => {
  console.log(`   ${name}: ${url}`);
});

// ========================================
// MIDDLEWARE SETUP
// ========================================

// Security middleware
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      scriptSrc: ["'self'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'", "ws:", "wss:"]
    }
  }
}));

// CORS is already configured via corsMiddleware above

// Global body parser for all routes - MUST be first
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Request parsing middleware - only for non-proxy routes
app.use('/api/websocket', express.json({ limit: '10mb' }));
app.use('/api/gateway', express.json({ limit: '10mb' }));
app.use('/api/auth', express.json({ limit: '10mb' }));
app.use('/api/templates', express.json({ limit: '10mb' }));
app.use('/api/features', express.json({ limit: '10mb' }));
app.use('/api/admin', express.json({ limit: '10mb' }));
app.use('/api/github', express.json({ limit: '10mb' }));
app.use('/api/mockup', express.json({ limit: '10mb' }));
app.use('/api/ai', express.json({ limit: '10mb' }));
app.use('/health', express.json({ limit: '10mb' }));

// Trust proxy for accurate IP addresses
app.set('trust proxy', 1);

// Request ID middleware for tracing
app.use((req, res, next) => {
  req.requestId = `gw-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  res.setHeader('X-Request-ID', req.requestId);
  next();
});

app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));

// Custom request logger for service tracking
app.use(requestLogger.logRequest);

// Rate limiting configuration (disabled by default via env)
const isRateLimitDisabled = (process.env.GATEWAY_DISABLE_RATE_LIMIT || process.env.DISABLE_RATE_LIMIT || 'true').toLowerCase() === 'true';
const createServiceLimiter = (maxRequests = 1000) => {
  if (isRateLimitDisabled) {
    return (req, res, next) => next();
  }
  return rateLimit({
    windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000,
    max: maxRequests,
    message: {
      success: false,
      message: 'Too many requests, please try again later.',
      retry_after: 900
    },
    standardHeaders: true,
    legacyHeaders: false
  });
};

// Health check endpoint (before rate limiting and authentication)
app.get('/health', (req, res) => {
  res.json({
    success: true,
    service: 'api-gateway',
    status: 'healthy',
    timestamp: new Date().toISOString(),
    version: process.env.npm_package_version || '1.0.0',
    environment: process.env.NODE_ENV || 'development',
    uptime: process.uptime(),
    services: {
      user_auth: process.env.USER_AUTH_URL ? 'configured' : 'not configured',
      template_manager: process.env.TEMPLATE_MANAGER_URL ? 'configured' : 'not configured',
      git_integration: process.env.GIT_INTEGRATION_URL ? 'configured' : 'not configured',
      requirement_processor: process.env.REQUIREMENT_PROCESSOR_URL ? 'configured' : 'not configured',
      tech_stack_selector: process.env.TECH_STACK_SELECTOR_URL ? 'configured' : 'not configured',
      architecture_designer: process.env.ARCHITECTURE_DESIGNER_URL ? 'configured' : 'not configured',
      code_generator: process.env.CODE_GENERATOR_URL ? 'configured' : 'not configured',
      test_generator: process.env.TEST_GENERATOR_URL ? 'configured' : 'not configured',
      deployment_manager: process.env.DEPLOYMENT_MANAGER_URL ? 'configured' : 'not configured',
      dashboard: process.env.DASHBOARD_URL ? 'configured' : 'not configured',
      self_improving_generator: process.env.SELF_IMPROVING_GENERATOR_URL ? 'configured' : 'not configured',
      ai_mockup: process.env.AI_MOCKUP_URL ? 'configured' : 'not configured'
    },
    websocket: 'enabled'
  });
});

// Service health monitoring routes
app.use('/health', healthRouter.router);

// Auth service health check endpoint
app.get('/api/auth/health', async (req, res) => {
  const authServiceUrl = serviceTargets.USER_AUTH_URL;
  const targetUrl = `${authServiceUrl}/health`;
  
  try {
    console.log(`🔍 [AUTH HEALTH] Checking: ${targetUrl}`);
    const response = await axios.get(targetUrl, { timeout: 5000 });
    res.json({
      success: true,
      auth_service: 'healthy',
      target_url: targetUrl,
      response: response.data
    });
  } catch (error) {
    console.error(`❌ [AUTH HEALTH] Error:`, error.message);
    res.status(502).json({
      success: false,
      auth_service: 'unhealthy',
      target_url: targetUrl,
      error: error.message,
      code: error.code
    });
  }
});

// WebSocket connection handling
const websocketHandlers = websocketAuth(io);

// Auth Service - Fixed proxy with proper connection handling
console.log('🔧 Registering /api/auth proxy route...');
app.use('/api/auth', (req, res, next) => {
  const authServiceUrl = serviceTargets.USER_AUTH_URL;
  const targetUrl = `${authServiceUrl}${req.originalUrl}`;
  console.log(`🔥 [AUTH PROXY] ${req.method} ${req.originalUrl} → ${targetUrl}`);
  console.log(`🔍 [AUTH PROXY] Service URL: ${authServiceUrl}`);
  console.log(`🔍 [AUTH PROXY] Full target: ${targetUrl}`);
  
  // Set response timeout to prevent hanging
  res.setTimeout(15000, () => {
    console.error('❌ [AUTH PROXY] Response timeout');
    if (!res.headersSent) {
      res.status(504).json({ error: 'Gateway timeout', service: 'user-auth' });
    }
  });

  const options = {
    method: req.method,
    url: targetUrl,
    headers: {
      'Content-Type': 'application/json',
      'User-Agent': 'API-Gateway/1.0',
      'Connection': 'keep-alive',
      // Forward Authorization header so protected auth-admin routes work
      'Authorization': req.headers.authorization,
      // Forward all relevant headers
      'X-Forwarded-For': req.ip,
      'X-Forwarded-Proto': req.protocol,
      'X-Forwarded-Host': req.get('host')
    },
    timeout: 10000,
    validateStatus: () => true,
    maxRedirects: 0
  };

  // Always include request body for POST/PUT/PATCH requests
  if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
    options.data = req.body || {};
    console.log(`📦 [AUTH PROXY] Request body:`, JSON.stringify(req.body));
  }

  console.log(`🚀 [AUTH PROXY] Making request to: ${targetUrl}`);
  axios(options)
    .then(response => {
      console.log(`✅ [AUTH PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
      console.log(`📊 [AUTH PROXY] Response headers:`, response.headers);
      if (!res.headersSent) {
        // Forward response headers except CORS; gateway controls CORS
        Object.keys(response.headers).forEach(key => {
          const k = key.toLowerCase();
          if (k === 'content-encoding' || k === 'transfer-encoding') return;
          if (k.startsWith('access-control-')) return; // strip downstream CORS
          res.setHeader(key, response.headers[key]);
        });
        // Set gateway CORS headers explicitly (support credentials)
        const origin = req.headers.origin || '*';
        res.removeHeader('Access-Control-Allow-Origin');
        res.removeHeader('access-control-allow-origin');
        res.setHeader('Access-Control-Allow-Origin', origin);
        res.setHeader('Vary', 'Origin');
        res.setHeader('Access-Control-Allow-Credentials', 'true');
        res.setHeader('Access-Control-Expose-Headers', 'Content-Length, X-Total-Count, X-Gateway-Request-ID, X-Gateway-Timestamp, X-Forwarded-By, X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host');
        res.status(response.status).json(response.data);
      }
    })
    .catch(error => {
      console.error(`❌ [AUTH PROXY ERROR]:`, error.message);
      console.error(`❌ [AUTH PROXY ERROR CODE]:`, error.code);
      console.error(`❌ [AUTH PROXY ERROR STACK]:`, error.stack);
      if (!res.headersSent) {
        if (error.response) {
          console.log(`📊 [AUTH PROXY] Error response status: ${error.response.status}`);
          console.log(`📊 [AUTH PROXY] Error response data:`, error.response.data);
          res.status(error.response.status).json(error.response.data);
        } else {
          res.status(502).json({ 
            error: 'Auth service unavailable', 
            message: error.code || error.message,
            service: 'user-auth',
            target_url: targetUrl,
            details: process.env.NODE_ENV === 'development' ? error.stack : undefined
          });
        }
      }
    });
});

// WebSocket API routes for managing connections
app.use('/api/websocket', websocketRouter);

// Apply rate limiting to other API routes
app.use('/api', createServiceLimiter(1000));

// Template Manager Service - Direct HTTP forwarding
console.log('🔧 Registering /api/templates proxy route...');
app.use('/api/templates', 
  createServiceLimiter(200),
  // Conditionally require auth: allow public GETs, require token for write ops
  (req, res, next) => {
    // Allow unauthenticated read operations
    if (req.method === 'GET') {
      return next();
    }
    // Allow unauthenticated POST to create a template at the root endpoint
    // Mounted path is /api/templates, so req.path === '/' for the root
    if (req.method === 'POST' && (req.path === '/' || req.originalUrl === '/api/templates')) {
      return next();
    }
    // For other write operations, require authentication and forward user context
    return authMiddleware.verifyToken(req, res, () => authMiddleware.forwardUserContext(req, res, next));
  },
  (req, res, next) => {
    const templateServiceUrl = serviceTargets.TEMPLATE_MANAGER_URL;
    console.log(`🔥 [TEMPLATE PROXY] ${req.method} ${req.originalUrl} → ${templateServiceUrl}${req.originalUrl}`);
    
    // Set response timeout to prevent hanging
    res.setTimeout(15000, () => {
      console.error('❌ [TEMPLATE PROXY] Response timeout');
      if (!res.headersSent) {
        res.status(504).json({ error: 'Gateway timeout', service: 'template-manager' });
      }
    });

    const options = {
      method: req.method,
      url: `${templateServiceUrl}${req.originalUrl}`,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        // Forward user context from auth middleware
        'X-User-ID': req.user?.id || req.user?.userId,
        'X-User-Role': req.user?.role,
        'Authorization': req.headers.authorization
      },
      timeout: 8000,
      validateStatus: () => true,
      maxRedirects: 0
    };

    // Always include request body for POST/PUT/PATCH requests
    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [TEMPLATE PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [TEMPLATE PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (!res.headersSent) {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [TEMPLATE PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            res.status(error.response.status).json(error.response.data);
          } else {
            res.status(502).json({ 
              error: 'Template service unavailable', 
              message: error.code || error.message,
              service: 'template-manager'
            });
          }
        }
      });
  }
);

// Admin endpoints (Template Manager) - expose /api/admin via gateway
console.log('🔧 Registering /api/admin proxy route...');
app.use('/api/admin', 
  createServiceLimiter(300),
  // Public proxy from gateway perspective; downstream service enforces JWT admin check
  (req, res, next) => {
    console.log(`🟠 [ADMIN PROXY] ${req.method} ${req.originalUrl}`);
    return next();
  },
  (req, res, next) => {
    const adminServiceUrl = serviceTargets.TEMPLATE_MANAGER_URL;
    const targetUrl = `${adminServiceUrl}${req.originalUrl}`;
    console.log(`🔥 [ADMIN PROXY] ${req.method} ${req.originalUrl} → ${targetUrl}`);

    res.setTimeout(15000, () => {
      console.error('❌ [ADMIN PROXY] Response timeout');
      if (!res.headersSent) {
        res.status(504).json({ error: 'Gateway timeout', service: 'template-manager(admin)' });
      }
    });

    const options = {
      method: req.method,
      url: targetUrl,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        // Forward Authorization header for admin JWT check
        'Authorization': req.headers.authorization
      },
      timeout: 8000,
      validateStatus: () => true,
      maxRedirects: 0
    };

    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [ADMIN PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [ADMIN PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (!res.headersSent) {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [ADMIN PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            res.status(error.response.status).json(error.response.data);
          } else {
            res.status(502).json({ 
              error: 'Admin endpoints unavailable', 
              message: error.code || error.message,
              service: 'template-manager(admin)'
            });
          }
        }
      });
  }
);

// AI Feature Analysis - Specific route for analyze-feature endpoint
console.log('🔧 Registering /api/ai/analyze-feature proxy route...');
app.use('/api/ai/analyze-feature',
  createServiceLimiter(300),
  // Allow unauthenticated access for AI analysis (public feature in builder)
  (req, res, next) => {
    console.log(`🤖 [AI ANALYSIS PROXY] ${req.method} ${req.originalUrl}`);
    console.log(`📦 [AI ANALYSIS PROXY] Request body type:`, typeof req.body);
    console.log(`📦 [AI ANALYSIS PROXY] Request body:`, JSON.stringify(req.body, null, 2));
    console.log(`📦 [AI ANALYSIS PROXY] Content-Type:`, req.headers['content-type']);
    return next();
  },
  (req, res, next) => {
    const templateManagerUrl = serviceTargets.TEMPLATE_MANAGER_URL;
    // Map /api/requirements/analyze-feature to /api/analyze-feature in template-manager
    const targetUrl = `${templateManagerUrl}/api/analyze-feature`;
    console.log(`🔥 [AI ANALYSIS PROXY] ${req.method} ${req.originalUrl} → ${targetUrl}`);

    res.setTimeout(30000, () => {
      console.error('❌ [AI ANALYSIS PROXY] Response timeout');
      if (!res.headersSent) {
            res.status(504).json({ error: 'Gateway timeout', service: 'template-manager' });
      }
    });

    const options = {
      method: req.method,
      url: targetUrl,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        'Authorization': req.headers.authorization,
        'X-User-ID': req.user?.id || req.user?.userId,
        'X-User-Role': req.user?.role,
      },
      timeout: 25000,
      validateStatus: () => true,
      maxRedirects: 0
    };

    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [AI ANALYSIS PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [AI ANALYSIS PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (!res.headersSent) {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [AI ANALYSIS PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            res.status(error.response.status).json(error.response.data);
          } else {
            res.status(502).json({
              error: 'AI analysis service unavailable',
              message: error.code || error.message,
              service: 'template-manager'
            });
          }
        }
      });
  }
);

// Requirement Processor Service - General routes (MUST come after specific routes)
app.use('/api/requirements', 
  createServiceLimiter(300),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.REQUIREMENT_PROCESSOR_URL, 'requirement-processor')
);

// Questions (Requirement Processor) - expose /api/questions via gateway
// Rewrites /api/questions/* -> /api/v1/* at the Requirement Processor
app.use('/api/questions',
  createServiceLimiter(300),
  // Allow unauthenticated access for generating questions (public step in builder)
  (req, res, next) => next(),
  serviceRouter.createServiceProxy(
    serviceTargets.REQUIREMENT_PROCESSOR_URL,
    'requirement-processor-questions',
    { pathRewrite: { '^/api/questions': '/api/v1' } }
  )
);

// Tech Stack Selector Service
app.use('/api/tech-stack', 
  createServiceLimiter(200),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.TECH_STACK_SELECTOR_URL, 'tech-stack-selector')
);

// Architecture Designer Service
app.use('/api/architecture', 
  createServiceLimiter(150),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.ARCHITECTURE_DESIGNER_URL, 'architecture-designer')
);

// Code Generator Service
app.use('/api/codegen', 
  createServiceLimiter(100),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.CODE_GENERATOR_URL, 'code-generator')
);

// Test Generator Service
app.use('/api/tests', 
  createServiceLimiter(150),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.TEST_GENERATOR_URL, 'test-generator')
);

// Deployment Manager Service
app.use('/api/deploy', 
  createServiceLimiter(100),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.DEPLOYMENT_MANAGER_URL, 'deployment-manager')
);

// Dashboard Service
app.use('/api/dashboard', 
  createServiceLimiter(300),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.DASHBOARD_URL, 'dashboard')
);

// Self-Improving Generator Service
app.use('/api/self-improving', 
  createServiceLimiter(50),
  authMiddleware.verifyToken,
  authMiddleware.forwardUserContext,
  serviceRouter.createServiceProxy(serviceTargets.SELF_IMPROVING_GENERATOR_URL, 'self-improving-generator')
);

// Features (Template Manager) - expose /api/features via gateway
console.log('🔧 Registering /api/features proxy route...');
app.use('/api/features',
  createServiceLimiter(300),
  // Public proxy: features endpoints do not require auth
  (req, res, next) => {
    console.log(`🟢 [FEATURES PROXY] Public access → ${req.method} ${req.originalUrl}`);
    return next();
  },
  (req, res, next) => {
    const templateServiceUrl = serviceTargets.TEMPLATE_MANAGER_URL;
    console.log(`🔥 [FEATURES PROXY] ${req.method} ${req.originalUrl} → ${templateServiceUrl}${req.originalUrl}`);

    res.setTimeout(15000, () => {
      console.error('❌ [FEATURES PROXY] Response timeout');
      if (!res.headersSent) {
        res.status(504).json({ error: 'Gateway timeout', service: 'template-manager' });
      }
    });

    const options = {
      method: req.method,
      url: `${templateServiceUrl}${req.originalUrl}`,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        'Authorization': req.headers.authorization,
        'X-User-ID': req.user?.id || req.user?.userId,
        'X-User-Role': req.user?.role,
      },
      timeout: 8000,
      validateStatus: () => true,
      maxRedirects: 0
    };

    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [FEATURES PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [FEATURES PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (!res.headersSent) {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [FEATURES PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            res.status(error.response.status).json(error.response.data);
          } else {
            res.status(502).json({
              error: 'Template feature service unavailable',
              message: error.code || error.message,
              service: 'template-manager'
            });
          }
        }
      });
  }
);

// Git Integration Service - Direct HTTP forwarding
console.log('🔧 Registering /api/github proxy route...');
app.use('/api/github',
  createServiceLimiter(200),
  // Conditionally require auth: allow public GETs, require token for write ops
  (req, res, next) => {
    // Allow unauthenticated access for read-only requests and specific public endpoints
    if (req.method === 'GET') {
      return next();
    }
    // Allowlist certain POST endpoints that must be public to initiate flows
    const url = req.originalUrl || '';
    const isPublicGithubEndpoint = (
      url.startsWith('/api/github/test-access') ||
      url.startsWith('/api/github/auth/github') ||
      url.startsWith('/api/github/auth/github/callback') ||
      url.startsWith('/api/github/auth/github/status')
    );
    if (isPublicGithubEndpoint) {
      return next();
    }
    return authMiddleware.verifyToken(req, res, () => authMiddleware.forwardUserContext(req, res, next));
  },
  (req, res, next) => {
    const gitServiceUrl = serviceTargets.GIT_INTEGRATION_URL;
    console.log(`🔥 [GIT PROXY] ${req.method} ${req.originalUrl} → ${gitServiceUrl}${req.originalUrl}`);
    
    // Set response timeout to prevent hanging
    res.setTimeout(15000, () => {
      console.error('❌ [GIT PROXY] Response timeout');
      if (!res.headersSent) {
        res.status(504).json({ error: 'Gateway timeout', service: 'git-integration' });
      }
    });

    const options = {
      method: req.method,
      url: `${gitServiceUrl}${req.originalUrl}`,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        // Forward user context from auth middleware
        'X-User-ID': req.user?.id || req.user?.userId,
        'X-User-Role': req.user?.role,
        'Authorization': req.headers.authorization
      },
      timeout: 8000,
      validateStatus: () => true,
      maxRedirects: 0
    };

    // Always include request body for POST/PUT/PATCH requests
    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [GIT PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [GIT PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (!res.headersSent) {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [GIT PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            res.status(error.response.status).json(error.response.data);
          } else {
            res.status(502).json({ 
              error: 'Git integration service unavailable', 
              message: error.code || error.message,
              service: 'git-integration'
            });
          }
        }
      });
  }
);

// AI Mockup Service - Direct HTTP forwarding
console.log('🔧 Registering /api/mockup proxy route...');
app.use('/api/mockup',
  createServiceLimiter(200),
  // Public proxy: AI mockup endpoints do not require auth for basic generation
  (req, res, next) => {
    console.log(`🎨 [AI MOCKUP PROXY] ${req.method} ${req.originalUrl}`);
    return next();
  },
  (req, res, next) => {
    const aiMockupServiceUrl = serviceTargets.AI_MOCKUP_URL;
    // Strip the /api/mockup prefix so /api/mockup/health -> /health at target
    const rewrittenPath = (req.originalUrl || '').replace(/^\/api\/mockup/, '');
    const targetUrl = `${aiMockupServiceUrl}${rewrittenPath}`;
    console.log(`🔥 [AI MOCKUP PROXY] ${req.method} ${req.originalUrl} → ${targetUrl}`);

    res.setTimeout(30000, () => {
      console.error('❌ [AI MOCKUP PROXY] Response timeout');
      if (!res.headersSent) {
        res.status(504).json({ error: 'Gateway timeout', service: 'ai-mockup' });
      }
    });

    const options = {
      method: req.method,
      url: targetUrl,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'API-Gateway/1.0',
        'Connection': 'keep-alive',
        'Authorization': req.headers.authorization,
        'X-User-ID': req.user?.id || req.user?.userId,
        'X-User-Role': req.user?.role,
      },
      timeout: 25000,
      validateStatus: () => true,
      maxRedirects: 0,
      responseType: 'text'
    };

    if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
      options.data = req.body || {};
      console.log(`📦 [AI MOCKUP PROXY] Request body:`, JSON.stringify(req.body));
    }

    axios(options)
      .then(response => {
        console.log(`✅ [AI MOCKUP PROXY] Response: ${response.status} for ${req.method} ${req.originalUrl}`);
        if (res.headersSent) return;
        const contentType = response.headers['content-type'] || '';
        // Forward key headers
        if (contentType) res.setHeader('Content-Type', contentType);
        res.setHeader('X-Gateway-Request-ID', req.requestId);
        res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
        res.setHeader('Access-Control-Allow-Credentials', 'true');

        // If response is SVG or XML or plain text, send as-is; else JSON
        if (contentType.includes('image/svg') || contentType.includes('xml') || contentType.includes('text/plain') || typeof response.data === 'string') {
          res.status(response.status).send(response.data);
        } else {
          res.status(response.status).json(response.data);
        }
      })
      .catch(error => {
        console.error(`❌ [AI MOCKUP PROXY ERROR]:`, error.message);
        if (!res.headersSent) {
          if (error.response) {
            const ct = error.response.headers?.['content-type'] || '';
            if (ct.includes('image/svg') || ct.includes('xml') || typeof error.response.data === 'string') {
              res.status(error.response.status).send(error.response.data);
            } else {
              res.status(error.response.status).json(error.response.data);
            }
          } else {
            res.status(502).json({
              error: 'AI Mockup service unavailable',
              message: error.code || error.message,
              service: 'ai-mockup'
            });
          }
        }
      });
  }
);

// Gateway management endpoints
app.get('/api/gateway/info', authMiddleware.verifyToken, (req, res) => {
  res.json({
    success: true,
    gateway: {
      name: 'CodeNuk API Gateway',
      version: process.env.npm_package_version || '1.0.0',
      environment: process.env.NODE_ENV || 'development',
      uptime: process.uptime()
    },
    services: {
      total_services: Object.keys(serviceTargets).length,
      operational_services: Object.keys(serviceTargets).length,
      service_urls: serviceTargets
    },
    features: {
      websocket_enabled: true,
      authentication: true,
      rate_limiting: true,
      health_monitoring: true,
      request_logging: true,
      cors_enabled: true
    },
    websocket: {
      connected_clients: io.engine.clientsCount,
      transport_types: ['websocket', 'polling']
    }
  });
});

// Service status endpoint
app.get('/api/gateway/services', authMiddleware.verifyToken, serviceHealthMiddleware.getServiceStatus);

// Root endpoint
app.get('/', (req, res) => {
  res.json({
    success: true,
    message: 'CodeNuk API Gateway',
    version: process.env.npm_package_version || '1.0.0',
    description: 'Central gateway for all CodeNuk microservices',
    documentation: {
      health: '/health',
      gateway_info: '/api/gateway/info',
      service_status: '/api/gateway/services'
    },
    services: {
      auth: '/api/auth',
      templates: '/api/templates',
      github: '/api/github',
      requirements: '/api/requirements',
      tech_stack: '/api/tech-stack',
      architecture: '/api/architecture',
      codegen: '/api/codegen',
      tests: '/api/tests',
      deploy: '/api/deploy',
      dashboard: '/api/dashboard',
      self_improving: '/api/self-improving',
      mockup: '/api/mockup'
    },
    websocket: {
      endpoint: '/socket.io/',
      authentication_required: true
    }
  });
});

// 404 handler
app.use('*', (req, res) => {
  res.status(404).json({
    success: false,
    message: 'Endpoint not found',
    available_services: {
      auth: '/api/auth',
      templates: '/api/templates',
      github: '/api/github',
      requirements: '/api/requirements',
      tech_stack: '/api/tech-stack',
      architecture: '/api/architecture',
      codegen: '/api/codegen',
      tests: '/api/tests',
      deploy: '/api/deploy',
      dashboard: '/api/dashboard',
      self_improving: '/api/self-improving',
      mockup: '/api/mockup'
    },
    documentation: '/api/gateway/info'
  });
});

// Global error handler
app.use((error, req, res, next) => {
  console.error(`[${req.requestId}] Gateway Error:`, error);
  
  // Handle proxy errors
  if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
    return res.status(503).json({
      success: false,
      message: 'Service temporarily unavailable',
      error: 'The requested service is currently unavailable',
      request_id: req.requestId
    });
  }

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

  // Handle authentication errors
  if (error.name === 'JsonWebTokenError' || error.name === 'TokenExpiredError') {
    return res.status(401).json({
      success: false,
      message: 'Authentication failed',
      error: error.message
    });
  }

  // Generic error handler
  res.status(error.status || 500).json({
    success: false,
    message: error.message || 'Internal gateway error',
    error: process.env.NODE_ENV === 'development' ? {
      stack: error.stack,
      name: error.name
    } : undefined,
    request_id: req.requestId
  });
});

// Start server and initialize health monitoring
const startServer = async () => {
  try {
    console.log('🚀 Starting CodeNuk API Gateway...');
    
    // Initialize service health monitoring
    await serviceHealthMiddleware.initializeHealthMonitoring();
    
    server.listen(PORT, '0.0.0.0', () => {
      console.log(`✅ API Gateway running on port ${PORT}`);
      console.log(`🌍 Environment: ${process.env.NODE_ENV || 'development'}`);
      console.log(`📋 Health check: http://localhost:${PORT}/health`);
      console.log(`📖 Gateway info: http://localhost:${PORT}/api/gateway/info`);
      console.log(`🔗 WebSocket enabled on: ws://localhost:${PORT}`);
      
      // Log service configuration
      console.log('⚙️  Configured Services:');
      Object.entries(serviceTargets).forEach(([name, url]) => {
        console.log(`   - ${name}: ${url}`);
      });
      
      console.log('🔧 Features:');
      console.log(`   - Rate Limiting: Enabled`);
      console.log(`   - Authentication: JWT with Auth Service`);
      console.log(`   - WebSocket: Real-time notifications`);
      console.log(`   - Health Monitoring: All services`);
      console.log(`   - Request Logging: Enabled`);
    });

  } catch (error) {
    console.error('❌ Failed to start API Gateway:', error);
    process.exit(1);
  }
};

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('📴 SIGTERM received, shutting down gracefully...');
  server.close(() => {
    console.log('✅ API Gateway shut down successfully');
    process.exit(0);
  });
});

process.on('SIGINT', () => {
  console.log('📴 SIGINT received, shutting down gracefully...');
  server.close(() => {
    console.log('✅ API Gateway shut down successfully');
    process.exit(0);
  });
});

// Start the server
startServer();

module.exports = app;