import dotenv from "dotenv";
import { z } from "zod";

// Loads `.env.test` under Mocha (see `.mocharc.json`'s `NODE_ENV=test`,
// package.json's `test` script) instead of `.env` — same reasoning as
// `apps/api/src/config/env.ts`'s identical guard: `test/*.test.ts` needs a
// real (if dummy) `INTERNAL_WORKER_SECRET` to satisfy `envSchema` below
// without requiring every test file to set `process.env` by hand before
// importing anything that (transitively) imports this module.
dotenv.config({ path: process.env.NODE_ENV === "test" ? ".env.test" : ".env" });

/**
 * Every environment variable this worker reads. Parsing (below) fails fast
 * at startup if something required is missing/invalid — same "no silent
 * fallback" posture as `apps/api/src/config/env.ts`, this worker's closest
 * analog even though it isn't part of that workspace.
 */
const envSchema = z.object({
  /** Base URL of `apps/api` — `http://app:3000` (the `app` service's own docker-compose hostname) is the right default inside the compose network; override for local dev against a host-run API. */
  API_BASE_URL: z.string().url().default("http://app:3000"),
  /** Must match `apps/api`'s own `INTERNAL_WORKER_SECRET` (`config/env.ts`) — required, no default, same reasoning as that variable's own doc comment. */
  INTERNAL_WORKER_SECRET: z.string().min(32),
  /**
   * `hf:<repo>:<quant>` URI `resolveModelFile` (node-llama-cpp) resolves
   * and downloads — defaults to the model this feature's plan settled on
   * (`qwen2.5-1.5b`, `Q4_K_M`): best empirically observed FR/EN robustness
   * and JSON-structuring instruction-following among the small models
   * `experiments/llm-tech-step-poc` benchmarked, and not slower than the
   * smaller alternatives there despite having more parameters. See that
   * PoC's `README.md` for the fuller comparison this default is based on.
   */
  TECH_STEP_LLM_MODEL_URI: z.string().default("hf:Qwen/Qwen2.5-1.5B-Instruct-GGUF:Q4_K_M"),
  /** Explicit local GGUF path, bypassing the HF download above — same escape hatch `experiments/llm-tech-step-poc`'s own `LLM_TECH_STEP_MODEL_PATH` provides, useful offline or when a network download mid-deploy isn't wanted. */
  TECH_STEP_LLM_MODEL_PATH: z.string().optional(),
  /**
   * Cron expression (`node-cron` syntax) the scheduler wakes up on to run
   * both jobs — default weekly (Sunday 03:00) is a provisional floor, not
   * a calibrated value: this feature's plan explicitly flags the real
   * cadence as needing to be set from observed recipe/correction volume
   * and server resources once this is actually deployed (see that plan's
   * "Risques" section).
   */
  TECH_STEP_WORKER_CRON: z.string().default("0 3 * * 0"),
  /** Which of `TECH_STEP_TRAINING_DATA`'s locales `audit-low-confidence` samples against — see that job's own doc comment for why this can't just be discovered per-`Step` (the app has no per-recipe locale field yet). */
  TECH_STEP_WORKER_LOCALE: z.string().default("fr"),
  /** Upper bound passed as `?limit=` to both `GET /internal/tech-steps/audit-batch` and `GET /internal/tech-steps/pending-corrections` per run — keeps one scheduled run's LLM inference cost bounded regardless of backlog size; a larger backlog just takes more scheduled runs to drain, not one slower one. */
  TECH_STEP_WORKER_BATCH_LIMIT: z.coerce.number().int().positive().default(50),
  /**
   * Runs both jobs once immediately and exits, instead of starting the
   * cron loop — for a manual/CI-triggered run (`pnpm start`) rather than
   * the long-lived container process. `z.coerce.boolean()` is deliberately
   * *not* used here — it coerces via `Boolean(value)`, which makes the
   * literal string `"false"` coerce to `true` (any non-empty string does),
   * a real footgun for an env var — same explicit string-comparison
   * transform `apps/api/src/config/env.ts`'s `COOKIE_SECURE` already uses
   * for the identical reason.
   */
  RUN_ONCE: z
    .string()
    .optional()
    .transform((value) => value === "true"),
});

/** Parsed, validated environment — import this instead of reading `process.env` directly anywhere else. */
export const env = envSchema.parse(process.env);
