import { z } from "zod";

/**
 * Helper to treat empty strings as undefined.
 */
const preprocessEmptyString = (val: unknown) => (val === "" ? undefined : val);

/**
 * Environment variable schema.
 */
export const envSchema = z.object({
  NODE_ENV: z
    .enum(["development", "production", "test"])
    .default("development"),
  NEXT_PUBLIC_BASE_URL: z.preprocess(
    preprocessEmptyString,
    z.string().url().optional(),
  ),
  NEXT_PUBLIC_TARGET: z
    .enum(["development", "testing", "staging", "production"])
    .optional(),

  // Analytics
  NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.preprocess(
    preprocessEmptyString,
    z.string().optional(),
  ),
  NEXT_PUBLIC_UMAMI_SCRIPT_URL: z.preprocess(
    preprocessEmptyString,
    z.string().url().default("https://analytics.infra.mintel.me/script.js"),
  ),

  // Error Tracking
  SENTRY_DSN: z.preprocess(preprocessEmptyString, z.string().optional()),

  // Logging
  LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),

  // Mail
  MAIL_HOST: z.preprocess(preprocessEmptyString, z.string().optional()),
  MAIL_PORT: z.preprocess(
    preprocessEmptyString,
    z.coerce.number().default(587),
  ),
  MAIL_USERNAME: z.preprocess(preprocessEmptyString, z.string().optional()),
  MAIL_PASSWORD: z.preprocess(preprocessEmptyString, z.string().optional()),
  MAIL_FROM: z.preprocess(preprocessEmptyString, z.string().optional()),
  MAIL_RECIPIENTS: z.preprocess(
    (val) => (typeof val === "string" ? val.split(",").filter(Boolean) : val),
    z.array(z.string()).default([]),
  ),

  // Directus
  DIRECTUS_URL: z.preprocess(
    preprocessEmptyString,
    z.string().url().default("http://localhost:8055"),
  ),
  DIRECTUS_ADMIN_EMAIL: z.preprocess(
    preprocessEmptyString,
    z.string().optional(),
  ),
  DIRECTUS_ADMIN_PASSWORD: z.preprocess(
    preprocessEmptyString,
    z.string().optional(),
  ),
  DIRECTUS_API_TOKEN: z.preprocess(
    preprocessEmptyString,
    z.string().optional(),
  ),
  INTERNAL_DIRECTUS_URL: z.preprocess(
    preprocessEmptyString,
    z.string().url().optional(),
  ),

  // Deploy Target
  TARGET: z
    .enum(["development", "testing", "staging", "production"])
    .optional(),
  // Gotify
  GOTIFY_URL: z.preprocess(preprocessEmptyString, z.string().url().optional()),
  GOTIFY_TOKEN: z.preprocess(preprocessEmptyString, z.string().optional()),
});

export type Env = z.infer<typeof envSchema>;

/**
 * Collects all environment variables from the process.
 * Explicitly references NEXT_PUBLIC_ variables for Next.js inlining.
 */
export function getRawEnv() {
  return {
    NODE_ENV: process.env.NODE_ENV,
    NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
    NEXT_PUBLIC_TARGET: process.env.NEXT_PUBLIC_TARGET,
    NEXT_PUBLIC_UMAMI_WEBSITE_ID: process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID,
    NEXT_PUBLIC_UMAMI_SCRIPT_URL: process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL,
    SENTRY_DSN: process.env.SENTRY_DSN,
    LOG_LEVEL: process.env.LOG_LEVEL,
    MAIL_HOST: process.env.MAIL_HOST,
    MAIL_PORT: process.env.MAIL_PORT,
    MAIL_USERNAME: process.env.MAIL_USERNAME,
    MAIL_PASSWORD: process.env.MAIL_PASSWORD,
    MAIL_FROM: process.env.MAIL_FROM,
    MAIL_RECIPIENTS: process.env.MAIL_RECIPIENTS,
    DIRECTUS_URL: process.env.DIRECTUS_URL,
    DIRECTUS_ADMIN_EMAIL: process.env.DIRECTUS_ADMIN_EMAIL,
    DIRECTUS_ADMIN_PASSWORD: process.env.DIRECTUS_ADMIN_PASSWORD,
    DIRECTUS_API_TOKEN: process.env.DIRECTUS_API_TOKEN,
    INTERNAL_DIRECTUS_URL: process.env.INTERNAL_DIRECTUS_URL,
    TARGET: process.env.TARGET,
    GOTIFY_URL: process.env.GOTIFY_URL,
    GOTIFY_TOKEN: process.env.GOTIFY_TOKEN,
  };
}
