import { sql } from "kysely";
function applyScopeWhere(builder, scope) {
  let q = builder.where("entity_type", "=", scope.entityType);
  q = q.where(sql`organization_id is not distinct from ${scope.organizationId ?? null}`);
  q = q.where(sql`tenant_id is not distinct from ${scope.tenantId ?? null}`);
  q = q.where(sql`partition_index is not distinct from ${scope.partitionIndex ?? null}`);
  q = q.where(sql`partition_count is not distinct from ${scope.partitionCount ?? null}`);
  return q;
}
function isMissingConflictArbiterError(err) {
  const code = err?.code;
  if (code === "42P10") return true;
  const message = err?.message;
  return typeof message === "string" && /no unique or exclusion constraint matching the on conflict/i.test(message);
}
async function prepareJob(db, scope, status, options = {}) {
  const base = {
    organization_id: scope.organizationId ?? null,
    tenant_id: scope.tenantId ?? null,
    partition_index: scope.partitionIndex ?? null,
    partition_count: scope.partitionCount ?? null,
    status,
    started_at: sql`now()`,
    finished_at: null,
    heartbeat_at: sql`now()`,
    processed_count: 0,
    total_count: options.totalCount ?? null
  };
  try {
    const upserted = await db.insertInto("entity_index_jobs").values({ entity_type: scope.entityType, ...base }).onConflict((oc) => oc.expression(sql`
          "entity_type",
          coalesce("organization_id", '00000000-0000-0000-0000-000000000000'::uuid),
          coalesce("tenant_id", '00000000-0000-0000-0000-000000000000'::uuid),
          coalesce("partition_index", -1),
          coalesce("partition_count", -1)
        `).doUpdateSet({
      status,
      started_at: sql`now()`,
      finished_at: null,
      heartbeat_at: sql`now()`,
      processed_count: 0,
      total_count: options.totalCount ?? null
    })).returning(["id"]).execute();
    return upserted?.[0]?.id ?? null;
  } catch (err) {
    if (!isMissingConflictArbiterError(err)) throw err;
    return prepareJobLegacy(db, scope, base);
  }
}
async function prepareJobLegacy(db, scope, base) {
  const existing = await applyScopeWhere(
    db.selectFrom("entity_index_jobs").select(["id"]),
    scope
  ).executeTakeFirst();
  if (existing) {
    await applyScopeWhere(
      db.updateTable("entity_index_jobs").set(base),
      scope
    ).execute();
    return existing.id;
  }
  const inserted = await db.insertInto("entity_index_jobs").values({
    entity_type: scope.entityType,
    ...base
  }).returning(["id"]).execute();
  return inserted?.[0]?.id ?? null;
}
async function updateJobProgress(db, scope, processedDelta) {
  await applyScopeWhere(
    db.updateTable("entity_index_jobs").set({
      processed_count: sql`coalesce(processed_count, 0) + ${Math.max(0, processedDelta)}`,
      heartbeat_at: sql`now()`
    }),
    scope
  ).execute();
}
async function finalizeJob(db, scope) {
  await applyScopeWhere(
    db.updateTable("entity_index_jobs").set({
      finished_at: sql`now()`,
      heartbeat_at: sql`now()`
    }),
    scope
  ).execute();
}
export {
  finalizeJob,
  prepareJob,
  updateJobProgress
};
//# sourceMappingURL=jobs.js.map
