import { join } from 'path'
import type { CronJob } from './schedules'
import { getNextRun } from './scheduler'

const APPS_DIR = process.env.APPS_DIR!

export async function executeJob(job: CronJob, onUpdate: () => void): Promise<void> {
  if (job.state === 'disabled') return

  job.state = 'running'
  job.lastRun = Date.now()
  onUpdate()

  const cwd = join(APPS_DIR, job.app, 'current')

  try {
    const proc = Bun.spawn(['bun', 'run', job.file], {
      cwd,
      env: { ...process.env },
      stdout: 'pipe',
      stderr: 'pipe',
    })

    const [stdout, stderr] = await Promise.all([
      new Response(proc.stdout).text(),
      new Response(proc.stderr).text(),
    ])

    const code = await proc.exited

    job.lastDuration = Date.now() - job.lastRun
    job.lastExitCode = code
    job.lastError = code !== 0 ? stderr || 'Non-zero exit' : undefined
    job.state = 'idle'
    job.nextRun = getNextRun(job.id)

    // Log result
    console.log(`[cron] ${job.id} finished: code=${code} duration=${job.lastDuration}ms`)
    if (stdout) console.log(stdout)
    if (stderr) console.error(stderr)
  } catch (e) {
    job.lastDuration = Date.now() - job.lastRun
    job.lastExitCode = 1
    job.lastError = e instanceof Error ? e.message : String(e)
    job.state = 'idle'
    console.error(`[cron] ${job.id} failed:`, e)
  }

  onUpdate()
}
