/**
 * Centralized Logging Service
 * Provides structured logging with different levels and contexts
 */

const LOG_LEVELS = {
  ERROR: 'ERROR',
  WARN: 'WARN',
  INFO: 'INFO',
  DEBUG: 'DEBUG',
};

class Logger {
  constructor() {
    this.level = process.env.LOG_LEVEL || 'INFO';
    this.enabledLevels = this.getEnabledLevels();
  }

  getEnabledLevels() {
    const levels = ['ERROR', 'WARN', 'INFO', 'DEBUG'];
    const currentIndex = levels.indexOf(this.level);
    return levels.slice(0, currentIndex + 1);
  }

  shouldLog(level) {
    return this.enabledLevels.includes(level);
  }

  formatMessage(level, message, meta = {}) {
    const timestamp = new Date().toISOString();
    const logObject = {
      timestamp,
      level,
      message,
      ...meta,
    };

    // In production, return JSON for log aggregation tools
    if (process.env.NODE_ENV === 'production') {
      return JSON.stringify(logObject);
    }

    // In development, return formatted string
    const metaStr = Object.keys(meta).length > 0 ? `\n${JSON.stringify(meta, null, 2)}` : '';
    return `[${timestamp}] ${level}: ${message}${metaStr}`;
  }

  error(message, error = null, meta = {}) {
    if (!this.shouldLog(LOG_LEVELS.ERROR)) return;

    const errorMeta = error ? {
      error: error.message,
      stack: error.stack,
      ...meta,
    } : meta;

    console.error(this.formatMessage(LOG_LEVELS.ERROR, message, errorMeta));
  }

  warn(message, meta = {}) {
    if (!this.shouldLog(LOG_LEVELS.WARN)) return;
    console.warn(this.formatMessage(LOG_LEVELS.WARN, message, meta));
  }

  info(message, meta = {}) {
    if (!this.shouldLog(LOG_LEVELS.INFO)) return;
    console.log(this.formatMessage(LOG_LEVELS.INFO, message, meta));
  }

  debug(message, meta = {}) {
    if (!this.shouldLog(LOG_LEVELS.DEBUG)) return;
    console.log(this.formatMessage(LOG_LEVELS.DEBUG, message, meta));
  }

  // Specialized logging methods
  http(method, path, statusCode, duration, meta = {}) {
    this.info(`HTTP ${method} ${path} ${statusCode}`, {
      method,
      path,
      statusCode,
      duration,
      ...meta,
    });
  }

  db(operation, collection, duration, meta = {}) {
    this.debug(`DB ${operation} on ${collection}`, {
      operation,
      collection,
      duration,
      ...meta,
    });
  }

  security(event, meta = {}) {
    this.warn(`SECURITY: ${event}`, meta);
  }
}

// Export singleton instance
module.exports = new Logger();
