// src/lib/envValidation.ts

/**
 * Zentrale Validierung aller erforderlichen Environment-Variablen.
 * Wird beim Server-Start aufgerufen und beendet den Prozess bei fehlenden Werten.
 */

interface RequiredEnvVars {
  PAYLOAD_SECRET: string
  DATABASE_URI: string
  CONSENT_LOGGING_API_KEY: string
  IP_ANONYMIZATION_PEPPER: string
}

// Optionale SMTP-Konfiguration (Fallback für Tenants ohne eigene SMTP-Config)
export interface SmtpEnvVars {
  SMTP_HOST?: string
  SMTP_PORT?: string
  SMTP_SECURE?: string
  SMTP_USER?: string
  SMTP_PASS?: string
  SMTP_FROM_ADDRESS?: string
  SMTP_FROM_NAME?: string
}

export function getSmtpConfig(): SmtpEnvVars {
  return {
    SMTP_HOST: process.env.SMTP_HOST,
    SMTP_PORT: process.env.SMTP_PORT,
    SMTP_SECURE: process.env.SMTP_SECURE,
    SMTP_USER: process.env.SMTP_USER,
    SMTP_PASS: process.env.SMTP_PASS,
    SMTP_FROM_ADDRESS: process.env.SMTP_FROM_ADDRESS,
    SMTP_FROM_NAME: process.env.SMTP_FROM_NAME,
  }
}

const FORBIDDEN_VALUES = [
  '',
  'default-pepper-change-me',
  'change-me',
  'your-secret-here',
  'xxx',
]

function validateEnvVar(name: string, value: string | undefined): string {
  if (!value || value.trim() === '') {
    throw new Error(
      `FATAL: Environment variable ${name} is required but not set. ` +
        `Server cannot start without this value.`,
    )
  }

  if (FORBIDDEN_VALUES.includes(value.trim().toLowerCase())) {
    throw new Error(
      `FATAL: Environment variable ${name} has an insecure default value. ` +
        `Please set a secure random value.`,
    )
  }

  return value.trim()
}

function validateSecretExpiry(secretName: string): void {
  const expiryKey = `${secretName}_EXPIRES_AT`
  const expiryValue = process.env[expiryKey]
  if (!expiryValue) return

  const expiresAt = new Date(expiryValue)
  if (Number.isNaN(expiresAt.getTime())) {
    throw new Error(
      `FATAL: ${expiryKey} must be a valid ISO timestamp (example: 2026-12-31T23:59:59Z).`,
    )
  }

  if (process.env.NODE_ENV === 'production' && expiresAt.getTime() <= Date.now()) {
    throw new Error(
      `FATAL: ${secretName} is expired according to ${expiryKey}. Rotate secret before startup.`,
    )
  }
}

/**
 * Validiert alle erforderlichen Environment-Variablen.
 * Wirft einen Fehler und beendet den Server-Start, wenn Variablen fehlen.
 */
export function validateRequiredEnvVars(): RequiredEnvVars {
  // Production-only security requirements
  if (process.env.NODE_ENV === 'production') {
    validateEnvVar('CRON_SECRET', process.env.CRON_SECRET)
  }

  validateSecretExpiry('PAYLOAD_SECRET')
  validateSecretExpiry('CRON_SECRET')
  validateSecretExpiry('CSRF_SECRET')

  return {
    PAYLOAD_SECRET: validateEnvVar('PAYLOAD_SECRET', process.env.PAYLOAD_SECRET),
    DATABASE_URI: validateEnvVar('DATABASE_URI', process.env.DATABASE_URI),
    CONSENT_LOGGING_API_KEY: validateEnvVar(
      'CONSENT_LOGGING_API_KEY',
      process.env.CONSENT_LOGGING_API_KEY,
    ),
    IP_ANONYMIZATION_PEPPER: validateEnvVar(
      'IP_ANONYMIZATION_PEPPER',
      process.env.IP_ANONYMIZATION_PEPPER,
    ),
  }
}

/**
 * Lazy-initialized Environment-Variablen.
 * Wird erst beim ersten Zugriff validiert (vermeidet Build-Probleme).
 */
let _cachedEnv: RequiredEnvVars | null = null

export const env: RequiredEnvVars = new Proxy({} as RequiredEnvVars, {
  get(_, prop: keyof RequiredEnvVars) {
    if (!_cachedEnv) {
      _cachedEnv = validateRequiredEnvVars()
    }
    return _cachedEnv[prop]
  },
})
