/**
 * Environment variable validation
 */

import { z } from 'zod';

/**
 * Environment variable schema
 */
const envSchema = z.object({
  // Node environment
  NODE_ENV: z.enum(['development', 'staging', 'production']).default('development'),

  // Server configuration
  PORT: z.string().transform(Number).pipe(z.number().int().positive()).default('3000'),

  // Database
  DATABASE_URL: z.string().url(),

  // Storage (S3/GCS)
  STORAGE_TYPE: z.enum(['s3', 'gcs']).default('s3'),
  STORAGE_BUCKET: z.string(),
  STORAGE_REGION: z.string().default('us-east-1'),
  AWS_ACCESS_KEY_ID: z.string().optional(),
  AWS_SECRET_ACCESS_KEY: z.string().optional(),
  GCP_PROJECT_ID: z.string().optional(),
  GCP_KEY_FILE: z.string().optional(),

  // KMS
  KMS_TYPE: z.enum(['aws', 'gcp']).default('aws'),
  KMS_KEY_ID: z.string(),
  KMS_REGION: z.string().default('us-east-1'),

  // Authentication
  JWT_SECRET: z.string().min(32),
  OIDC_ISSUER: z.string().url().optional(),
  OIDC_CLIENT_ID: z.string().optional(),
  OIDC_CLIENT_SECRET: z.string().optional(),
  VC_ISSUER_DID: z.string().optional(),
  VC_ISSUER_DOMAIN: z.string().optional(),
  SWAGGER_SERVER_URL: z.string().url().optional(),

  // eIDAS
  EIDAS_PROVIDER_URL: z.string().url().optional(),
  EIDAS_API_KEY: z.string().optional(),

  // Microsoft Entra VerifiedID
  ENTRA_TENANT_ID: z.string().optional(),
  ENTRA_CLIENT_ID: z.string().optional(),
  ENTRA_CLIENT_SECRET: z.string().optional(),
  ENTRA_CREDENTIAL_MANIFEST_ID: z.string().optional(),
  ENTRA_MANIFESTS: z.string().optional(), // JSON object mapping manifest names to IDs
  // Entra Rate Limiting
  ENTRA_RATE_LIMIT_ISSUANCE: z.string().optional(),
  ENTRA_RATE_LIMIT_VERIFICATION: z.string().optional(),
  ENTRA_RATE_LIMIT_STATUS_CHECK: z.string().optional(),
  ENTRA_RATE_LIMIT_GLOBAL: z.string().optional(),
  // Credential Display/Images
  ENTRA_CREDENTIAL_LOGO_URI: z.string().url().optional(),
  ENTRA_CREDENTIAL_BG_COLOR: z.string().optional(),
  ENTRA_CREDENTIAL_TEXT_COLOR: z.string().optional(),

  // Credential Rate Limiting
  CREDENTIAL_RATE_LIMIT_PER_USER: z.string().optional(),
  CREDENTIAL_RATE_LIMIT_PER_IP: z.string().optional(),

  // Azure Logic Apps
  AZURE_LOGIC_APPS_WORKFLOW_URL: z.string().url().optional(),
  AZURE_LOGIC_APPS_ACCESS_KEY: z.string().optional(),
  AZURE_LOGIC_APPS_MANAGED_IDENTITY_CLIENT_ID: z.string().optional(),

  // CORS
  CORS_ORIGIN: z.string().optional(),

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

  // Monitoring
  OTEL_EXPORTER_OTLP_ENDPOINT: z.string().url().optional(),
  OTEL_SERVICE_NAME: z.string().optional(),

  // Payment Gateway
  PAYMENT_GATEWAY_API_KEY: z.string().optional(),
  PAYMENT_GATEWAY_WEBHOOK_SECRET: z.string().optional(),

  // OCR Service
  OCR_SERVICE_URL: z.string().url().optional(),
  OCR_SERVICE_API_KEY: z.string().optional(),

  // ML Classification
  ML_CLASSIFICATION_SERVICE_URL: z.string().url().optional(),
  ML_CLASSIFICATION_API_KEY: z.string().optional(),

  // Redis/Cache
  REDIS_URL: z.string().url().optional(),

  // Message Queue
  MESSAGE_QUEUE_URL: z.string().url().optional(),

  // Notifications
  EMAIL_PROVIDER: z.enum(['smtp', 'sendgrid', 'ses', 'sendinblue']).optional(),
  EMAIL_API_KEY: z.string().optional(),
  EMAIL_FROM: z.string().email().optional(),
  EMAIL_FROM_NAME: z.string().optional(),
  SMS_PROVIDER: z.enum(['twilio', 'aws-sns', 'nexmo']).optional(),
  SMS_API_KEY: z.string().optional(),
  SMS_FROM_NUMBER: z.string().optional(),
  PUSH_PROVIDER: z.enum(['fcm', 'apns', 'web-push']).optional(),
  PUSH_API_KEY: z.string().optional(),

  // Credential URLs
  CREDENTIALS_URL: z.string().url().optional(),
  RENEWAL_URL: z.string().url().optional(),

  // Compliance providers
  KYC_PROVIDER_URL: z.string().url().optional(),
  AML_PROVIDER_URL: z.string().url().optional(),
  SANCTIONS_PROVIDER_URL: z.string().url().optional(),
  
  // KYC Provider (Veriff)
  VERIFF_API_KEY: z.string().optional(),
  VERIFF_API_URL: z.string().url().optional(),
  VERIFF_WEBHOOK_SECRET: z.string().optional(),
  
  // Sanctions Provider (ComplyAdvantage)
  SANCTIONS_API_KEY: z.string().optional(),
  SANCTIONS_API_URL: z.string().url().optional(),
  
  // eResidency Service
  ERESIDENCY_SERVICE_URL: z.string().url().optional(),
  
  // DSB Configuration
  DSB_ISSUER_DID: z.string().optional(),
  DSB_ISSUER_DOMAIN: z.string().optional(),
  DSB_SCHEMA_REGISTRY_URL: z.string().url().optional(),

  // Secrets Management
  SECRETS_PROVIDER: z.enum(['aws', 'azure', 'env']).optional(),
  AZURE_KEY_VAULT_URL: z.string().url().optional(),
  AZURE_TENANT_ID: z.string().optional(),
  AZURE_CLIENT_ID: z.string().optional(),
  AZURE_CLIENT_SECRET: z.string().optional(),
  AZURE_MANAGED_IDENTITY_CLIENT_ID: z.string().optional(),
  SECRETS_CACHE_TTL: z.string().transform(Number).pipe(z.number().int().positive()).optional(),
});

/**
 * Validated environment variables
 */
export type Env = z.infer<typeof envSchema>;

let env: Env | null = null;

/**
 * Get validated environment variables
 */
export function getEnv(): Env {
  if (env) {
    return env;
  }

  try {
    env = envSchema.parse(process.env);
    return env;
  } catch (error) {
    if (error instanceof z.ZodError) {
      const missing = error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
      throw new Error(`Invalid environment variables: ${missing}`);
    }
    throw error;
  }
}

/**
 * Validate environment variables on module load
 */
getEnv();

