import { readdir } from 'fs/promises'
import { existsSync } from 'fs'
import { join } from 'path'
import { isValidSchedule, toCronExpr, type CronJob, type Schedule } from './schedules'

const APPS_DIR = process.env.APPS_DIR!

export async function getApps(): Promise<string[]> {
  const entries = await readdir(APPS_DIR, { withFileTypes: true })
  const apps: string[] = []

  for (const entry of entries) {
    if (!entry.isDirectory()) continue
    // Check if it has a current symlink (valid app)
    if (existsSync(join(APPS_DIR, entry.name, 'current'))) {
      apps.push(entry.name)
    }
  }

  return apps.sort()
}

export async function discoverCronJobs(): Promise<CronJob[]> {
  const jobs: CronJob[] = []
  const apps = await readdir(APPS_DIR, { withFileTypes: true })

  for (const app of apps) {
    if (!app.isDirectory()) continue

    const cronDir = join(APPS_DIR, app.name, 'current', 'cron')
    if (!existsSync(cronDir)) continue

    const files = await readdir(cronDir)
    for (const file of files) {
      if (!file.endsWith('.ts')) continue

      const filePath = join(cronDir, file)
      const name = file.replace(/\.ts$/, '')

      try {
        const mod = await import(filePath)
        const schedule = mod.schedule as Schedule

        if (!isValidSchedule(schedule)) {
          console.error(`Invalid schedule in ${filePath}: ${schedule}`)
          continue
        }

        jobs.push({
          id: `${app.name}:${name}`,
          app: app.name,
          name,
          file: filePath,
          schedule,
          cronExpr: toCronExpr(schedule),
          state: 'idle',
        })
      } catch (e) {
        console.error(`Failed to load cron file ${filePath}:`, e)
      }
    }
  }

  return jobs
}
