import { z } from 'zod';
import { config } from 'dotenv';
import { resolve } from 'path';

// Load .env file from the api package root
config({ path: resolve(process.cwd(), '.env') });

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.string().default('4000'),
  DATABASE_URL: z.string(),
  JWT_SECRET: z.string().min(32),
  JWT_EXPIRES_IN: z.string().default('15m'),
  JWT_REFRESH_EXPIRES_IN: z.string().default('7d'),
  CORS_ORIGIN: z.string().default('http://localhost:3000'),

  // Frontend URL (for MercadoPago back_url, emails, etc.)
  FRONTEND_URL: z.string().default('https://horuxfin.com'),

  // FIEL encryption (separate from JWT to allow independent rotation)
  FIEL_ENCRYPTION_KEY: z.string().min(32),
  FIEL_STORAGE_PATH: z.string().default('/var/horux/fiel'),

  // MercadoPago
  MP_ACCESS_TOKEN: z.string().optional(),
  // Token sandbox (TEST-...) para pruebas locales sin cobro real. Conviven con
  // el de prod para no estar swap-eando manualmente. Solo se usa cuando
  // MP_USE_SANDBOX=true.
  MP_ACCESS_TOKEN_SANDBOX: z.string().optional(),
  // Toggle global: cuando true, todas las llamadas a MP usan
  // MP_ACCESS_TOKEN_SANDBOX. Default false → usa MP_ACCESS_TOKEN (prod).
  MP_USE_SANDBOX: z.string().transform(v => v === 'true' || v === '1').default('false'),
  MP_WEBHOOK_SECRET: z.string().optional(),
  MP_NOTIFICATION_URL: z.string().optional(),
  // Solo dev/staging: override del payer_email enviado a MercadoPago. Útil cuando
  // el owner del tenant tiene el mismo email vinculado al MP_ACCESS_TOKEN
  // (vendedor) — MP rechaza con "Payer and collector cannot be the same user".
  // Al setearlo, todas las llamadas a MP usan este email como payer en lugar del
  // owner real. Production: dejar vacío. (string vacío se trata como undefined
  // para que prod pueda dejar la línea declarada sin valor sin romper Zod.)
  MP_TEST_PAYER_EMAIL: z.preprocess(
    v => (v === '' ? undefined : v),
    z.string().email().optional(),
  ),

  // SMTP (Gmail Workspace)
  SMTP_HOST: z.string().default('smtp.gmail.com'),
  SMTP_PORT: z.string().default('587'),
  SMTP_USER: z.string().optional(),
  SMTP_PASS: z.string().optional(),
  SMTP_FROM: z.string().default('Horux360 <noreply@horuxfin.com>'),

  // Admin notification email
  ADMIN_EMAIL: z.string().default('carlos@horuxfin.com'),

  // SAT sync monitoring alerts (optional; falls back to ADMIN_EMAIL)
  SAT_ALERT_EMAIL: z.string().email().optional(),
  SAT_MONITOR_SCHEDULE: z.string().default('0 */2 * * *'),
  SAT_STUCK_RUNNING_HOURS: z.string().transform(v => parseInt(v, 10)).default('2'),
  SAT_FAILED_LOOKBACK_HOURS: z.string().transform(v => parseInt(v, 10)).default('24'),

  // Facturapi
  FACTURAPI_USER_KEY: z.string().optional(),

  // Cloudflare Tunnel (connector BYO-DB)
  CLOUDFLARE_API_TOKEN: z.string().optional(),
  CLOUDFLARE_ACCOUNT_ID: z.string().optional(),
  CLOUDFLARE_TUNNEL_DOMAIN: z.string().default('tunnel.horux.mx'),

  // KMS for encrypting DB connection strings and connector tokens
  CONNECTOR_ENCRYPTION_KEY: z.string().optional(),

  // Metabase (auto-registro de BDs tenant en Metabase para BI)
  METABASE_URL: z.string().optional(),
  METABASE_USERNAME: z.string().optional(),
  METABASE_PASSWORD: z.string().optional(),
  METABASE_PG_HOST: z.string().optional(),
  METABASE_PG_PORT: z.string().optional(),
  METABASE_PG_USER: z.string().optional(),
  METABASE_PG_PASSWORD: z.string().optional(),
});

const parsed = envSchema.safeParse(process.env);

if (!parsed.success) {
  console.error('❌ Invalid environment variables:', parsed.error.flatten().fieldErrors);
  process.exit(1);
}

export const env = parsed.data;

// Parse CORS origins (comma-separated) into array
export function getCorsOrigins(): string[] {
  return env.CORS_ORIGIN.split(',').map(origin => origin.trim());
}
