/**
 * Utility untuk membuat error dengan format yang konsisten
 * Memudahkan developer membuat custom validation errors
 */

class AppError extends Error {
	constructor(message, options = {}) {
		super(message);
		this.name = options.name || 'AppError';
		this.statusCode = options.statusCode || 400;
		this.type = options.type || 'CUSTOM_ERROR';
		this.validation = options.validation || null;
		this.details = options.details || null;
		this.code = options.code || null;
	}
}

/**
 * Create validation error dengan field-specific errors
 * @param {Object} fieldErrors - Object dengan field sebagai key dan error message sebagai value
 * @param {string} message - Optional custom message
 * @returns {AppError}
 * 
 * @example
 * throw createValidationError({
 *   email: 'Email is required',
 *   password: 'Password must be at least 8 characters'
 * });
 */
function createValidationError(fieldErrors, message = 'Validation failed') {
	const error = new AppError(message, {
		name: 'ValidationError',
		statusCode: 400,
		type: 'VALIDATION_ERROR',
		validation: fieldErrors,
	});
	return error;
}

/**
 * Create not found error
 * @param {string} resource - Resource name (e.g., 'User', 'Item')
 * @param {string|number} id - Resource ID
 * @returns {AppError}
 * 
 * @example
 * throw createNotFoundError('User', userId);
 */
function createNotFoundError(resource, id = null) {
	const message = id 
		? `${resource} with ID ${id} not found`
		: `${resource} not found`;
	
	return new AppError(message, {
		name: 'NotFoundError',
		statusCode: 404,
		type: 'NOT_FOUND_ERROR',
	});
}

/**
 * Create unauthorized error
 * @param {string} message - Optional custom message
 * @returns {AppError}
 */
function createUnauthorizedError(message = 'Unauthorized access') {
	return new AppError(message, {
		name: 'UnauthorizedError',
		statusCode: 401,
		type: 'AUTHENTICATION_ERROR',
	});
}

/**
 * Create forbidden error
 * @param {string} message - Optional custom message
 * @returns {AppError}
 */
function createForbiddenError(message = 'Access forbidden') {
	return new AppError(message, {
		name: 'ForbiddenError',
		statusCode: 403,
		type: 'AUTHORIZATION_ERROR',
	});
}

/**
 * Create conflict error (e.g., duplicate entry)
 * @param {string} message - Error message
 * @param {Object} details - Optional details
 * @returns {AppError}
 */
function createConflictError(message = 'Resource conflict', details = null) {
	return new AppError(message, {
		name: 'ConflictError',
		statusCode: 409,
		type: 'CONFLICT_ERROR',
		details,
	});
}

/**
 * Create bad request error
 * @param {string} message - Error message
 * @param {Object} details - Optional details
 * @returns {AppError}
 */
function createBadRequestError(message = 'Bad request', details = null) {
	return new AppError(message, {
		name: 'BadRequestError',
		statusCode: 400,
		type: 'BAD_REQUEST_ERROR',
		details,
	});
}

/**
 * Create internal server error
 * @param {string} message - Error message
 * @param {Error} originalError - Optional original error
 * @returns {AppError}
 */
function createInternalError(message = 'Internal server error', originalError = null) {
	const error = new AppError(message, {
		name: 'InternalServerError',
		statusCode: 500,
		type: 'INTERNAL_ERROR',
	});
	
	if (originalError) {
		error.originalError = {
			name: originalError.name,
			message: originalError.message,
			stack: originalError.stack,
		};
	}
	
	return error;
}

module.exports = {
	AppError,
	createValidationError,
	createNotFoundError,
	createUnauthorizedError,
	createForbiddenError,
	createConflictError,
	createBadRequestError,
	createInternalError,
};
