-- name: CreateDesktopPublishJob :one
INSERT INTO desktop_publish_jobs (
    desktop_id,
    tenant_id,
    workspace_id,
    created_by_user_id,
    title,
    content_ref,
    scheduled_at,
    article_id,
    article_version_id
)
VALUES (
    sqlc.arg(desktop_id),
    sqlc.arg(tenant_id),
    sqlc.arg(workspace_id),
    sqlc.arg(created_by_user_id),
    sqlc.arg(title),
    sqlc.arg(content_ref),
    sqlc.narg(scheduled_at),
    sqlc.narg(article_id),
    sqlc.narg(article_version_id)
)
RETURNING *;

-- name: CreateDesktopTask :one
INSERT INTO desktop_tasks (
    desktop_id,
    job_id,
    tenant_id,
    workspace_id,
    target_account_id,
    target_client_id,
    platform_id,
    kind,
    payload,
    status,
    dedup_key
)
VALUES (
    sqlc.arg(desktop_id),
    sqlc.arg(job_id),
    sqlc.arg(tenant_id),
    sqlc.arg(workspace_id),
    sqlc.arg(target_account_id),
    sqlc.arg(target_client_id),
    sqlc.arg(platform_id),
    sqlc.arg(kind),
    sqlc.arg(payload),
    sqlc.arg(status),
    sqlc.narg(dedup_key)
)
RETURNING *;

-- name: GetDesktopTaskByDesktopID :one
SELECT *
FROM desktop_tasks
WHERE desktop_id = sqlc.arg(desktop_id)
  AND workspace_id = sqlc.arg(workspace_id)
LIMIT 1;

-- name: LeaseNextQueuedDesktopTask :one
WITH candidate AS (
    SELECT dt.desktop_id
    FROM desktop_tasks AS dt
    WHERE dt.target_client_id = sqlc.arg(client_id)
      AND dt.status = 'queued'
      AND (
        sqlc.narg(kind)::text IS NULL
        OR dt.kind = sqlc.narg(kind)::text
      )
      AND (
        dt.kind <> 'publish'
        OR dt.attempts < 3
      )
      AND (
        dt.kind <> 'publish'
        OR NOT EXISTS (
            SELECT 1
            FROM desktop_publish_jobs AS j
            WHERE j.desktop_id = dt.job_id
              AND j.status <> 'queued'
        )
      )
    ORDER BY dt.lane_weight DESC,
        dt.priority DESC,
        COALESCE(dt.enqueued_at, dt.created_at) ASC,
        dt.created_at ASC,
        dt.desktop_id ASC
    LIMIT 1
    FOR UPDATE OF dt SKIP LOCKED
)
UPDATE desktop_tasks AS t
SET active_attempt_id = sqlc.arg(attempt_id),
    lease_token_hash = sqlc.arg(lease_token_hash),
    lease_expires_at = now() + CASE WHEN t.kind = 'publish' THEN interval '3 minutes' ELSE interval '10 minutes' END,
    status = 'in_progress',
    attempts = t.attempts + 1,
    started_at = COALESCE(t.started_at, now()),
    updated_at = now()
FROM candidate
WHERE t.desktop_id = candidate.desktop_id
RETURNING t.*;

-- name: LeaseQueuedDesktopTaskByDesktopID :one
UPDATE desktop_tasks
SET active_attempt_id = sqlc.arg(attempt_id),
    lease_token_hash = sqlc.arg(lease_token_hash),
    lease_expires_at = now() + CASE WHEN kind = 'publish' THEN interval '3 minutes' ELSE interval '10 minutes' END,
    status = 'in_progress',
    attempts = attempts + 1,
    started_at = COALESCE(started_at, now()),
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND target_client_id = sqlc.arg(client_id)
  AND status = 'queued'
  AND (
    kind <> 'publish'
    OR attempts < 3
  )
RETURNING *;

-- name: ExtendDesktopTaskLease :one
UPDATE desktop_tasks
SET lease_expires_at = now() + CASE WHEN kind = 'publish' THEN interval '3 minutes' ELSE interval '10 minutes' END,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND lease_token_hash = sqlc.arg(lease_token_hash)
  AND status = 'in_progress'
