const require_utils_errors_ErrorsClass = require('../utils/errors/ErrorsClass.cjs');
const require_utils_validation_validateUser = require('../utils/validation/validateUser.cjs');
const require_models_user_model = require('../models/user.model.cjs');

//#region src/services/user.service.ts
/**
* Creates a new user with password in the database and hashes the password.
* @param user - User object with password not hashed.
* @returns Created user object.
*/
const createUser = async (user) => {
	const errors = require_utils_validation_validateUser.validateUser(user, ["email"]);
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("USER_INVALID_FIELDS", {
		userEmail: user.email,
		errors
	});
	const newUser = await require_models_user_model.UserModel.create(user);
	if (!newUser) throw new require_utils_errors_ErrorsClass.GenericError("USER_CREATION_FAILED", { userEmail: user.email });
	return newUser;
};
/**
* Retrieves a user by email.
* @param email - User's email.
* @returns User object or null if no user was found.
*/
const getUserByEmail = async (email) => {
	return await require_models_user_model.UserModel.findOne({ email });
};
/**
* Retrieves users list by email.
* @param emails - Users email.
* @returns User object or null if no user was found.
*/
const getUsersByEmails = async (emails) => {
	return await require_models_user_model.UserModel.find({ email: { $in: emails } });
};
/**
* Checks if a user exists by email.
* @param email - User's email.
* @returns True if the user exists, false otherwise.
*/
const checkUserExists = async (email) => {
	return await require_models_user_model.UserModel.exists({ email }) !== null;
};
/**
* Retrieves a user by ID.
* @param userId - User's ID.
* @returns User object or null if no user was found.
*/
const getUserById = async (userId) => await require_models_user_model.UserModel.findById(userId);
/**
* Retrieves a user by ID.
* @param userId - User's ID.
* @returns User object or null if no user was found.
*/
const getUsersByIds = async (userIds) => await require_models_user_model.UserModel.find({ _id: { $in: userIds } });
/**
* Finds users based on filters and pagination options.
* @param filters - MongoDB filter query.
* @param skip - Number of documents to skip.
* @param limit - Number of documents to limit.
* @param sortOptions - Sorting options.
* @returns List of users matching the filters.
*/
const findUsers = async (filters, skip, limit, sortOptions) => {
	let query = require_models_user_model.UserModel.find(filters).skip(skip).limit(limit);
	if (sortOptions && Object.keys(sortOptions).length > 0) query = query.sort(sortOptions);
	return await query;
};
/**
* Counts the total number of users that match the filters.
* @param filters - MongoDB filter query.
* @returns Total number of users.
*/
const countUsers = async (filters) => {
	const count = await require_models_user_model.UserModel.countDocuments(filters);
	if (typeof count === "undefined") throw new require_utils_errors_ErrorsClass.GenericError("USER_COUNT_FAILED");
	return count;
};
/**
* Updates a user's information.
* @param user - The user object.
* @param updates - The updates to apply to the user.
* @returns The updated user.
*/
const updateUserById = async (userId, updates) => {
	const errors = require_utils_validation_validateUser.validateUser(updates, Object.keys(updates));
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("USER_INVALID_FIELDS", {
		userId,
		errors
	});
	if ((await require_models_user_model.UserModel.updateOne({ _id: userId }, { $set: updates })).matchedCount === 0) throw new require_utils_errors_ErrorsClass.GenericError("USER_UPDATE_FAILED", { userId });
	const updatedUser = await require_models_user_model.UserModel.findById(userId);
	if (!updatedUser) throw new require_utils_errors_ErrorsClass.GenericError("USER_UPDATED_USER_NOT_FOUND", { userId });
	return updatedUser;
};
/**
* Deletes a user from the database.
* @param userId - The user object.
* @returns
*/
const deleteUser = async (userId) => {
	await getUserById(userId);
	const user = await require_models_user_model.UserModel.findByIdAndDelete(userId);
	if (!user) throw new require_utils_errors_ErrorsClass.GenericError("USER_NOT_FOUND", { userId });
	return user;
};

//#endregion
exports.checkUserExists = checkUserExists;
exports.countUsers = countUsers;
exports.createUser = createUser;
exports.deleteUser = deleteUser;
exports.findUsers = findUsers;
exports.getUserByEmail = getUserByEmail;
exports.getUserById = getUserById;
exports.getUsersByEmails = getUsersByEmails;
exports.getUsersByIds = getUsersByIds;
exports.updateUserById = updateUserById;
//# sourceMappingURL=user.service.cjs.map