const fs = require('fs');
const path = require('path');

// Create logs directory if it doesn't exist
const logsDir = path.join(__dirname, '..', 'logs');
if (!fs.existsSync(logsDir)) {
  fs.mkdirSync(logsDir, { recursive: true });
}

// Logger utility
class Logger {
  static log(level, message, error = null) {
    const timestamp = new Date().toISOString();
    const logEntry = {
      timestamp,
      level,
      message,
      error: error ? {
        message: error.message,
        stack: error.stack,
        name: error.name
      } : null
    };

    // Console output
    const consoleMessage = `[${timestamp}] ${level.toUpperCase()}: ${message}`;
    if (level === 'error') {
      console.error(consoleMessage, error || '');
    } else if (level === 'warn') {
      console.warn(consoleMessage);
    } else {
      console.log(consoleMessage);
    }

    // File output
    const logFile = path.join(logsDir, `${level}.log`);
    const logLine = JSON.stringify(logEntry) + '\n';
    
    fs.appendFile(logFile, logLine, (err) => {
      if (err) console.error('Failed to write to log file:', err);
    });
  }

  static info(message) {
    this.log('info', message);
  }

  static warn(message) {
    this.log('warn', message);
  }

  static error(message, error = null) {
    this.log('error', message, error);
  }
}

// Global error handler middleware
const errorHandler = (err, req, res, next) => {
  Logger.error('Unhandled error occurred', err);

  // Don't leak error details in production
  const isDevelopment = process.env.NODE_ENV === 'development';
  
  const errorResponse = {
    success: false,
    message: isDevelopment ? err.message : 'Internal server error',
    ...(isDevelopment && { stack: err.stack })
  };

  // Set status code
  const statusCode = err.statusCode || err.status || 500;
  res.status(statusCode).json(errorResponse);
};

// 404 handler
const notFoundHandler = (req, res) => {
  Logger.warn(`404 - Route not found: ${req.method} ${req.originalUrl}`);
  res.status(404).json({
    success: false,
    message: 'Route not found'
  });
};

// Async error wrapper
const asyncHandler = (fn) => {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

// Socket error handler
const socketErrorHandler = (socket, error, context = '') => {
  Logger.error(`Socket error ${context}`, error);
  socket.emit('error', {
    message: 'An error occurred',
    context
  });
};

// Validation error creator
class ValidationError extends Error {
  constructor(message, field = null) {
    super(message);
    this.name = 'ValidationError';
    this.statusCode = 400;
    this.field = field;
  }
}

// Database error handler
const handleDatabaseError = (error, context = '') => {
  Logger.error(`Database error ${context}`, error);
  
  if (error.code === 'SQLITE_CONSTRAINT') {
    throw new ValidationError('Data constraint violation');
  }
  
  throw new Error('Database operation failed');
};

module.exports = {
  Logger,
  errorHandler,
  notFoundHandler,
  asyncHandler,
  socketErrorHandler,
  ValidationError,
  handleDatabaseError
};