import { z } from "zod";

const schema = z.object({
  DATABASE_URL: z.string().min(1, "DATABASE_URL is required"),
  SESSION_TTL_HOURS: z.coerce.number().int().min(1).max(720).default(12),
  // Pause before the single retry that confirms a failed health check.
  HEALTH_CHECK_RETRY_DELAY_MS: z.coerce.number().int().min(0).max(60_000).default(3000),
  // How many health checks may be in flight at once during a bulk run.
  HEALTH_CHECK_CONCURRENCY: z.coerce.number().int().min(1).max(50).default(10),
  // internal: this server process ticks the scheduler itself (default; right for a single long-running server).
  // external: something else calls POST /api/cron/tick (needs CRON_SECRET). off: no scheduled checks.
  SCHEDULER_MODE: z.enum(["internal", "external", "off"]).default("internal"),
  SCHEDULER_TICK_SECONDS: z.coerce.number().int().min(5).max(3600).default(60),
  // Bearer token for POST /api/cron/tick. The endpoint is disabled while this is unset.
  CRON_SECRET: z.string().min(16, "CRON_SECRET must be at least 16 characters").optional(),
  // Where to find which registry runs the RDAP server for each domain ending. Only the
  // end-to-end tests change this (to a fake registry); production uses IANA's file.
  RDAP_BOOTSTRAP_URL: z.url().default("https://data.iana.org/rdap/dns.json"),
  NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
});

const parsed = schema.safeParse(process.env);

if (!parsed.success) {
  const issues = parsed.error.issues
    .map((i) => `${i.path.join(".")}: ${i.message}`)
    .join("; ");
  throw new Error(`Invalid environment configuration — ${issues}`);
}

export const env = parsed.data;
