/**
 * runCronGroup — shared dispatch logic for Cloudflare scheduled() triggers
 * and the POST /api/cron/dispatch-group HTTP endpoint.
 *
 * Kept in its own module to avoid circular imports between index.ts and the
 * dispatch-group route handler.
 */
import type { Env } from '../env'
import { runSessionExpiredSweep } from './session-expired-sweep'
import { runSessionIdleCleanup } from './session-idle-cleanup'
import { runScheduledReports } from './scheduled-reports'

const CRON_ROUTE_MAP: Record<string, string[]> = {
  // SLA checks every 15 min
  '*/15 * * * *': ['/api/cron/ticket-sla-check'],
  // hourly
  '0 * * * *':   ['/api/cron/invoice-adapter-reconcile', '/api/cron/tasks-sync', '/api/cron/time-cleanup'],
  // daily 01:30 UTC — retention + cleanup
  '30 1 * * *':  [
    '/api/cron/webhook-log-retention',
    '/api/cron/audit-log-retention',
    '/api/cron/data-retention-purge',
    '/api/cron/audit-partition-create',
  ],
  // daily 05:00 UTC — billing, renewals, contracts
  '0 5 * * *':   [
    '/api/cron/subscription-trial-check',
    '/api/cron/proposal-expiry',
    '/api/cron/proposal-expiry-reminder',
    '/api/cron/calendar-sync',
    '/api/cron/ticket-close-stale',
    '/api/cron/contract-expiry-reminder',
    '/api/cron/contract-signing-reminders',
    '/api/cron/withholding-expiry-check',
  ],
  // daily 06:00 UTC — recurring invoice generation
  '0 6 * * *':   [
    '/api/cron/recurring-invoice-generator',
  ],
  // daily 09:00 UTC — invoicing, leads, generators
  '0 9 * * *':   [
    '/api/cron/invoice-reminders',
    '/api/cron/lead-reengagement',
    '/api/cron/lead-score-refresh',
    '/api/cron/recurring-task-generator',
    '/api/cron/generate-recurring-expenses',
  ],
}

/**
 * Dispatch all HTTP-based cron routes for a given cron expression by
 * POSTing to each route internally (Workers self-fetch via http://localhost).
 */
export async function dispatchCronRoutes(cronExpr: string, env: Env): Promise<void> {
  const secret = (env as unknown as Record<string, string>).CRON_SECRET ?? ''
  const headers = { 'x-cron-secret': secret, 'content-type': 'application/json' }
  const base = 'http://localhost'

  const paths = CRON_ROUTE_MAP[cronExpr]
  if (!paths) return

  for (const path of paths) {
    try {
      await fetch(new Request(`${base}${path}`, { method: 'POST', headers }))
    } catch (err) {
      console.error(`[dispatchCronRoutes] ${path} failed:`, err)
    }
  }
}

/**
 * Run all cron logic for the given cron expression — HTTP routes + direct handlers.
 * Used by both scheduled() and POST /api/cron/dispatch-group.
 */
export async function runCronGroup(cronExpr: string, env: Env): Promise<void> {
  await dispatchCronRoutes(cronExpr, env)
  // wave-13: session-security — direct cron handlers (no HTTP hop)
  if (cronExpr === '*/5 * * * *') {
    await runSessionExpiredSweep(env)
    await runScheduledReports(env)
  }
  if (cronExpr === '*/15 * * * *') {
    await runSessionExpiredSweep(env)
    await runScheduledReports(env)
  }
  if (cronExpr === '30 1 * * *') {
    await runSessionIdleCleanup(env)
  }
}
