/**
 * Error Handler Utility
 * Sanitizes error messages and responses to prevent information disclosure
 */

import { sanitizeErrorMessage } from './timestamp-utils';

/**
 * Sanitizes error objects before sending to client
 * Removes server version, stack traces, and sensitive information
 */
export function sanitizeError(error: any): { message: string; code?: string } {
  if (!error) {
    return { message: 'An error occurred' };
  }

  // Get the error message
  let message = typeof error === 'string' ? error : error.message || 'An error occurred';

  // Remove server version patterns
  message = message.replace(/Apache\/[\d.]+/gi, '[SERVER_VERSION_REMOVED]');
  message = message.replace(/nginx\/[\d.]+/gi, '[SERVER_VERSION_REMOVED]');
  message = message.replace(/Node\.js\/v[\d.]+/gi, '[SERVER_VERSION_REMOVED]');
  message = message.replace(/Express\/[\d.]+/gi, '[SERVER_VERSION_REMOVED]');
  message = message.replace(/PHP\/[\d.]+/gi, '[SERVER_VERSION_REMOVED]');
  
  // Remove file paths that might expose server structure
  message = message.replace(/\/[a-zA-Z0-9_\-\/]+\.php/gi, '[FILE_PATH_REMOVED]');
  message = message.replace(/\/[a-zA-Z0-9_\-\/]+\.js/gi, '[FILE_PATH_REMOVED]');
  message = message.replace(/\/[a-zA-Z0-9_\-\/]+\.ts/gi, '[FILE_PATH_REMOVED]');
  
  // Remove IP addresses
  message = message.replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g, '[IP_ADDRESS_REMOVED]');
  
  // Sanitize timestamps
  message = sanitizeErrorMessage(message);

  // Remove stack traces in production
  if (process.env.NODE_ENV === 'production') {
    // Only return the first line of error message
    message = message.split('\n')[0];
  }

  // Determine error code if available
  const code = error.code || error.statusCode || undefined;

  return {
    message: message.substring(0, 200), // Limit message length
    code: code ? String(code) : undefined
  };
}

/**
 * Creates a safe error response for API endpoints
 */
export function createErrorResponse(error: any, statusCode: number = 500) {
  const sanitizedError = sanitizeError(error);
  
  return {
    success: false,
    error: {
      message: sanitizedError.message,
      code: sanitizedError.code || String(statusCode)
    },
    // Never include stack traces in production
    ...(process.env.NODE_ENV !== 'production' && error.stack ? { stack: error.stack } : {})
  };
}

/**
 * Logs error safely without exposing sensitive information
 */
export function logErrorSafely(error: any, context?: string) {
  if (process.env.NODE_ENV === 'development') {
    console.error(`[Error${context ? ` - ${context}` : ''}]:`, error);
  } else {
    // In production, log sanitized version
    const sanitized = sanitizeError(error);
    console.error(`[Error${context ? ` - ${context}` : ''}]: ${sanitized.message}`);
  }
}

/**
 * Middleware to catch and sanitize errors in API routes
 */
export function withErrorHandler(handler: any) {
  return async (req: any, res: any) => {
    try {
      return await handler(req, res);
    } catch (error) {
      logErrorSafely(error, req.url);
      const errorResponse = createErrorResponse(error);
      return res.status(500).json(errorResponse);
    }
  };
}
