/**
 * POST /api/cron/dispatch-group
 *
 * HTTP endpoint that lets external cron services (cron-job.org) trigger
 * one of the named cron groups. Guarded by CRON_SECRET (timing-safe).
 *
 * Body: { "group": "5min" | "hourly" | "daily-0130" | "daily-0500" | "daily-0900" }
 */
import { Hono } from 'hono'
import type { Env } from '../../env'
import { timingSafeEqual } from '@zync/auth'
import { runCronGroup } from '../../cron/runner'

const GROUP_MAP: Record<string, string> = {
  '5min':       '*/5 * * * *',
  'hourly':     '0 * * * *',
  'daily-0130': '30 1 * * *',
  'daily-0500': '0 5 * * *',
  'daily-0900': '0 9 * * *',
}

export const dispatchGroupRoute = new Hono<{ Bindings: Env }>()

dispatchGroupRoute.post('/', async (c) => {
  const inbound = c.req.header('x-cron-secret') ?? ''
  const expected = c.env.CRON_SECRET ?? ''
  // ACCEPTED-RISK (S7-i2-005): dispatch-group enforces a 32-char floor, but leaf
  // cron routes independently accept CRON_SECRET >= 16. Effective entropy is the
  // weakest per-route check; standardizing all routes is deferred.
  if (!expected || expected.length < 32) {
    return c.json({ error: 'Server misconfigured' }, 500)
  }
  if (!timingSafeEqual(inbound, expected)) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const body = (await c.req.json<{ group?: string }>().catch(() => ({}))) as { group?: string }
  const group = body.group
  const cronExpr = group ? GROUP_MAP[group] : undefined
  if (!cronExpr) {
    return c.json(
      { error: `Unknown group: ${group}. Valid: ${Object.keys(GROUP_MAP).join(', ')}` },
      400,
    )
  }

  c.executionCtx.waitUntil(runCronGroup(cronExpr, c.env))
  return c.json({ ok: true, group, cronExpr })
})
