import { z } from 'zod';

// Environment variable schema for type-safe parsing
export const EnvSchema = z.object({
	// Server
	NODE_ENV: z.enum(['development', 'staging', 'production', 'test']).default('development'),
	PORT: z.coerce.number().default(3001),
	BACKEND_URL: z.url().default('http://localhost:3001'),
	FRONTEND_URL: z.string().default('http://localhost:3000'),
	PROJECT_NAME: z.string().default('Bekind Backend'),
	PROJECT_VERSION: z.string().default('1.0.0'),

	// Database
	DB_HOST: z.string().default('localhost'),
	DB_PORT: z.coerce.number().default(5432),
	DB_USER: z.string().default('postgres'),
	DB_PASSWORD: z.string().default(''),
	DB_NAME: z.string().default('sso'),
	DB_CONNECTION_STRING: z.string().default(''),
	DB_READ_HOST: z.string().default(''),
	DB_READ_PORT: z.coerce.number().default(5432),
	SLOW_QUERY_THRESHOLD_MS: z.coerce.number().default(500),
	DB_POOL_MAX: z.coerce.number().default(50),
	DB_POOL_MIN: z.coerce.number().default(5),
	DB_POOL_ACQUIRE: z.coerce.number().default(30000),
	DB_POOL_IDLE: z.coerce.number().default(10000),
	DB_POOL_EVICT: z.coerce.number().default(60000),

	// Redis
	REDIS_ENABLED: z.coerce.boolean().default(false),
	REDIS_HOST: z.string().default('localhost'),
	REDIS_PORT: z.coerce.number().default(6379),
	REDIS_PASSWORD: z.string().default(''),
	REDIS_DB: z.coerce.number().default(0),
	REDIS_CONNECT_TIMEOUT: z.coerce.number().default(10000),
	REDIS_COMMAND_TIMEOUT: z.coerce.number().default(5000),
	REDIS_MAX_RETRIES: z.coerce.number().default(3),
	REDIS_IP_FAMILY: z.coerce.number().default(4),

	// Redis A
	REDIS_A_ENABLED: z.coerce.boolean().default(false),
	REDIS_A_HOST: z.string().default('localhost'),
	REDIS_A_PORT: z.coerce.number().default(6379),
	REDIS_A_PASSWORD: z.string().default(''),
	REDIS_A_CLUSTER: z.coerce.boolean().default(false),
	REDIS_A_CLUSTER_NODES: z.string().default(''),

	// Redis B
	REDIS_B_HOST: z.string().default('localhost'),
	REDIS_B_PORT: z.coerce.number().default(6380),
	REDIS_B_PASSWORD: z.string().default(''),
	REDIS_B_DB: z.coerce.number().default(0),

	// Auth
	JWT_SECRET: z.string().min(32).default(''),
	JWT_SECRET_PREVIOUS: z.string().default(''), // Comma-separated previous secrets
	JWT_REFRESH_SECRET: z.string().min(32).default(''),
	JWT_REFRESH_SECRET_PREVIOUS: z.string().default(''), // Comma-separated previous refresh secrets
	JWT_EXPIRES_IN: z.string().default('1h'),
	JWT_REFRESH_EXPIRES_IN: z.string().default('7d'),
	TOKEN_ENCRYPTION_KEY: z.string().min(32).default(''),
	TOKEN_ENCRYPTION_KEY_PREVIOUS: z.string().default(''), // Comma-separated previous encryption keys
	BCRYPT_ROUNDS: z.coerce.number().min(4).max(12).default(12),
	DEFAULT_PASSWORD: z.string().default(''),
	PASSWORD_MIN_LENGTH: z.coerce.number().min(8).default(8),
	PASSWORD_MAX_LENGTH: z.coerce.number().max(128).default(128),
	INCLUDE_TOKENS_IN_RESPONSE: z.coerce.boolean().default(false),
	SKIP_SENSITIVE_CONFIRM: z.coerce.boolean().default(false),
	ENABLE_REGISTER: z.coerce.boolean().default(true),
	PASSWORD_HISTORY_LIMIT: z.coerce.number().default(5),

	// Cookie
	COOKIE_DOMAIN: z.string().default('.yourdomain.com'),
	COOKIE_CROSS_SITE: z.coerce.boolean().default(false),
	FORCE_SECURE_COOKIES: z.coerce.boolean().default(true),
	DEV_SAMESITE_LAX: z.coerce.boolean().default(false),

	// CSRF
	CSRF_ORIGIN_VALIDATION: z.coerce.boolean().default(true),
	CSRF_DOUBLE_SUBMIT: z.coerce.boolean().default(true),
	CSRF_HTTPONLY: z.coerce.boolean().default(true),
	ALLOWED_ORIGINS: z.string().default(''),

	// Uploads
	UPLOAD_PATH: z.string().default('./storage/uploads'),
	MAX_FILE_SIZE: z.coerce.number().default(10485760),
	STORAGE_IMAGES_PATH: z.string().default('/storage/uploads/images'),
	COMPRESS_TIMEOUT_MS: z.coerce.number().default(30000),

	// Storage
	STORAGE_PROVIDER: z.enum(['local', 'minio']).default('minio'),
	PUBLIC_BASE_URL: z.url().default('https://api.yourdomain.com'),
	LOCAL_STORAGE_ROOT: z.string().default('./storage/uploads'),
	MINIO_ENDPOINT: z.string().default('minio'),
	MINIO_PORT: z.coerce.number().default(9000),
	MINIO_USE_SSL: z.coerce.boolean().default(true),
	MINIO_ACCESS_KEY: z.string().default(''),
	MINIO_SECRET_KEY: z.string().default(''),
	MINIO_BUCKET: z.string().default('uploads'),
	MINIO_REGION: z.string().default('us-east-1'),
	S3_BUCKET: z.string().default(''),
	STORAGE_QUOTA_PER_USER: z.coerce.number().default(0),

	// Email
	EMAIL_HOST: z.string().default('smtp.example.com'),
	EMAIL_PORT: z.coerce.number().default(587),
	EMAIL_USER: z.string().default(''),
	EMAIL_PASS: z.string().default(''),
	EMAIL_FROM: z.email().default('noreply@yourdomain.com'),

	// Notifications
	QUEUE_CONCURRENCY: z.coerce.number().default(10),
	WORKER_CONCURRENCY: z.coerce.number().default(20),
	JOB_ATTEMPTS: z.coerce.number().default(3),
	JOB_BACKOFF_DELAY: z.coerce.number().default(2000),
	MAX_LOGIN_ATTEMPTS: z.coerce.number().default(5),
	LOCKOUT_DURATION_MINUTES: z.coerce.number().default(15),
	RATE_LIMIT_WINDOW_MS: z.coerce.number().default(60000),
	RATE_LIMIT_ONESIGNAL_MAX: z.coerce.number().default(100),
	RATE_LIMIT_ZALO_MAX: z.coerce.number().default(50),
	RATE_LIMIT_EMAIL_MAX: z.coerce.number().default(200),
	PERM_CACHE_TTL: z.coerce.number().default(300),
	SESSION_CACHE_TTL: z.coerce.number().default(900),
	REUSE_WINDOW_SECONDS: z.coerce.number().default(30),
	MAX_NOTIFICATION_RETRIES: z.coerce.number().default(3),

	// Zalo
	ZALO_APP_ID: z.string().default(''),
	ZALO_SECRET_KEY: z.string().default(''),
	ZALO_OA_ACCESS_TOKEN: z.string().default(''),
	ZALO_ZNS_ACCESS_TOKEN: z.string().default(''),
	ZALO_ZNS_TEMPLATE_ID: z.string().default(''),
	SERVICE_JWT_SECRET: z.string().default(''),
	MTLS_ENABLED: z.coerce.boolean().default(false),
	WORKLOAD_IDENTITY_ENABLED: z.coerce.boolean().default(false),

	// OneSignal
	ONESIGNAL_APP_ID: z.string().default(''),
	ONESIGNAL_API_KEY: z.string().default(''),

	// VAPID
	VAPID_SUBJECT: z.string().default('mailto:admin@yourdomain.com'),
	VAPID_PUBLIC_KEY: z.string().default(''),
	VAPID_PRIVATE_KEY: z.string().default(''),

	// Idempotency
	IDEMPOTENCY_KEY_TTL: z.coerce.number().default(86400),

	// Circuit Breaker
	CIRCUIT_BREAKER_ERROR_RATE: z.coerce.number().default(0.3),
	CIRCUIT_BREAKER_MIN_REQUESTS: z.coerce.number().default(100),
	CIRCUIT_BREAKER_TIMEOUT: z.coerce.number().default(300000),

	// Partition
	PARTITION_RETAIN_MONTHS: z.coerce.number().default(12),

	// Virus Scan
	VIRUS_SCAN_ENABLED: z.coerce.boolean().default(false),
	CLAM_SOCKET: z.string().default(''),
	CLAM_HOST: z.string().default('127.0.0.1'),
	CLAM_PORT: z.coerce.number().default(3310),
	CLAM_SCAN_TIMEOUT_MS: z.coerce.number().default(15000),
	VIRUS_SCAN_FAIL_OPEN: z.coerce.boolean().default(false),

	// Logging
	LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug', 'off']).default('info'),
	LOG_URL: z.string().default('./storage/logs'),
	LOG_MODE: z.enum(['file', 'console', 'both']).default('file'),
	LOG_TIMEOUT: z.coerce.number().default(5000),

	// CORS
	DEV_CORS_DISABLE: z.coerce.boolean().default(false),

	// Feature Flags
	SHOW_STACK_IN_ERRORS: z.coerce.boolean().default(false),
	FILE_LIST_URL_CONCURRENCY: z.coerce.number().default(5),
	MAX_SIMPLE_FALLBACK_SIZE: z.coerce.number().default(5000),
	MAX_FALLBACK_MAP_SIZE: z.coerce.number().default(10000),

	// Debug
	LOG_CONFIG_SOURCES: z.coerce.boolean().default(false),

	// Audit
	AUDIT_MODE: z.enum(['direct', 'worker']).default('direct'),
	AUDIT_ENABLED: z.coerce.boolean().default(true),

	// Webhook
	WEBHOOK_TOKEN: z.string().default(''),

	// Email verification
	EMAIL_VERIFICATION_TTL_HOURS: z.coerce.number().default(24),
});

export type EnvVars = z.infer<typeof EnvSchema>;