RETURNING *;

-- name: CompleteDesktopTask :one
UPDATE desktop_tasks
SET status = sqlc.arg(status),
    result = sqlc.narg(result),
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND lease_token_hash = sqlc.arg(lease_token_hash)
  AND status = 'in_progress'
RETURNING *;

-- name: CancelDesktopTaskByLease :one
UPDATE desktop_tasks
SET status = 'aborted',
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND lease_token_hash = sqlc.arg(lease_token_hash)
  AND status = 'in_progress'
RETURNING *;

-- name: CancelDesktopTaskByClient :one
UPDATE desktop_tasks
SET status = 'aborted',
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND target_client_id = sqlc.arg(client_id)
  AND status = 'queued'
RETURNING *;

-- name: CancelQueuedPublishDesktopTaskByOwner :one
UPDATE desktop_tasks AS t
SET status = 'aborted',
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
FROM desktop_publish_jobs AS j
WHERE t.desktop_id = sqlc.arg(desktop_id)
  AND t.tenant_id = sqlc.arg(tenant_id)
  AND t.workspace_id = sqlc.arg(workspace_id)
  AND t.kind = 'publish'
  AND t.status = 'queued'
  AND j.desktop_id = t.job_id
  AND j.tenant_id = t.tenant_id
  AND j.workspace_id = t.workspace_id
  AND j.created_by_user_id = sqlc.arg(user_id)
RETURNING t.*;

-- name: TenantCancelDesktopTask :one
UPDATE desktop_tasks
SET status = 'aborted',
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND tenant_id = sqlc.arg(tenant_id)
  AND workspace_id = sqlc.arg(workspace_id)
  AND status = 'queued'
  AND EXISTS (
    SELECT 1
    FROM desktop_publish_jobs AS j
    WHERE j.desktop_id = desktop_tasks.job_id
      AND j.tenant_id = desktop_tasks.tenant_id
      AND j.workspace_id = desktop_tasks.workspace_id
      AND j.created_by_user_id = sqlc.arg(user_id)
  )
RETURNING *;

-- name: ReconcileDesktopTask :one
UPDATE desktop_tasks
SET status = CASE
        WHEN sqlc.arg(status)::text = 'retry' THEN 'queued'
        ELSE sqlc.arg(status)::text
    END,
    result = CASE
        WHEN sqlc.arg(status)::text = 'retry' THEN NULL
        ELSE sqlc.narg(result)
    END,
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    attempts = CASE WHEN sqlc.arg(status)::text = 'retry' THEN 0 ELSE attempts END,
    updated_at = now()
WHERE desktop_id = sqlc.arg(desktop_id)
  AND workspace_id = sqlc.arg(workspace_id)
  AND status = 'unknown'
RETURNING *;

-- name: MarkDesktopTasksUnknownByClient :execrows
UPDATE desktop_tasks
SET status = 'unknown',
    error = sqlc.narg(error),
    active_attempt_id = NULL,
    lease_token_hash = NULL,
    lease_expires_at = NULL,
    updated_at = now()
WHERE target_client_id = sqlc.arg(client_id)
  AND workspace_id = sqlc.arg(workspace_id)
  AND status = 'in_progress';

-- name: CreateDesktopTaskAttempt :one
INSERT INTO desktop_task_attempts (
    desktop_id,
    task_id,
    client_id,
    lease_token_hash
)
VALUES (
    sqlc.arg(desktop_id),
    sqlc.arg(task_id),
    sqlc.arg(client_id),
    sqlc.arg(lease_token_hash)
)
RETURNING *;

-- name: FinishDesktopTaskAttempt :exec
UPDATE desktop_task_attempts
SET ended_at = now(),
    final_status = sqlc.narg(final_status),
    error = sqlc.narg(error)
WHERE task_id = sqlc.arg(task_id)
  AND desktop_id = sqlc.arg(attempt_id);
