import { projectMetadata } from "../../db/runtime/runtime-schema.js";
import { tenantScopedWhere } from "../manage/scope-helpers.js";
import { and, count, desc, eq, inArray } from "drizzle-orm";

//#region src/data-access/runtime/projects.ts
/**
* Get a project from the runtime DB by ID
*/
const getProjectMetadata = (db) => async (params) => {
	return await db.query.projectMetadata.findFirst({ where: and(tenantScopedWhere(projectMetadata, { tenantId: params.tenantId }), eq(projectMetadata.id, params.projectId)) }) ?? null;
};
/**
* List all runtimeProjects for a tenant from the runtime DB
*/
const listProjectsMetadata = (db) => async (params) => {
	return await db.query.projectMetadata.findMany({
		where: tenantScopedWhere(projectMetadata, { tenantId: params.tenantId }),
		orderBy: [desc(projectMetadata.createdAt)]
	});
};
/**
* List runtimeProjects with pagination from the runtime DB
* @param projectIds - Optional array of project IDs to filter by. If undefined, returns all projects.
*/
const listProjectsMetadataPaginated = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const conditions = [tenantScopedWhere(projectMetadata, { tenantId: params.tenantId })];
	if (params.projectIds !== void 0) {
		if (params.projectIds.length === 0) return {
			data: [],
			pagination: {
				page,
				limit,
				total: 0,
				pages: 0
			}
		};
		conditions.push(inArray(projectMetadata.id, params.projectIds));
	}
	const whereClause = and(...conditions);
	const [data, totalResult] = await Promise.all([db.select().from(projectMetadata).where(whereClause).limit(limit).offset(offset).orderBy(desc(projectMetadata.createdAt)), db.select({ count: count() }).from(projectMetadata).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	const totalNumber = typeof total === "string" ? Number.parseInt(total, 10) : total;
	return {
		data,
		pagination: {
			page,
			limit,
			total: totalNumber,
			pages: Math.ceil(totalNumber / limit)
		}
	};
};
/**
* Create a project in the runtime DB
*/
const createProjectMetadata = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [project] = await db.insert(projectMetadata).values({
		id: params.id,
		tenantId: params.tenantId,
		createdBy: params.createdBy ?? null,
		mainBranchName: params.mainBranchName,
		createdAt: now
	}).returning();
	return project;
};
/**
* Delete a project from the runtime DB
*/
const deleteProjectMetadata = (db) => async (params) => {
	return (await db.delete(projectMetadata).where(and(tenantScopedWhere(projectMetadata, { tenantId: params.tenantId }), eq(projectMetadata.id, params.projectId))).returning()).length > 0;
};
/**
* Check if a project exists in the runtime DB
*/
const projectsMetadataExists = (db) => async (params) => {
	return await getProjectMetadata(db)(params) !== null;
};
/**
* Count runtimeProjects for a tenant
*/
const countProjectsInRuntime = (db) => async (params) => {
	const total = (await db.select({ count: count() }).from(projectMetadata).where(tenantScopedWhere(projectMetadata, { tenantId: params.tenantId })))[0]?.count || 0;
	return typeof total === "string" ? Number.parseInt(total, 10) : total;
};

//#endregion
export { countProjectsInRuntime, createProjectMetadata, deleteProjectMetadata, getProjectMetadata, listProjectsMetadata, listProjectsMetadataPaginated, projectsMetadataExists };