const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_utils_ensureMongoDocumentToObject = require('../utils/ensureMongoDocumentToObject.cjs');
const require_logger_index = require('../logger/index.cjs');
const require_utils_responseData = require('../utils/responseData.cjs');
const require_utils_errors_ErrorHandler = require('../utils/errors/ErrorHandler.cjs');
const require_services_dictionary_service = require('../services/dictionary.service.cjs');
const require_controllers_eventListener_controller = require('./eventListener.controller.cjs');
const require_utils_filtersAndPagination_getDictionaryFiltersAndPagination = require('../utils/filtersAndPagination/getDictionaryFiltersAndPagination.cjs');
const require_utils_mapper_dictionary = require('../utils/mapper/dictionary.cjs');
const require_utils_permissions = require('../utils/permissions.cjs');
let express_intlayer = require("express-intlayer");
express_intlayer = require_rolldown_runtime.__toESM(express_intlayer);

//#region src/controllers/dictionary.controller.ts
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const getDictionaries = async (req, res, _next) => {
	const { user, project, roles } = res.locals;
	const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = require_utils_filtersAndPagination_getDictionaryFiltersAndPagination.getDictionaryFiltersAndPagination(req, res);
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	try {
		const dictionaries = await require_services_dictionary_service.findDictionaries({
			...filters,
			projectIds: project.id
		}, skip, pageSize, sortOptions);
		if (!require_utils_permissions.hasPermission(roles, "dictionary:read")({
			...res.locals,
			targetDictionaries: dictionaries
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const totalItems = await require_services_dictionary_service.countDictionaries(filters);
		const responseData = require_utils_responseData.formatPaginatedResponse({
			data: dictionaries.map((el) => require_utils_mapper_dictionary.mapDictionaryToAPI(el)),
			page,
			pageSize,
			totalPages: getNumberOfPages(totalItems),
			totalItems
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries keys based on filters and pagination.
*/
const getDictionariesKeys = async (_req, res, _next) => {
	const { project, roles } = res.locals;
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	try {
		const dictionaries = await require_services_dictionary_service.findDictionaries({ projectIds: project.id });
		if (!require_utils_permissions.hasPermission(roles, "dictionary:read")({
			...res.locals,
			targetDictionaries: dictionaries
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const responseData = require_utils_responseData.formatResponse({ data: dictionaries.map((dictionary) => dictionary.key) });
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries keys based on filters and pagination.
*/
const getDictionariesUpdateTimestamp = async (_req, res, _next) => {
	const { project, roles } = res.locals;
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	try {
		const dictionaries = await require_services_dictionary_service.findDictionaries({ projectIds: project.id });
		if (!require_utils_permissions.hasPermission(roles, "dictionary:read")({
			...res.locals,
			targetDictionaries: dictionaries
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const responseData = require_utils_responseData.formatResponse({ data: dictionaries.reduce((acc, dictionary) => ({
			...acc,
			[dictionary.key]: new Date(dictionary.updatedAt).getTime()
		}), {}) });
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const getDictionaryByKey = async (req, res, _next) => {
	const { project, user, roles } = res.locals;
	const { dictionaryKey } = req.params;
	const version = req.query.version;
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	try {
		const dictionary = await require_services_dictionary_service.getDictionaryByKey(dictionaryKey, project.id);
		if (!require_utils_permissions.hasPermission(roles, "dictionary:read")({
			...res.locals,
			targetDictionaries: [dictionary]
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		if (!dictionary.projectIds.map(String).includes(String(project.id))) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
			return;
		}
		const responseData = require_utils_responseData.formatResponse({ data: require_utils_mapper_dictionary.mapDictionaryToAPI(dictionary, version) });
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Adds a new dictionary to the database.
*/
const addDictionary = async (req, res, _next) => {
	const { project, user, roles } = res.locals;
	const dictionaryData = req.body.dictionary;
	if (!dictionaryData) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_DATA_NOT_FOUND");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!dictionaryData.projectIds?.includes(String(project.id))) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
		return;
	}
	const dictionary = {
		key: dictionaryData.key,
		title: dictionaryData.title,
		description: dictionaryData.description,
		content: new Map([["v1", { content: dictionaryData.content ?? {} }]]),
		creatorId: user.id,
		projectIds: dictionaryData.projectIds ?? [String(project.id)]
	};
	if (!require_utils_permissions.hasPermission(roles, "dictionary:write")(res.locals)) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const newDictionary = await require_services_dictionary_service.createDictionary(dictionary);
		const apiResult = require_utils_mapper_dictionary.mapDictionaryToAPI(newDictionary);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Dictionary created successfully",
				fr: "Dictionnaire créé avec succès",
				es: "Diccionario creado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your dictionary has been created successfully",
				fr: "Votre dictionnaire a été créé avec succès",
				es: "Su diccionario ha sido creado con éxito"
			}),
			data: apiResult
		});
		res.json(responseData);
		require_controllers_eventListener_controller.sendDictionaryUpdate([{
			dictionary: require_utils_mapper_dictionary.mapDictionaryToAPI(newDictionary),
			status: "ADDED"
		}]);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Check each dictionaries, add the new ones and update the existing ones.
* @param req - Express request object.
* @param res - Express response object.
* @returns Response containing the created dictionary.
*/
const pushDictionaries = async (req, res, _next) => {
	const { project, user, roles } = res.locals;
	const dictionaryData = req.body.dictionaries;
	const dictionariesKeys = dictionaryData.map((dictionary) => dictionary.key);
	if (typeof dictionaryData === "object" && Array.isArray(dictionaryData) && dictionaryData.length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARIES_NOT_PROVIDED");
		return;
	} else if (!dictionaryData) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_DATA_NOT_FOUND");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "dictionary:write")(res.locals)) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const { existingDictionariesKey, newDictionariesKey } = await require_services_dictionary_service.getExistingDictionaryKey(dictionariesKeys, project.id);
		const existingDictionaries = dictionaryData.filter((dictionary) => existingDictionariesKey.includes(dictionary.key));
		const newDictionaries = dictionaryData.filter((dictionary) => newDictionariesKey.includes(dictionary.key));
		const newDictionariesResult = [];
		const updatedDictionariesResult = [];
		const errorResult = [];
		for (const dictionaryDataEl of newDictionaries) {
			const dictionary = {
				title: dictionaryDataEl.title,
				description: dictionaryDataEl.description,
				projectIds: [String(project.id)],
				creatorId: user.id,
				content: new Map([["v1", { content: dictionaryDataEl.content ?? {} }]]),
				key: dictionaryDataEl.key
			};
			try {
				const newDictionary = await require_services_dictionary_service.createDictionary(dictionary);
				newDictionariesResult.push(require_utils_mapper_dictionary.mapDictionaryToAPI(newDictionary));
			} catch (error) {
				require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
				return;
			}
		}
		if (existingDictionariesKey.length >= 0) {
			const existingDictionariesDB = await require_services_dictionary_service.getDictionariesByKeys(existingDictionariesKey, project.id);
			for (const dictionaryDataEl of existingDictionaries) {
				const existingDictionaryDB = existingDictionariesDB.find((dictionaryDB) => dictionaryDB.key === dictionaryDataEl.key);
				const versionList = [...existingDictionaryDB.content.keys() ?? []];
				const lastVersion = versionList[versionList.length - 1];
				const lastContent = existingDictionaryDB.content.get(lastVersion)?.content ?? null;
				const isSameContent = JSON.stringify(lastContent) === JSON.stringify(dictionaryDataEl.content);
				let newContent = existingDictionaryDB.content;
				if (!isSameContent) {
					const newContentVersion = require_services_dictionary_service.incrementVersion(existingDictionaryDB);
					existingDictionaryDB.content.set(newContentVersion, { content: dictionaryDataEl.content ?? {} });
					newContent = existingDictionaryDB.content;
				}
				const dictionary = {
					...require_utils_ensureMongoDocumentToObject.ensureMongoDocumentToObject(existingDictionaryDB),
					...dictionaryDataEl,
					content: newContent,
					projectIds: [String(project.id)],
					creatorId: user.id,
					key: dictionaryDataEl.key
				};
				try {
					const updatedDictionary = await require_services_dictionary_service.updateDictionaryByKey(dictionaryDataEl.key, dictionary, project.id);
					updatedDictionariesResult.push(require_utils_mapper_dictionary.mapDictionaryToAPI(updatedDictionary));
				} catch (error) {
					require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
					return;
				}
			}
		}
		const result = {
			newDictionaries: newDictionariesResult.map((dictionary) => dictionary.key),
			updatedDictionaries: updatedDictionariesResult.map((dictionary) => dictionary.key),
			error: errorResult
		};
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Dictionaries updated successfully",
				fr: "Dictionnaires mis à jour avec succès",
				es: "Diccionarios actualizados con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your dictionaries have been updated successfully",
				fr: "Vos dictionnaires ont été mis à jour avec succès",
				es: "Sus diccionarios han sido actualizados con éxito"
			}),
			data: result
		});
		require_controllers_eventListener_controller.sendDictionaryUpdate([...newDictionariesResult.map((dictionary) => ({
			dictionary,
			status: "ADDED"
		})), ...updatedDictionariesResult.map((dictionary) => ({
			dictionary,
			status: "UPDATED"
		}))]);
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Updates an existing dictionary in the database.
*/
const updateDictionary = async (req, res, _next) => {
	const { dictionaryId } = req.params;
	const { project, roles } = res.locals;
	const dictionaryData = req.body;
	if (!dictionaryData) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_DATA_NOT_FOUND");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!dictionaryData.projectIds?.includes(String(project.id))) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
		return;
	}
	if (typeof dictionaryId === "undefined") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_ID_NOT_FOUND");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "dictionary:write")(res.locals)) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const apiResult = require_utils_mapper_dictionary.mapDictionaryToAPI(await require_services_dictionary_service.updateDictionaryById(dictionaryId, dictionaryData));
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Dictionary updated successfully",
				fr: "Dictionnaire mis à jour avec succès",
				es: "Diccionario actualizado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your dictionary has been updated successfully",
				fr: "Votre dictionnaire a été mis à jour avec succès",
				es: "Su diccionario ha sido actualizado con éxito"
			}),
			data: apiResult
		});
		require_controllers_eventListener_controller.sendDictionaryUpdate([{
			dictionary: apiResult,
			status: "UPDATED"
		}]);
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Deletes a dictionary from the database by its ID.
*/
const deleteDictionary = async (req, res, _next) => {
	const { project, roles } = res.locals;
	const { dictionaryId } = req.params;
	if (!dictionaryId) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_ID_NOT_FOUND");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "dictionary:admin")(res.locals)) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		if (!(await require_services_dictionary_service.getDictionaryById(dictionaryId)).projectIds.includes(project.id)) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_PROJECT_MISMATCH");
			return;
		}
		const deletedDictionary = await require_services_dictionary_service.deleteDictionaryById(dictionaryId);
		if (!deletedDictionary) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "DICTIONARY_NOT_FOUND", { dictionaryId });
			return;
		}
		require_logger_index.logger.info(`Dictionary deleted: ${String(deletedDictionary.id)}`);
		const apiResult = require_utils_mapper_dictionary.mapDictionaryToAPI(deletedDictionary);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Dictionary deleted successfully",
				fr: "Dictionnaire supprimé avec succès",
				es: "Diccionario eliminado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your dictionary has been deleted successfully",
				fr: "Votre dictionnaire a été supprimé avec succès",
				es: "Su diccionario ha sido eliminado con éxito"
			}),
			data: apiResult
		});
		res.json(responseData);
		require_controllers_eventListener_controller.sendDictionaryUpdate([{
			dictionary: apiResult,
			status: "DELETED"
		}]);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};

//#endregion
exports.addDictionary = addDictionary;
exports.deleteDictionary = deleteDictionary;
exports.getDictionaries = getDictionaries;
exports.getDictionariesKeys = getDictionariesKeys;
exports.getDictionariesUpdateTimestamp = getDictionariesUpdateTimestamp;
exports.getDictionaryByKey = getDictionaryByKey;
exports.pushDictionaries = pushDictionaries;
exports.updateDictionary = updateDictionary;
//# sourceMappingURL=dictionary.controller.cjs.map