import { z } from "zod";

export const mintelEnvSchema = {
  NODE_ENV: z
    .enum(["development", "production", "test"])
    .default("development"),
  NEXT_PUBLIC_BASE_URL: z.string().url().optional(),
  NEXT_PUBLIC_TARGET: z
    .enum(["development", "testing", "staging", "production"])
    .optional(),
  TARGET: z
    .enum(["development", "testing", "staging", "production"])
    .optional(),

  // Analytics (Proxy Pattern)
  UMAMI_WEBSITE_ID: z.string().optional(),
  NEXT_PUBLIC_UMAMI_WEBSITE_ID: z.string().optional(),
  UMAMI_API_ENDPOINT: z
    .string()
    .url()
    .default("https://analytics.infra.mintel.me"),

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

  // Notifications
  GOTIFY_URL: z.string().url().optional(),
  GOTIFY_TOKEN: z.string().optional(),

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

  // Mail
  MAIL_HOST: z.string().optional(),
  MAIL_PORT: z.coerce.number().default(587),
  MAIL_USERNAME: z.string().optional(),
  MAIL_PASSWORD: z.string().optional(),
  MAIL_FROM: 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.string().url().default("http://localhost:8055"),
  DIRECTUS_ADMIN_EMAIL: z.string().optional(),
  DIRECTUS_ADMIN_PASSWORD: z.string().optional(),
  DIRECTUS_API_TOKEN: z.string().optional(),
  INTERNAL_DIRECTUS_URL: z.string().url().optional(),
};

/**
 * Standard Mintel refinements for environment variables.
 * Enforces mandatory requirements for non-development environments.
 */
export const withMintelRefinements = <T extends z.ZodTypeAny>(schema: T) => {
  return schema.superRefine((data: any, ctx) => {
    const skipValidation =
      process.env.SKIP_ENV_VALIDATION === "true" ||
      process.env.SKIP_RUNTIME_ENV_VALIDATION === "true";

    if (skipValidation) return;

    const target = data.TARGET || data.NEXT_PUBLIC_TARGET || "development";

    // Strict validation for non-development environments
    if (target !== "development") {
      if (!data.MAIL_HOST) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "MAIL_HOST is required in non-development environments",
          path: ["MAIL_HOST"],
        });
      }
    }
  });
};

export type MintelEnv<T extends z.ZodRawShape = Record<string, never>> =
  z.infer<
    ReturnType<
      typeof withMintelRefinements<z.ZodObject<typeof mintelEnvSchema & T>>
    >
  >;

export function validateMintelEnv<
  T extends z.ZodRawShape = Record<string, never>,
>(schemaExtension: T = {} as T): MintelEnv<T> {
  const fullSchema = withMintelRefinements(
    z.object(mintelEnvSchema).extend(schemaExtension),
  );

  const isBuildTime =
    process.env.NEXT_PHASE === "phase-production-build" ||
    process.env.SKIP_ENV_VALIDATION === "true" ||
    process.env.SKIP_RUNTIME_ENV_VALIDATION === "true";

  const result = fullSchema.safeParse(process.env);

  if (!result.success) {
    if (isBuildTime) {
      console.warn(
        "⚠️ Some environment variables are missing during build, but skipping strict validation.",
      );
      // Return process.env casted to the full schema type to unblock builds
      return process.env as unknown as z.infer<typeof fullSchema>;
    }

    console.error(
      "❌ Invalid environment variables:",
      result.error.flatten().fieldErrors,
    );
    throw new Error("Invalid environment variables");
  }

  return result.data as MintelEnv<T>;
}
