import { eq, sql } from "drizzle-orm";
import { integer, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
//#region src/db-poll.ts
const jobsTable = pgTable("jobs", {
	id: uuid("id").primaryKey().defaultRandom(),
	type: text("type").notNull(),
	payload: jsonb("payload").notNull(),
	status: text("status").notNull().default("pending"),
	scheduledFor: timestamp("scheduled_for", { withTimezone: true }).notNull().defaultNow(),
	attempts: integer("attempts").notNull().default(0),
	maxAttempts: integer("max_attempts").notNull().default(5),
	lastError: text("last_error"),
	createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
	processedAt: timestamp("processed_at", { withTimezone: true }),
	failedAt: timestamp("failed_at", { withTimezone: true })
});
const schema = { jobs: jobsTable };
async function claim(db, opts) {
	const limit = opts.limit;
	return db.update(jobsTable).set({ status: "processing" }).where(sql`id IN (
      SELECT id FROM jobs
      WHERE status = 'pending' AND scheduled_for <= NOW()
      ORDER BY scheduled_for
      FOR UPDATE SKIP LOCKED
      LIMIT ${limit}
    )`).returning();
}
async function requeueAfterFailure(db, jobId, error) {
	const [row] = await db.select().from(jobsTable).where(eq(jobsTable.id, jobId)).limit(1);
	if (!row) return void 0;
	const nextAttempts = row.attempts + 1;
	if (nextAttempts >= row.maxAttempts) {
		const [failed] = await db.update(jobsTable).set({
			status: "failed",
			attempts: nextAttempts,
			lastError: error,
			failedAt: /* @__PURE__ */ new Date()
		}).where(eq(jobsTable.id, jobId)).returning();
		return failed;
	}
	const delayMinutes = 2 ** nextAttempts;
	const [requeued] = await db.update(jobsTable).set({
		status: "pending",
		attempts: nextAttempts,
		lastError: error,
		scheduledFor: sql`NOW() + (${delayMinutes} * INTERVAL '1 minute')`
	}).where(eq(jobsTable.id, jobId)).returning();
	return requeued;
}
async function markJobCompleted(db, jobId) {
	await db.update(jobsTable).set({
		status: "completed",
		processedAt: /* @__PURE__ */ new Date()
	}).where(eq(jobsTable.id, jobId));
}
//#endregion
export { claim, schema as jobsSchema, jobsTable, markJobCompleted, requeueAfterFailure };
