import { ensureMongoDocumentToObject } from "../utils/ensureMongoDocumentToObject.mjs";
import { GenericError } from "../utils/errors/ErrorsClass.mjs";
import { removeObjectKeys } from "../utils/removeObjectKeys.mjs";
import { validateProject } from "../utils/validation/validateProject.mjs";
import { ProjectModel } from "../models/project.model.mjs";

//#region src/services/project.service.ts
/**
* Finds projects 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 projects matching the filters.
*/
const findProjects = async (filters, skip = 0, limit = 100, sortOptions) => {
	let query = ProjectModel.find(filters).skip(skip).limit(limit);
	if (sortOptions && Object.keys(sortOptions).length > 0) query = query.sort(sortOptions);
	return await query;
};
/**
* Finds a project by its ID.
* @param projectId - The ID of the project to find.
* @returns The project matching the ID.
*/
const getProjectById = async (projectId) => {
	const project = await ProjectModel.findById(projectId);
	if (!project) throw new GenericError("PROJECT_NOT_DEFINED", { projectId });
	return project;
};
/**
* Counts the total number of projects that match the filters.
* @param filters - MongoDB filter query.
* @returns Total number of projects.
*/
const countProjects = async (filters) => {
	const result = await ProjectModel.countDocuments(filters);
	if (typeof result === "undefined") throw new GenericError("PROJECT_COUNT_FAILED", { filters });
	return result;
};
/**
* Creates a new project in the database.
* @param  project - The project data to create.
* @returns The created project.
*/
const createProject = async (project) => {
	if (project.oAuth2Access) project.oAuth2Access = void 0;
	const errors = await validateProject(project, ["name"]);
	if (Object.keys(errors).length > 0) throw new GenericError("PROJECT_INVALID_FIELDS", { errors });
	return await ProjectModel.create(project);
};
/**
* Updates an existing project in the database by its ID.
* @param projectId - The ID of the project to update.
* @param project - The updated project data.
* @returns The updated project.
*/
const updateProjectById = async (projectId, project) => {
	const projectToUpdate = removeObjectKeys(ensureMongoDocumentToObject(project), [
		"id",
		"oAuth2Access",
		"organizationId"
	]);
	const errors = validateProject(project, Object.keys(projectToUpdate));
	if (Object.keys(errors).length > 0) throw new GenericError("PROJECT_INVALID_FIELDS", {
		projectId,
		errors
	});
	if ((await ProjectModel.updateOne({ _id: projectId }, projectToUpdate)).matchedCount === 0) throw new GenericError("PROJECT_UPDATE_FAILED", { projectId });
	return await getProjectById(projectId);
};
/**
* Deletes a project from the database by its ID.
* @param projectId - The ID of the project to delete.
* @returns The result of the deletion operation.
*/
const deleteProjectById = async (projectId) => {
	const project = await ProjectModel.findByIdAndDelete(projectId);
	if (!project) throw new GenericError("PROJECT_NOT_DEFINED", { projectId });
	return project;
};

//#endregion
export { countProjects, createProject, deleteProjectById, findProjects, getProjectById, updateProjectById };
//# sourceMappingURL=project.service.mjs.map