/**
 * Canonical CORS / Origin allowlist — single source of truth.
 *
 * zync-api is ONE worker that serves both production (`*.zync.is`) and the
 * dev/staging deploy (`dev.zync.is`, `app.dev.zync.is`) plus the `workers.dev`
 * preview origins. Every state-mutating auth endpoint pins the `Origin` header
 * against this set. It previously lived as copy-pasted `new Set([...])` literals
 * in cors.ts + each auth route; the copies drifted (the per-route ones never got
 * the dev origins) and silently 403'd the dev login flow. Import this instead so
 * the allowlist can never diverge again.
 *
 * workers.dev origins are excluded in production (S11-i2-001).
 */
const BASE_APP_ORIGINS = [
  'https://app.zync.is',
  'https://admin.zync.is',
  'https://zync.is',
  'https://dev.zync.is',
  'https://app.dev.zync.is',
] as const

const WORKERS_DEV_APP_ORIGINS = [
  'https://zync-app.dry-salad-ffa1.workers.dev',
  'https://zync-app-preview.dry-salad-ffa1.workers.dev',
  'https://zync-admin.dry-salad-ffa1.workers.dev',
] as const

export function isProductionDeploy(environment?: string): boolean {
  if (environment === 'production') return true
  if (environment && environment !== 'production') return false
  // ENVIRONMENT not set: fail-closed — assume production (exclude workers.dev)
  return true
}

export function getAppOrigins(options?: { environment?: string }): Set<string> {
  const origins = new Set<string>(BASE_APP_ORIGINS)
  if (!isProductionDeploy(options?.environment)) {
    for (const origin of WORKERS_DEV_APP_ORIGINS) origins.add(origin)
  }
  return origins
}

/** @deprecated Prefer getAppOrigins({ environment }) — includes workers.dev for local/tests. */
export const APP_ORIGINS = getAppOrigins({ environment: 'development' })

/** True if `origin` (an `Origin` header value) is an allowed app origin. */
export function isAllowedOrigin(
  origin: string | undefined | null,
  options?: { environment?: string },
): boolean {
  return !!origin && getAppOrigins(options).has(origin)
}

/**
 * Derive the post-auth app origin (for verify-email / redirect targets) from the
 * incoming request host, so a dev-deploy request never bounces the user to prod.
 * The host encodes the environment because the email/verify link is built against
 * the same deploy that sent it. Falls back to prod for unknown hosts.
 */
export function appOriginForRequest(reqUrl: string): string {
  let host: string
  try {
    host = new URL(reqUrl).host
  } catch {
    return 'https://app.zync.is'
  }
  if (host === 'app.dev.zync.is' || host === 'dev.zync.is' || host.endsWith('.dev.zync.is')) {
    return 'https://app.dev.zync.is'
  }
  if (host.endsWith('.workers.dev')) {
    return host.startsWith('zync-app-preview.')
      ? 'https://zync-app-preview.dry-salad-ffa1.workers.dev'
      : 'https://zync-app.dry-salad-ffa1.workers.dev'
  }
  return 'https://app.zync.is'
}

export function getAdminOrigins(options?: { environment?: string }): Set<string> {
  const origins = new Set(['https://admin.zync.is'])
  if (!isProductionDeploy(options?.environment)) {
    origins.add('https://zync-admin.dry-salad-ffa1.workers.dev')
  }
  return origins
}
