-- name: EnqueueJob :one
INSERT INTO jobs (id, type, payload, status, scheduled_at, attempts, max_attempts)
VALUES ($1, $2, $3, 'pending', $4, 0, $5)
RETURNING *;

-- name: LeaseNextJob :one
-- SKIP LOCKED 让多 worker 并行抢不冲突；只返回单行。
UPDATE jobs
   SET status='running',
       leased_at=now(),
       leased_by=$1,
       attempts=attempts+1,
       updated_at=now()
 WHERE id = (
   SELECT id FROM jobs
    WHERE status='pending' AND scheduled_at <= now()
    ORDER BY scheduled_at ASC
    FOR UPDATE SKIP LOCKED
    LIMIT 1
 )
RETURNING *;

-- name: CompleteJob :execrows
-- 围栏谓词：只有持有当前租约的 worker 才能写回，防止被 reaper 重新租出后旧 worker 覆盖新一轮状态。
UPDATE jobs
   SET status='completed', completed_at=now(),
       leased_at=NULL, leased_by=NULL, last_error=NULL,
       updated_at=now()
 WHERE id=$1 AND leased_by=$2 AND status='running';

-- name: FailJobWithRetry :execrows
-- 围栏谓词同上。
UPDATE jobs
   SET status='pending',
       scheduled_at=$2,
       leased_at=NULL, leased_by=NULL,
       last_error=$3,
       updated_at=now()
 WHERE id=$1 AND leased_by=$4 AND status='running';

-- name: DeadLetterJob :execrows
-- 围栏谓词同上。
UPDATE jobs
   SET status='dead', completed_at=now(),
       leased_at=NULL, leased_by=NULL, last_error=$2,
       updated_at=now()
 WHERE id=$1 AND leased_by=$3 AND status='running';

-- name: GetJob :one
SELECT * FROM jobs WHERE id=$1;

-- name: ReapStuckRunningJobs :many
-- 复位 worker 崩了卡 running 的任务。
UPDATE jobs
   SET status='pending', leased_at=NULL, leased_by=NULL, scheduled_at=now(),
       updated_at=now()
 WHERE status='running' AND leased_at < $1
RETURNING id;

-- name: PurgeCompletedJobs :execrows
DELETE FROM jobs
 WHERE status IN ('completed','dead') AND completed_at < $1;

-- name: ListDeadJobs :many
SELECT * FROM jobs
 WHERE status='dead' AND completed_at >= $1
 ORDER BY completed_at DESC
 LIMIT $2;
