/**
 * Centralized error handling utility for API routes
 * 
 * Standard error format:
 * {
 *   error: 'ErrorType',
 *   message: 'Human-readable description',
 *   field: 'optional-field-name',
 *   code: 'machine-readable-code'
 * }
 */

class ApiError extends Error {
  constructor(code, message, status = 500, details = {}) {
    super(message);
    this.name = 'ApiError';
    this.code = code;
    this.status = status;
    this.details = details;
    
    // Extract field name from details if provided
    if (details.field) {
      this.field = details.field;
    }
  }
}

/**
 * Create a standardized validation error
 */
function ValidationError(message, field, code = 'VALIDATION_ERROR') {
  return new ApiError(code, message, 400, { field });
}

/**
 * Create a standardized authentication error
 */
function AuthError(message = 'Authentication required', code = 'AUTH_ERROR') {
  return new ApiError(code, message, 401);
}

/**
 * Create a standardized authorization error
 */
function ForbiddenError(message = 'Access denied', code = 'FORBIDDEN') {
  return new ApiError(code, message, 403);
}

/**
 * Create a standardized not found error
 */
function NotFoundError(message = 'Resource not found', code = 'NOT_FOUND') {
  return new ApiError(code, message, 404);
}

/**
 * Create a standardized conflict error
 */
function ConflictError(message = 'Resource conflict', code = 'CONFLICT') {
  return new ApiError(code, message, 409);
}

/**
 * Create a standardized rate limit error
 */
function RateLimitError(message = 'Too many requests', code = 'RATE_LIMITED') {
  return new ApiError(code, message, 429);
}

/**
 * Format an error for JSON response
 * This ensures consistent error format across all routes
 */
function formatError(err) {
  if (err instanceof ApiError) {
    const output = { 
      error: err.code,
      message: err.message,
    };
    if (err.field) output.field = err.field;
    return output;
  }
  
  // Fallback for non-standard errors (log internally, show safe message)
  const safeMessage = err.status === 500 
    ? 'Internal server error'
    : err.message || 'An error occurred';
  
  return {
    error: err.code || 'ERROR',
    message: safeMessage,
  };
}

/**
 * Express middleware to handle errors centrally
 */
function errorHandler(err, req, res, next) {
  const formatted = formatError(err);
  const status = err.status || (err instanceof ApiError ? 500 : 500);
  
  // Only log non-500 errors to avoid exposing sensitive info
  if (status !== 500) {
    console.error(`[error] ${formatted.error}: ${formatted.message}`);
  }
  
  if (!res.headersSent) {
    res.status(status).json(formatted);
  }
}

module.exports = {
  ApiError,
  ValidationError,
  AuthError,
  ForbiddenError,
  NotFoundError,
  ConflictError,
  RateLimitError,
  formatError,
  errorHandler,
};
