import { z } from 'zod';

const envSchema = z.object({
  // Database
  DATABASE_URL: z.string().url().startsWith('postgresql://'),

  // Redis
  REDIS_URL: z.string().url().startsWith('redis://'),

  // Auth
  BETTER_AUTH_SECRET: z.string().min(32),
  BETTER_AUTH_URL: z.string().url(),
  CSRF_SECRET: z.string().min(32),

  // MinIO
  MINIO_ENDPOINT: z.string().min(1),
  MINIO_PORT: z.coerce.number().int().positive(),
  MINIO_ACCESS_KEY: z.string().min(1),
  MINIO_SECRET_KEY: z.string().min(1),
  MINIO_BUCKET: z.string().min(1),
  MINIO_USE_SSL: z.enum(['true', 'false']).transform((v) => v === 'true'),

  // Documenso
  DOCUMENSO_API_URL: z.string().url(),
  DOCUMENSO_API_KEY: z.string().min(1),
  DOCUMENSO_API_VERSION: z.enum(['v1', 'v2']).default('v1'),
  DOCUMENSO_WEBHOOK_SECRET: z.string().min(16),
  DOCUMENSO_TEMPLATE_ID_EOI: z.coerce.number().int().positive().default(8),
  DOCUMENSO_CLIENT_RECIPIENT_ID: z.coerce.number().int().positive().default(192),
  DOCUMENSO_DEVELOPER_RECIPIENT_ID: z.coerce.number().int().positive().default(193),
  DOCUMENSO_APPROVAL_RECIPIENT_ID: z.coerce.number().int().positive().default(194),

  // Email
  SMTP_HOST: z.string().min(1),
  SMTP_PORT: z.coerce.number().int().positive(),
  SMTP_USER: z.string().optional(),
  SMTP_PASS: z.string().optional(),
  SMTP_FROM: z.string().optional(),
  // Dev/test safety net: when set, sendEmail redirects every outbound message
  // to this address regardless of the requested recipient. Leave empty in prod.
  EMAIL_REDIRECT_TO: z.string().email().optional(),

  // Encryption
  EMAIL_CREDENTIAL_KEY: z
    .string()
    .length(64)
    .regex(/^[0-9a-f]+$/i, 'Must be a 64-character hex string'),

  // Google OAuth (optional)
  GOOGLE_CLIENT_ID: z.string().optional(),
  GOOGLE_CLIENT_SECRET: z.string().optional(),

  // OpenAI (optional)
  OPENAI_API_KEY: z.string().optional(),

  // App
  APP_URL: z.string().url(),
  PUBLIC_SITE_URL: z.string().url(),
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),
});

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

function validateEnv(): Env {
  if (process.env.SKIP_ENV_VALIDATION === '1') {
    return process.env as unknown as Env;
  }

  const result = envSchema.safeParse(process.env);
  if (!result.success) {
    console.error('Invalid environment variables:');
    for (const issue of result.error.issues) {
      console.error(`  ${issue.path.join('.')}: ${issue.message}`);
    }
    process.exit(1);
  }
  return result.data;
}

export const env = validateEnv();
