/**
 * Custom error class for application errors
 */
class AppError extends Error {
    constructor(message, statusCode = 500, isOperational = true) {
        super(message);
        this.statusCode = statusCode;
        this.isOperational = isOperational;
        Error.captureStackTrace(this, this.constructor);
    }
}

/**
 * Global error handling middleware
 */
function errorHandler(err, req, res, next) {
    let { statusCode = 500, message } = err;

    // Log error for debugging
    if (process.env.NODE_ENV === 'development') {
        console.error('❌ Error:', err);
    }

    // Don't leak error details in production for operational errors
    if (process.env.NODE_ENV === 'production' && !err.isOperational) {
        message = 'Something went wrong';
    }

    // Prepare response
    const response = {
        status: 'error',
        message
    };

    // Add stack trace in development
    if (process.env.NODE_ENV === 'development') {
        response.stack = err.stack;
    }

    res.status(statusCode).json(response);
}

/**
 * Handle 404 errors
 */
function notFoundHandler(req, res, next) {
    res.status(404).json({
        status: 'error',
        message: 'Route not found'
    });
}

/**
 * Async wrapper to catch errors in async route handlers
 */
function asyncHandler(fn) {
    return (req, res, next) => {
        Promise.resolve(fn(req, res, next)).catch(next);
    };
}

module.exports = {
    AppError,
    errorHandler,
    notFoundHandler,
    asyncHandler
};
