const require_rolldown_runtime = require('../_virtual/rolldown_runtime.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_project_service = require('../services/project.service.cjs');
const require_utils_permissions = require('../utils/permissions.cjs');
const require_services_user_service = require('../services/user.service.cjs');
const require_models_session_model = require('../models/session.model.cjs');
const require_utils_plan = require('../utils/plan.cjs');
const require_utils_filtersAndPagination_getProjectFiltersAndPagination = require('../utils/filtersAndPagination/getProjectFiltersAndPagination.cjs');
const require_utils_mapper_project = require('../utils/mapper/project.cjs');
let express_intlayer = require("express-intlayer");
express_intlayer = require_rolldown_runtime.__toESM(express_intlayer);

//#region src/controllers/project.controller.ts
/**
* Retrieves a list of projects based on filters and pagination.
*/
const getProjects = async (req, res, _next) => {
	const { user, organization, roles } = res.locals;
	const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = require_utils_filtersAndPagination_getProjectFiltersAndPagination.getProjectFiltersAndPagination(req, res);
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!organization && !roles.includes("admin")) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	try {
		const projects = await require_services_project_service.findProjects(filters, skip, pageSize, sortOptions);
		if (!require_utils_permissions.hasPermission(roles, "project:read")({
			...res.locals,
			targetProjects: projects
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const totalItems = await require_services_project_service.countProjects(filters);
		const responseData = require_utils_responseData.formatPaginatedResponse({
			data: require_utils_mapper_project.mapProjectsToAPI(projects),
			page,
			pageSize,
			totalPages: getNumberOfPages(totalItems),
			totalItems
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Adds a new project to the database.
*/
const addProject = async (req, res, _next) => {
	const { organization, user, roles } = res.locals;
	const projectData = req.body;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (!projectData) require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
	if (!require_utils_permissions.hasPermission(roles, "organization:admin")({
		...res.locals,
		targetOrganizations: [organization]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	const { plan } = organization;
	const planType = require_utils_plan.getPlanDetails(plan);
	if (planType.numberOfProjects) {
		if (await require_services_project_service.countProjects({ organizationId: organization.id }) >= planType.numberOfProjects) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PLAN_PROJECT_LIMIT_REACHED", { organizationId: organization.id });
			return;
		}
	}
	const project = {
		membersIds: [user.id],
		adminsIds: [user.id],
		creatorId: user.id,
		organizationId: organization.id,
		...projectData
	};
	try {
		const formattedProject = require_utils_mapper_project.mapProjectToAPI(await require_services_project_service.createProject(project));
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project created successfully",
				fr: "Projet créé avec succès",
				es: "Proyecto creado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project has been created successfully",
				fr: "Votre projet a été créé avec succès",
				es: "Su proyecto ha sido creado con éxito"
			}),
			data: formattedProject
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Updates an existing project in the database.
*/
const updateProject = async (req, res, _next) => {
	const { organization, project, user, roles } = res.locals;
	const projectData = req.body;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_DATA_NOT_FOUND");
		return;
	}
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (String(project.organizationId) !== String(organization.id)) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_IN_ORGANIZATION");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "project:write")({
		...res.locals,
		targetProjectIds: [String(project.id)]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const formattedProject = require_utils_mapper_project.mapProjectToAPI(await require_services_project_service.updateProjectById(project.id, projectData));
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project updated successfully",
				fr: "Projet mis à jour avec succès",
				es: "Proyecto actualizado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project has been updated successfully",
				fr: "Votre projet a été mis à jour avec succès",
				es: "Su proyecto ha sido actualizado con éxito"
			}),
			data: formattedProject
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Update members to the dictionary in the database.
*/
const updateProjectMembers = async (req, res, _next) => {
	const { user, project, organization, roles } = res.locals;
	const { membersIds } = req.body;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (membersIds?.length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_MUST_HAVE_MEMBER");
		return;
	}
	if (membersIds?.map((el) => el.isAdmin)?.length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_MUST_HAVE_ADMIN");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "project:write")({
		...res.locals,
		targetProjectIds: [String(project.id)]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const existingUsers = [];
		if (membersIds) {
			const userIdList = membersIds?.filter((member) => !organization?.membersIds.includes(member.userId)).map((member) => member.userId);
			const users = await require_services_user_service.getUsersByIds(userIdList);
			if (users) {
				const userMap = users.map((user$1) => ({
					user: user$1,
					isAdmin: membersIds.find((member) => String(member.userId) === String(user$1.id))?.isAdmin ?? false
				}));
				existingUsers.push(...userMap);
			}
		}
		const formattedMembers = existingUsers.map((user$1) => user$1.user.id);
		const formattedAdmin = existingUsers.filter((el) => el.isAdmin).map((user$1) => user$1.user.id);
		const formattedProject = require_utils_mapper_project.mapProjectToAPI(await require_services_project_service.updateProjectById(project.id, {
			...project,
			membersIds: formattedMembers,
			adminsIds: formattedAdmin
		}));
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project members updated successfully",
				fr: "Membres du projet mis à jour avec succès",
				es: "Miembros del proyecto actualizados con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project members have been updated successfully",
				fr: "Les membres de votre projet ont été mis à jour avec succès",
				es: "Los miembros de su proyecto han sido actualizados con éxito"
			}),
			data: formattedProject
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Pushes a project configuration to the database.
* @param req - Express request object.
* @param  res - Express response object.
* @returns Response confirming the deletion.
*/
const pushProjectConfiguration = async (req, res, _next) => {
	const { user, project, roles } = res.locals;
	const projectConfiguration = req.body;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "project:write")({
		...res.locals,
		targetProjectIds: [String(project.id)]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const projectObject = await require_services_project_service.getProjectById(project.id);
		projectObject.configuration = projectConfiguration;
		projectObject.save();
		if (!projectObject.configuration) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_UPDATE_FAILED", { projectId: project.id });
			return;
		}
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project configuration updated successfully",
				fr: "Configuration du projet mise à jour avec succès",
				es: "Configuración del proyecto actualizada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project configuration has been updated successfully",
				fr: "La configuration du projet a été mise à jour avec succès",
				es: "Su configuración del proyecto ha sido actualizada con éxito"
			}),
			data: projectObject.configuration
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Deletes a project from the database by its ID.
* @param req - Express request object.
* @param  res - Express response object.
* @returns Response confirming the deletion.
*/
const deleteProject = async (_req, res, _next) => {
	const { user, organization, project, session, roles } = res.locals;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (!project) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED");
		return;
	}
	if (typeof session === "undefined") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "project:admin")({
		...res.locals,
		targetProjectIds: [String(project.id)]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const projectToDelete = await require_services_project_service.getProjectById(project.id);
		if (String(projectToDelete.organizationId) !== String(organization.id)) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_IN_ORGANIZATION");
			return;
		}
		const deletedProject = await require_services_project_service.deleteProjectById(project.id);
		if (!deletedProject) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_NOT_DEFINED", { projectId: project.id });
			return;
		}
		require_logger_index.logger.info(`Project deleted: ${String(deletedProject.id)}`);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project deleted successfully",
				fr: "Projet supprimé avec succès",
				es: "Proyecto eliminado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project has been deleted successfully",
				fr: "Votre projet a été supprimé avec succès",
				es: "Su proyecto ha sido eliminado con éxito"
			}),
			data: require_utils_mapper_project.mapProjectToAPI(deletedProject)
		});
		await require_models_session_model.SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: null } });
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Select a project.
*/
const selectProject = async (req, res, _next) => {
	const { projectId } = req.params;
	const { session } = res.locals;
	if (!projectId) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECT_ID_NOT_FOUND");
		return;
	}
	if (typeof session === "undefined") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
		return;
	}
	try {
		const project = await require_services_project_service.getProjectById(projectId);
		await require_models_session_model.SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: String(projectId) } });
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project selected successfully",
				fr: "Projet sélectionné avec succès",
				es: "Proyecto seleccionado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project has been selected successfully",
				fr: "Votre projet a été sélectionné avec succès",
				es: "Su proyecto ha sido seleccionado con éxito"
			}),
			data: require_utils_mapper_project.mapProjectToAPI(project)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Unselect a project.
*/
const unselectProject = async (_req, res, _next) => {
	const { session } = res.locals;
	if (typeof session === "undefined") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
		return;
	}
	try {
		await require_models_session_model.SessionModel.updateOne({ _id: session.id }, { $set: { activeProjectId: null } });
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Project unselected successfully",
				fr: "Projet désélectionné avec succès",
				es: "Proyecto deseleccionado con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your project has been unselected successfully",
				fr: "Votre projet a été désélectionné avec succès",
				es: "Su proyecto ha sido deseleccionado con éxito"
			}),
			data: null
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};

//#endregion
exports.addProject = addProject;
exports.deleteProject = deleteProject;
exports.getProjects = getProjects;
exports.pushProjectConfiguration = pushProjectConfiguration;
exports.selectProject = selectProject;
exports.unselectProject = unselectProject;
exports.updateProject = updateProject;
exports.updateProjectMembers = updateProjectMembers;
//# sourceMappingURL=project.controller.cjs.map