import type { JobEnvelope, JobRegistry, DispatchOpts } from './index.js'
import type { QueueBatch } from './index.js'

/** CF `Queue` binding — structural subset used by this adapter. */
export type QueueBinding<T = unknown> = {
  send(message: T, options?: { contentType?: string; delaySeconds?: number }): Promise<void>
}

/** Name → binding map for many named queues. */
export type QueueBindings = Record<string, QueueBinding>

export async function enqueue<T>(queue: QueueBinding<T>, body: T): Promise<void> {
  await queue.send(body)
}

export function resolveQueue(bindings: QueueBindings, name: string): QueueBinding {
  const queue = bindings[name]
  if (!queue) throw new Error(`queue binding not found: ${name}`)
  return queue
}

export async function consume<E>(
  registry: JobRegistry<E>,
  batch: QueueBatch<JobEnvelope>,
  env: E,
  opts?: DispatchOpts<E>,
): Promise<void> {
  for (const msg of batch.messages) {
    try {
      await registry.dispatch(env, msg.body, opts)
      msg.ack()
    } catch {
      msg.retry()
    }
  }
}
