const winston = require('winston');

// Configure Winston logger
const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  defaultMeta: { service: 'api-gateway' },
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.simple()
      )
    })
  ]
});

// Request logging middleware
const logRequest = (req, res, next) => {
  const startTime = Date.now();
  
  // Log incoming request
  logger.info('Incoming Request', {
    requestId: req.requestId,
    method: req.method,
    url: req.originalUrl,
    ip: req.ip,
    userAgent: req.get('User-Agent'),
    timestamp: new Date().toISOString(),
    headers: {
      authorization: req.headers.authorization ? '[REDACTED]' : undefined,
      'content-type': req.headers['content-type'],
      'x-forwarded-for': req.headers['x-forwarded-for']
    }
  });

  // Override res.end to log response
  const originalEnd = res.end;
  res.end = function(chunk, encoding) {
    const responseTime = Date.now() - startTime;
    
    // Log response
    logger.info('Response Sent', {
      requestId: req.requestId,
      method: req.method,
      url: req.originalUrl,
      statusCode: res.statusCode,
      responseTime: `${responseTime}ms`,
      timestamp: new Date().toISOString()
    });

    // Call original end method
    originalEnd.call(this, chunk, encoding);
  };

  next();
};

// Error logging middleware
const logError = (error, req, res, next) => {
  logger.error('Request Error', {
    requestId: req.requestId,
    method: req.method,
    url: req.originalUrl,
    error: error.message,
    stack: error.stack,
    timestamp: new Date().toISOString()
  });
  
  next(error);
};

// Service proxy logging
const logProxyRequest = (serviceName, targetUrl) => {
  return (proxyReq, req, res) => {
    logger.info('Proxy Request', {
      requestId: req.requestId,
      service: serviceName,
      method: req.method,
      originalUrl: req.originalUrl,
      targetUrl: targetUrl,
      timestamp: new Date().toISOString()
    });
  };
};

const logProxyResponse = (serviceName) => {
  return (proxyRes, req, res) => {
    logger.info('Proxy Response', {
      requestId: req.requestId,
      service: serviceName,
      method: req.method,
      originalUrl: req.originalUrl,
      statusCode: proxyRes.statusCode,
      timestamp: new Date().toISOString()
    });
  };
};

const logProxyError = (serviceName) => {
  return (err, req, res) => {
    logger.error('Proxy Error', {
      requestId: req.requestId,
      service: serviceName,
      method: req.method,
      originalUrl: req.originalUrl,
      error: err.message,
      timestamp: new Date().toISOString()
    });
  };
};

module.exports = {
  logger,
  logRequest,
  logError,
  logProxyRequest,
  logProxyResponse,
  logProxyError
};
