const require_utils_errors_ErrorsClass = require('../utils/errors/ErrorsClass.cjs');
const require_utils_validation_validateTag = require('../utils/validation/validateTag.cjs');
const require_models_tag_model = require('../models/tag.model.cjs');

//#region src/services/tag.service.ts
/**
* Finds tags 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.
* @returns List of tags matching the filters.
*/
const findTags = async (filters, skip = 0, limit = 100, sortOptions) => {
	let query = require_models_tag_model.TagModel.find(filters).skip(skip).limit(limit);
	if (sortOptions && Object.keys(sortOptions).length > 0) query = query.sort(sortOptions);
	return await query;
};
/**
* Finds a tag by its ID.
* @param tagId - The ID of the tag to find.
* @returns The tag matching the ID.
*/
const getTagById = async (tagId) => {
	const tag = await require_models_tag_model.TagModel.findById(tagId);
	if (!tag) throw new require_utils_errors_ErrorsClass.GenericError("TAG_NOT_FOUND", { tagId });
	return tag;
};
const getTagsByKeys = async (keys, organizationId) => {
	return await require_models_tag_model.TagModel.find({
		key: { $in: keys },
		organizationId
	});
};
/**
* Counts the total number of tags that match the filters.
* @param filters - MongoDB filter query.
* @returns Total number of tags.
*/
const countTags = async (filters) => {
	const result = await require_models_tag_model.TagModel.countDocuments(filters);
	if (typeof result === "undefined") throw new require_utils_errors_ErrorsClass.GenericError("TAG_COUNT_FAILED", { filters });
	return result;
};
/**
* Creates a new tag in the database.
* @param  tag - The tag data to create.
* @returns The created tag.
*/
const createTag = async (tag) => {
	const errors = await require_utils_validation_validateTag.validateTag(tag, ["key"]);
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("TAG_INVALID_FIELDS", { errors });
	return await require_models_tag_model.TagModel.create(tag);
};
/**
* Updates an existing tag in the database by its ID.
* @param tagId - The ID of the tag to update.
* @param tag - The updated tag data.
* @returns The updated tag.
*/
const updateTagById = async (tagId, tag) => {
	const errors = require_utils_validation_validateTag.validateTag(tag, Object.keys(tag));
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("TAG_INVALID_FIELDS", {
		tagId,
		errors
	});
	if ((await require_models_tag_model.TagModel.updateOne({ _id: tagId }, tag)).matchedCount === 0) throw new require_utils_errors_ErrorsClass.GenericError("TAG_UPDATE_FAILED", { tagId });
	return await getTagById(tagId);
};
/**
* Deletes a tag from the database by its ID.
* @param tagId - The ID of the tag to delete.
* @returns The result of the deletion operation.
*/
const deleteTagById = async (tagId) => {
	const tag = await require_models_tag_model.TagModel.findByIdAndDelete(tagId);
	if (!tag) throw new require_utils_errors_ErrorsClass.GenericError("TAG_NOT_FOUND", { tagId });
	return tag;
};

//#endregion
exports.countTags = countTags;
exports.createTag = createTag;
exports.deleteTagById = deleteTagById;
exports.findTags = findTags;
exports.getTagById = getTagById;
exports.getTagsByKeys = getTagsByKeys;
exports.updateTagById = updateTagById;
//# sourceMappingURL=tag.service.cjs.map