//#region src/data-reconciliation/reconcile.ts
async function reconcile(registry, diffs, ctx) {
	const result = {
		applied: [],
		skipped: [],
		failed: []
	};
	const operations = diffs.map(async (diff) => {
		const handlers = registry[diff.table];
		if (!handlers) {
			result.skipped.push({
				table: diff.table,
				operation: diff.operation,
				primaryKey: diff.primaryKey,
				reason: "no registry entry"
			});
			return;
		}
		try {
			if (diff.operation === "insert" && handlers.onCreated && diff.after) await handlers.onCreated(diff.after, ctx);
			else if (diff.operation === "update" && handlers.onUpdated && diff.before && diff.after) await handlers.onUpdated(diff.before, diff.after, ctx);
			else if (diff.operation === "delete" && handlers.onDeleted && diff.before) await handlers.onDeleted(diff.before, ctx);
			else {
				result.skipped.push({
					table: diff.table,
					operation: diff.operation,
					primaryKey: diff.primaryKey,
					reason: `no handler for ${diff.operation}`
				});
				return;
			}
			result.applied.push({
				table: diff.table,
				operation: diff.operation,
				primaryKey: diff.primaryKey
			});
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : String(error);
			ctx.logger.error({
				table: diff.table,
				operation: diff.operation,
				primaryKey: diff.primaryKey,
				error: errorMessage
			}, `Reconcile effect failed for ${diff.table}.${diff.operation}`);
			result.failed.push({
				table: diff.table,
				operation: diff.operation,
				primaryKey: diff.primaryKey,
				error: errorMessage
			});
		}
	});
	await Promise.allSettled(operations);
	return result;
}

//#endregion
export { reconcile };