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_organization_service = require('../services/organization.service.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_services_email_service = require('../services/email.service.cjs');
const require_utils_filtersAndPagination_getOrganizationFiltersAndPagination = require('../utils/filtersAndPagination/getOrganizationFiltersAndPagination.cjs');
const require_utils_mapper_organization = require('../utils/mapper/organization.cjs');
const require_utils_plan = require('../utils/plan.cjs');
let express_intlayer = require("express-intlayer");
express_intlayer = require_rolldown_runtime.__toESM(express_intlayer);
let stripe = require("stripe");
stripe = require_rolldown_runtime.__toESM(stripe);

//#region src/controllers/organization.controller.ts
/**
* Retrieves a list of organizations based on filters and pagination.
*/
const getOrganizations = async (req, res, _next) => {
	const { user, roles } = res.locals;
	const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = require_utils_filtersAndPagination_getOrganizationFiltersAndPagination.getOrganizationFiltersAndPagination(req, res);
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	try {
		const organizations = await require_services_organization_service.findOrganizations(filters, skip, pageSize, sortOptions);
		if (!require_utils_permissions.hasPermission(roles, "organization:read")({
			...res.locals,
			targetOrganizations: organizations
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const totalItems = await require_services_organization_service.countOrganizations(filters);
		const responseData = require_utils_responseData.formatPaginatedResponse({
			data: require_utils_mapper_organization.mapOrganizationsToAPI(organizations),
			page,
			pageSize,
			totalPages: getNumberOfPages(totalItems),
			totalItems
		});
		res.status(200).json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves an organization by its ID.
*/
const getOrganization = async (req, res, _next) => {
	const { roles } = res.locals;
	const { organizationId } = req.params;
	if (!organizationId) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_ID_NOT_FOUND");
		return;
	}
	try {
		const organization = await require_services_organization_service.getOrganizationById(organizationId);
		if (!require_utils_permissions.hasPermission(roles, "organization:read")({
			...res.locals,
			targetOrganizations: [organization]
		})) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const responseData = require_utils_responseData.formatResponse({ data: require_utils_mapper_organization.mapOrganizationToAPI(organization) });
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Adds a new organization to the database.
*/
const addOrganization = async (req, res, _next) => {
	const { user } = res.locals;
	const organization = req.body;
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_DATA_NOT_FOUND");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	try {
		const newOrganization = await require_services_organization_service.createOrganization(organization, user.id);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization created successfully",
				fr: "Organisation créée avec succès",
				es: "Organización creada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been created successfully",
				fr: "Votre organisation a été créée avec succès",
				es: "Su organización ha sido creada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(newOrganization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Updates an existing organization in the database.
*/
const updateOrganization = async (req, res, _next) => {
	const { organization, roles } = res.locals;
	const organizationFields = req.body;
	if (!organizationFields) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_DATA_NOT_FOUND");
		return;
	}
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "organization:write")({
		...res.locals,
		targetOrganizations: [organization]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		const updatedOrganization = await require_services_organization_service.updateOrganizationById(organization.id, organizationFields);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization updated successfully",
				fr: "Organisation mise à jour avec succès",
				es: "Organización actualizada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been updated successfully",
				fr: "Votre organisation a été mise à jour avec succès",
				es: "Su organización ha sido actualizada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(updatedOrganization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Add member to the organization in the database.
*/
const addOrganizationMember = async (req, res, _next) => {
	const { organization, user, roles } = res.locals;
	const { userEmail } = req.body;
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "organization:admin")({
		...res.locals,
		targetOrganizations: [organization]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	const planType = require_utils_plan.getPlanDetails(organization.plan);
	if (planType.numberOfOrganizationUsers && organization.membersIds.length >= planType.numberOfOrganizationUsers) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PLAN_USER_LIMIT_REACHED", { organizationId: organization.id });
		return;
	}
	try {
		let newMember = await require_services_user_service.getUserByEmail(userEmail);
		if (!newMember) {
			const newUser = await require_services_user_service.createUser({ email: userEmail });
			if (!newUser) {
				require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_CREATION_FAILED", { email: userEmail });
				return;
			}
			newMember = newUser;
		}
		const updatedOrganization = await require_services_organization_service.updateOrganizationById(organization.id, {
			...organization,
			membersIds: [...organization.membersIds, newMember.id]
		});
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization updated successfully",
				fr: "Organisation mise à jour avec succès",
				es: "Organización actualizada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been updated successfully",
				fr: "Votre organisation a été mise à jour avec succès",
				es: "Su organización ha sido actualizada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(updatedOrganization)
		});
		res.json(responseData);
		await require_services_email_service.sendEmail({
			type: "invite",
			to: userEmail,
			username: newMember.email.slice(0, newMember.email.indexOf("@")),
			invitedByUsername: user.name,
			invitedByEmail: user.email,
			organizationName: organization.name,
			inviteLink: `${process.env.CLIENT_URL}/auth/login?email=${newMember.email}`,
			inviteFromIp: req.ip ?? "",
			inviteFromLocation: req.hostname
		});
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Update members to the organization in the database.
*/
const updateOrganizationMembers = async (req, res, _next) => {
	const { organization, roles } = res.locals;
	const { membersIds, adminsIds } = req.body;
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "organization:admin")({
		...res.locals,
		targetOrganizations: [organization]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	if (!membersIds) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "INVALID_REQUEST_BODY");
		return;
	}
	if (membersIds?.length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_MUST_HAVE_MEMBER");
		return;
	}
	if (adminsIds?.filter((id) => membersIds?.includes(id)).length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_MUST_HAVE_ADMIN");
		return;
	}
	try {
		const existingUsers = await require_services_user_service.getUsersByIds(membersIds);
		if (!existingUsers) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
			return;
		}
		const existingAdmins = await require_services_user_service.getUsersByIds(adminsIds);
		if (!existingAdmins) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
			return;
		}
		const updatedOrganization = await require_services_organization_service.updateOrganizationById(organization.id, {
			membersIds: existingUsers.map((user) => user.id),
			adminsIds: existingAdmins.map((user) => user.id)
		});
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization updated successfully",
				fr: "Organisation mise à jour avec succès",
				es: "Organización actualizada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been updated successfully",
				fr: "Votre organisation a été mise à jour avec succès",
				es: "Su organización ha sido actualizada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(updatedOrganization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Admin-only: Update members of any organization by ID
*/
const updateOrganizationMembersById = async (req, res, _next) => {
	const { user } = res.locals;
	const { organizationId } = req.params;
	const { membersIds, adminsIds } = req.body;
	if (!user) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	if (user.role !== "admin") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	if (!membersIds) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "INVALID_REQUEST_BODY");
		return;
	}
	if (membersIds?.length === 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_MUST_HAVE_MEMBER");
		return;
	}
	try {
		const targetOrganization = await require_services_organization_service.getOrganizationById(organizationId);
		if (!targetOrganization) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_FOUND");
			return;
		}
		const existingUsers = await require_services_user_service.getUsersByIds(membersIds);
		if (!existingUsers) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_FOUND");
			return;
		}
		const finalAdminsIds = adminsIds && adminsIds.length > 0 ? adminsIds : targetOrganization.adminsIds;
		const existingAdmins = finalAdminsIds ? await require_services_user_service.getUsersByIds(finalAdminsIds) : [];
		if (!existingAdmins || existingAdmins.length === 0) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_MUST_HAVE_ADMIN");
			return;
		}
		const updatedOrganization = await require_services_organization_service.updateOrganizationById(targetOrganization.id, {
			membersIds: existingUsers.map((user$1) => user$1.id),
			adminsIds: existingAdmins.map((user$1) => user$1.id)
		});
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization members updated successfully",
				fr: "Membres de l'organisation mis à jour avec succès",
				es: "Miembros de la organización actualizados con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Organization members have been updated successfully",
				fr: "Les membres de l'organisation ont été mis à jour avec succès",
				es: "Los miembros de la organización han sido actualizados con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(updatedOrganization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Deletes an organization from the database by its ID.
*/
const deleteOrganization = async (_req, res, _next) => {
	const stripe$1 = new stripe.Stripe(process.env.STRIPE_SECRET_KEY);
	const { organization, roles } = res.locals;
	if (!organization) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_DEFINED");
		return;
	}
	if ((await require_services_project_service.findProjects({ organizationId: organization.id })).length > 0) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PROJECTS_EXIST", { organizationId: organization.id });
		return;
	}
	if (!require_utils_permissions.hasPermission(roles, "organization:admin")({
		...res.locals,
		targetOrganizations: [organization]
	})) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
		return;
	}
	try {
		if (organization.plan?.subscriptionId) await stripe$1.subscriptions.cancel(organization.plan.subscriptionId);
		const deletedOrganization = await require_services_organization_service.deleteOrganizationById(organization.id);
		if (!deletedOrganization) {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_NOT_FOUND", { organizationId: organization.id });
			return;
		}
		require_logger_index.logger.info(`Organization deleted: ${String(deletedOrganization.id)}`);
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization deleted successfully",
				fr: "Organisation supprimée avec succès",
				es: "Organización eliminada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been deleted successfully",
				fr: "Votre organisation a été supprimée avec succès",
				es: "Su organización ha sido eliminada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(deletedOrganization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Select an organization.
*/
const selectOrganization = async (req, res, _next) => {
	const { organizationId } = req.params;
	const { session } = res.locals;
	if (!organizationId) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "ORGANIZATION_ID_NOT_FOUND");
		return;
	}
	if (typeof session === "undefined") {
		require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
		return;
	}
	try {
		const organization = await require_services_organization_service.getOrganizationById(organizationId);
		await require_models_session_model.SessionModel.updateOne({ _id: session.id }, { $set: {
			activeOrganizationId: String(organization.id),
			activeProjectId: null
		} });
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization retrieved successfully",
				fr: "Organisation récupérée avec succès",
				es: "Organización recuperada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been retrieved successfully",
				fr: "Votre organisation a été récupérée avec succès",
				es: "Su organización ha sido recuperada con éxito"
			}),
			data: require_utils_mapper_organization.mapOrganizationToAPI(organization)
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Unselect an organization.
*/
const unselectOrganization = async (_req, res, _next) => {
	const { session } = res.locals;
	try {
		if (typeof session === "undefined") {
			require_utils_errors_ErrorHandler.ErrorHandler.handleGenericErrorResponse(res, "SESSION_NOT_DEFINED");
			return;
		}
		await require_models_session_model.SessionModel.updateOne({ _id: session.id }, { $set: {
			activeOrganizationId: null,
			activeProjectId: null
		} });
		const responseData = require_utils_responseData.formatResponse({
			message: (0, express_intlayer.t)({
				en: "Organization unselected successfully",
				fr: "Organisation désélectionnée avec succès",
				es: "Organización deseleccionada con éxito"
			}),
			description: (0, express_intlayer.t)({
				en: "Your organization has been unselected successfully",
				fr: "Votre organisation a été désélectionnée avec succès",
				es: "Su organización ha sido deseleccionada con éxito"
			}),
			data: null
		});
		res.json(responseData);
		return;
	} catch (error) {
		require_utils_errors_ErrorHandler.ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};

//#endregion
exports.addOrganization = addOrganization;
exports.addOrganizationMember = addOrganizationMember;
exports.deleteOrganization = deleteOrganization;
exports.getOrganization = getOrganization;
exports.getOrganizations = getOrganizations;
exports.selectOrganization = selectOrganization;
exports.unselectOrganization = unselectOrganization;
exports.updateOrganization = updateOrganization;
exports.updateOrganizationMembers = updateOrganizationMembers;
exports.updateOrganizationMembersById = updateOrganizationMembersById;
//# sourceMappingURL=organization.controller.cjs.map