import { logger } from "../logger/index.mjs";
import { formatPaginatedResponse, formatResponse } from "../utils/responseData.mjs";
import { ErrorHandler } from "../utils/errors/ErrorHandler.mjs";
import { countTags, createTag, deleteTagById, findTags, getTagById, updateTagById } from "../services/tag.service.mjs";
import { hasPermission } from "../utils/permissions.mjs";
import { getTagFiltersAndPagination } from "../utils/filtersAndPagination/getTagFiltersAndPagination.mjs";
import { mapTagToAPI, mapTagsToAPI } from "../utils/mapper/tag.mjs";
import { t } from "fastify-intlayer";

//#region src/controllers/tag.controller.ts
/**
* Retrieves a list of tags based on filters and pagination.
*/
const getTags = async (request, reply) => {
	const { user, organization, roles } = request.locals || {};
	const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getTagFiltersAndPagination(request);
	if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
	if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
	try {
		const tags = await findTags(filters, skip, pageSize, sortOptions);
		if (!hasPermission(roles || [], "tag:read")({
			...request.locals,
			targetTags: tags
		})) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
		const totalItems = await countTags(filters);
		const responseData = formatPaginatedResponse({
			data: mapTagsToAPI(tags),
			page,
			pageSize,
			totalPages: getNumberOfPages(totalItems),
			totalItems
		});
		return reply.send(responseData);
	} catch (error) {
		return ErrorHandler.handleAppErrorResponse(reply, error);
	}
};
/**
* Adds a new tag to the database.
*/
const addTag = async (request, reply) => {
	const { organization, project, user, roles } = request.locals || {};
	const tagData = request.body;
	if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
	if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
	if (!project) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_NOT_DEFINED");
	if (!tagData) return ErrorHandler.handleGenericErrorResponse(reply, "PROJECT_DATA_NOT_FOUND");
	const tag = {
		creatorId: user.id,
		organizationId: organization.id,
		projectId: project.id,
		...tagData
	};
	if (!hasPermission(roles || [], "tag:admin")({
		...request.locals,
		targetTags: [tag]
	})) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
	try {
		const formattedTag = mapTagToAPI(await createTag(tag));
		const responseData = formatResponse({
			message: t({
				en: "Tag created successfully",
				fr: "Tag créé avec succès",
				es: "Tag creado con éxito"
			}),
			description: t({
				en: "Your tag has been created successfully",
				fr: "Votre tag a été créé avec succès",
				es: "Su tag ha sido creado con éxito"
			}),
			data: formattedTag
		});
		return reply.send(responseData);
	} catch (error) {
		return ErrorHandler.handleAppErrorResponse(reply, error);
	}
};
/**
* Updates an existing tag in the database.
*/
const updateTag = async (request, reply) => {
	const { tagId } = request.params;
	const { organization, user, roles } = request.locals || {};
	if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
	if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
	try {
		const tag = {
			_id: tagId,
			name: request.body.name,
			key: request.body.key,
			description: request.body.description,
			instructions: request.body.instructions
		};
		const tagToDelete = await getTagById(tagId);
		if (!hasPermission(roles || [], "tag:write")({
			...request.locals,
			targetTags: [tagToDelete]
		})) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
		if (String(tagToDelete.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_IN_ORGANIZATION");
		const formattedTag = mapTagToAPI(await updateTagById(tag._id, tag));
		const responseData = formatResponse({
			message: t({
				en: "Tag updated successfully",
				fr: "Tag mis à jour avec succès",
				es: "Tag actualizado con éxito"
			}),
			description: t({
				en: "Your tag has been updated successfully",
				fr: "Votre tag a été mis à jour avec succès",
				es: "Su tag ha sido actualizado con éxito"
			}),
			data: formattedTag
		});
		return reply.send(responseData);
	} catch (error) {
		return ErrorHandler.handleAppErrorResponse(reply, error);
	}
};
/**
* Deletes a tag from the database by its ID.
*/
const deleteTag = async (request, reply) => {
	const { user, organization, roles } = request.locals || {};
	const { tagId } = request.params;
	if (!user) return ErrorHandler.handleGenericErrorResponse(reply, "USER_NOT_DEFINED");
	if (!organization) return ErrorHandler.handleGenericErrorResponse(reply, "ORGANIZATION_NOT_DEFINED");
	if (!tagId) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_ID_NOT_FOUND");
	try {
		const tagToDelete = await getTagById(tagId);
		if (!hasPermission(roles || [], "tag:admin")({
			...request.locals,
			targetTags: [tagToDelete]
		})) return ErrorHandler.handleGenericErrorResponse(reply, "PERMISSION_DENIED");
		if (String(tagToDelete.organizationId) !== String(organization.id)) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_IN_ORGANIZATION");
		const deletedTag = await deleteTagById(tagId);
		if (!deletedTag) return ErrorHandler.handleGenericErrorResponse(reply, "TAG_NOT_FOUND", { tagId });
		logger.info(`Tag deleted: ${String(deletedTag.id)}`);
		const formattedTag = mapTagToAPI(deletedTag);
		const responseData = formatResponse({
			message: t({
				en: "Tag deleted successfully",
				fr: "Tag supprimé avec succès",
				es: "Tag eliminado con éxito"
			}),
			description: t({
				en: "Your tag has been deleted successfully",
				fr: "Votre tag a été supprimé avec succès",
				es: "Su tag ha sido eliminado con éxito"
			}),
			data: formattedTag
		});
		return reply.send(responseData);
	} catch (error) {
		return ErrorHandler.handleAppErrorResponse(reply, error);
	}
};

//#endregion
export { addTag, deleteTag, getTags, updateTag };
//# sourceMappingURL=tag.controller.mjs.map