const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_models_dictionary_model = require('../models/dictionary.model.cjs');
const require_utils_ensureMongoDocumentToObject = require('../utils/ensureMongoDocumentToObject.cjs');
const require_utils_errors_ErrorsClass = require('../utils/errors/ErrorsClass.cjs');
const require_utils_removeObjectKeys = require('../utils/removeObjectKeys.cjs');
const require_utils_validation_validateDictionary = require('../utils/validation/validateDictionary.cjs');
let mongoose = require("mongoose");

//#region src/services/dictionary.service.ts
/**
* Finds dictionaries 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 dictionaries matching the filters.
*/
const findDictionaries = async (filters, skip = 0, limit = 100, sortOptions) => {
	try {
		return (await require_models_dictionary_model.DictionaryModel.aggregate([
			{ $match: filters },
			...sortOptions && Object.keys(sortOptions).length > 0 ? [{ $sort: sortOptions }] : [],
			{ $skip: skip },
			{ $limit: limit }
		])).map((result) => new require_models_dictionary_model.DictionaryModel(result));
	} catch (error) {
		console.error("Error fetching dictionaries:", error);
		throw error;
	}
};
/**
* Finds a dictionary by its ID.
* @param dictionaryId - The ID of the dictionary to find.
* @returns The dictionary matching the ID.
*/
/**
* Finds a dictionary by its ID and includes the 'versions' field.
* @param dictionaryId - The ID of the dictionary to find.
* @returns The dictionary matching the ID with available versions.
*/
const getDictionaryById = async (dictionaryId) => {
	const id = mongoose.Types.ObjectId.isValid(dictionaryId) ? new mongoose.Types.ObjectId(dictionaryId) : dictionaryId;
	const dictionaries = await require_models_dictionary_model.DictionaryModel.aggregate([{ $match: { _id: id } }, { $addFields: { versions: { $map: {
		input: { $objectToArray: "$content" },
		as: "version",
		in: "$$version.k"
	} } } }]);
	if (!dictionaries.length) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_NOT_FOUND", { dictionaryId });
	return new require_models_dictionary_model.DictionaryModel(dictionaries[0]);
};
/**
* Finds a dictionary by its ID.
* @param dictionaryKey - The ID of the dictionary to find.
* @returns The dictionary matching the ID.
*/
const getDictionaryByKey = async (dictionaryKey, projectId) => {
	return (await getDictionariesByKeys([dictionaryKey], projectId))[0];
};
const getDictionariesByKeys = async (dictionaryKeys, projectId) => {
	const dictionaries = await require_models_dictionary_model.DictionaryModel.aggregate([{ $match: {
		key: { $in: dictionaryKeys },
		projectIds: projectId
	} }, { $addFields: { versions: { $map: {
		input: { $objectToArray: "$content" },
		as: "version",
		in: "$$version.k"
	} } } }]);
	if (!dictionaries) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_NOT_FOUND", {
		dictionaryKeys,
		projectId
	});
	return dictionaries.map((result) => new require_models_dictionary_model.DictionaryModel(result));
};
const getDictionariesByTags = async (tags, projectId) => {
	return (await require_models_dictionary_model.DictionaryModel.aggregate([{ $match: {
		tags: { $in: tags },
		projectIds: projectId
	} }, { $addFields: { versions: { $map: {
		input: { $objectToArray: "$content" },
		as: "version",
		in: "$$version.k"
	} } } }])).map((result) => new require_models_dictionary_model.DictionaryModel(result));
};
/**
* Counts the total number of dictionaries that match the filters.
* @param filters - MongoDB filter query.
* @returns Total number of dictionaries.
*/
const countDictionaries = async (filters) => {
	const result = await require_models_dictionary_model.DictionaryModel.countDocuments(filters);
	if (typeof result === "undefined") throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_COUNT_FAILED", { filters });
	return result;
};
/**
* Creates a new dictionary in the database.
* @param  dictionary - The dictionary data to create.
* @returns The created dictionary.
*/
const createDictionary = async (dictionary) => {
	const errors = await require_utils_validation_validateDictionary.validateDictionary(dictionary);
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_INVALID_FIELDS", { errors });
	return await require_models_dictionary_model.DictionaryModel.create(dictionary);
};
/**
* Gets the existing dictionaries from the provided list of keys.
* @param dictionariesKeys - List of dictionary keys to check.
* @param projectId - The ID of the project to check the dictionaries against.
* @returns The existing dictionaries and the new dictionaries.
*/
const getExistingDictionaryKey = async (dictionariesKeys, projectId) => {
	const existingDictionaries = await require_models_dictionary_model.DictionaryModel.find({
		key: { $in: dictionariesKeys },
		projectIds: projectId
	});
	const existingDictionariesKey = [];
	const newDictionariesKey = [];
	for (const key of dictionariesKeys) if (existingDictionaries.some((dictionary) => dictionary.key === key)) existingDictionariesKey.push(key);
	else newDictionariesKey.push(key);
	return {
		existingDictionariesKey,
		newDictionariesKey
	};
};
/**
* Updates an existing dictionary in the database by its ID.
* @param dictionaryId - The ID of the dictionary to update.
* @param dictionary - The updated dictionary data.
* @returns The updated dictionary.
*/
const updateDictionaryById = async (dictionaryId, dictionary) => {
	const dictionaryToUpdate = require_utils_removeObjectKeys.removeObjectKeys(require_utils_ensureMongoDocumentToObject.ensureMongoDocumentToObject(dictionary), ["id"]);
	const errors = await require_utils_validation_validateDictionary.validateDictionary(dictionaryToUpdate, Object.keys(dictionaryToUpdate));
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_INVALID_FIELDS", {
		dictionaryId,
		errors
	});
	if ((await require_models_dictionary_model.DictionaryModel.updateOne({ _id: dictionaryId }, dictionaryToUpdate)).matchedCount === 0) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_UPDATE_FAILED", { dictionaryId });
	return await getDictionaryById(dictionaryId);
};
/**
* Updates an existing dictionary in the database by its key.
* @param dictionaryKey - The ID of the dictionary to update.
* @param dictionary - The updated dictionary data.
* @returns The updated dictionary.
*/
const updateDictionaryByKey = async (dictionaryKey, dictionary, projectId) => {
	const dictionaryToUpdate = require_utils_removeObjectKeys.removeObjectKeys(require_utils_ensureMongoDocumentToObject.ensureMongoDocumentToObject(dictionary), ["id"]);
	const errors = await require_utils_validation_validateDictionary.validateDictionary(dictionaryToUpdate, Object.keys(dictionaryToUpdate));
	if (Object.keys(errors).length > 0) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_INVALID_FIELDS", {
		dictionaryKey,
		projectId,
		errors
	});
	if ((await require_models_dictionary_model.DictionaryModel.updateOne({
		key: dictionaryKey,
		projectIds: projectId
	}, dictionaryToUpdate)).matchedCount === 0) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_UPDATE_FAILED", { dictionaryKey });
	return await getDictionaryByKey(dictionaryKey, projectId);
};
/**
* Deletes a dictionary from the database by its ID.
* @param dictionaryId - The ID of the dictionary to delete.
* @returns The result of the deletion operation.
*/
const deleteDictionaryById = async (dictionaryId) => {
	const dictionary = await require_models_dictionary_model.DictionaryModel.findByIdAndDelete(dictionaryId);
	if (!dictionary) throw new require_utils_errors_ErrorsClass.GenericError("DICTIONARY_NOT_FOUND", { dictionaryId });
	return dictionary;
};
const getVersionNumber = (version) => {
	const match = version.match(/^v(\d+)$/);
	if (!match) throw new Error(`Invalid version format: ${version}`);
	return parseInt(match[1], 10);
};
const incrementVersion = (dictionary) => {
	const VERSION_PREFIX = "v";
	const versions = [...dictionary.content.keys() ?? []];
	const lastVersion = versions[versions.length - 1];
	let newNumber = getVersionNumber(lastVersion) + 1;
	let newVersion = `${VERSION_PREFIX}${newNumber}`;
	while (versions.includes(newVersion)) {
		newNumber += 1;
		newVersion = `${VERSION_PREFIX}${newNumber}`;
	}
	return newVersion;
};

//#endregion
exports.countDictionaries = countDictionaries;
exports.createDictionary = createDictionary;
exports.deleteDictionaryById = deleteDictionaryById;
exports.findDictionaries = findDictionaries;
exports.getDictionariesByKeys = getDictionariesByKeys;
exports.getDictionariesByTags = getDictionariesByTags;
exports.getDictionaryById = getDictionaryById;
exports.getDictionaryByKey = getDictionaryByKey;
exports.getExistingDictionaryKey = getExistingDictionaryKey;
exports.incrementVersion = incrementVersion;
exports.updateDictionaryById = updateDictionaryById;
exports.updateDictionaryByKey = updateDictionaryByKey;
//# sourceMappingURL=dictionary.service.cjs.map