import { z } from 'zod';
import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';

dotenv.config({ path: path.resolve(process.cwd(), '.env') });

function localhostOriginsFromPortsFile(): string[] {
  const portsFile = path.resolve(process.cwd(), '../logs/ports.env');
  if (!fs.existsSync(portsFile)) return [];
  const ports: number[] = [];
  for (const line of fs.readFileSync(portsFile, 'utf8').split('\n')) {
    const m = line.match(/^export\s+CALENDAR_(?:HOST|PUBLIC|EMBED)_PORT=(\d+)/);
    if (m) ports.push(Number(m[1]));
  }
  return ports.flatMap((p) => [`http://localhost:${p}`, `http://127.0.0.1:${p}`]);
}

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.coerce.number().default(3000),
  APP_URL: z.string().url().default('http://localhost:4200'),
  BOOKING_APP_URL: z.string().url().optional(),
  API_URL: z.string().url().default('http://localhost:3000'),
  DB_HOST: z.string(),
  DB_PORT: z.coerce.number().default(3306),
  DB_USER: z.string(),
  DB_PASSWORD: z.string(),
  DB_NAME: z.string(),
  DB_POOL_SIZE: z.coerce.number().default(10),
  REDIS_HOST: z.string().default('localhost'),
  REDIS_PORT: z.coerce.number().default(6379),
  REDIS_PASSWORD: z.string().optional(),
  KAFKA_BROKERS: z.string().default('198.204.241.250:9092'),
  KAFKA_CLIENT_ID: z.string().default('calendar-api'),
  JWT_SECRET: z.string().min(32),
  JWT_EXPIRES_IN: z.coerce.number().default(3600),
  GOOGLE_CLIENT_ID: z.string().optional(),
  GOOGLE_CLIENT_SECRET: z.string().optional(),
  GOOGLE_REDIRECT_URI: z.string().optional(),
  GOOGLE_AUTH_REDIRECT_URI: z.string().optional(),
  LINKEDIN_CLIENT_ID: z.string().optional(),
  LINKEDIN_CLIENT_SECRET: z.string().optional(),
  LINKEDIN_AUTH_REDIRECT_URI: z.string().optional(),
  MICROSOFT_CLIENT_ID: z.string().optional(),
  MICROSOFT_CLIENT_SECRET: z.string().optional(),
  MICROSOFT_REDIRECT_URI: z.string().optional(),
  TOKEN_ENCRYPTION_KEY: z.string().optional(),
  SMTP_HOST: z.string().optional(),
  SMTP_PORT: z.coerce.number().default(587),
  SMTP_USER: z.string().optional(),
  SMTP_PASS: z.string().optional(),
  EMAIL_FROM: z.string().default('noreply@example.com'),
  /** smtp (default) or gmail_api — Gmail API needs GMAIL_REFRESH_TOKEN + Google OAuth client */
  MAIL_TRANSPORT: z.enum(['smtp', 'gmail_api']).default('smtp'),
  GMAIL_REFRESH_TOKEN: z.string().optional(),
  GMAIL_USER: z.string().optional(),
  EMBED_SCRIPT_URL: z.string().default('http://localhost:3000/embed/loader.js'),
  CORS_ALLOWED_ORIGINS: z.string().default('http://localhost:4200'),
});

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

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

const data = parsed.data;

export const env = {
  ...data,
  bookingAppUrl: data.BOOKING_APP_URL ?? data.APP_URL,
  redisUrl: data.REDIS_PASSWORD
    ? `redis://:${encodeURIComponent(data.REDIS_PASSWORD)}@${data.REDIS_HOST}:${data.REDIS_PORT}`
    : `redis://${data.REDIS_HOST}:${data.REDIS_PORT}`,
  kafkaBrokers: data.KAFKA_BROKERS.split(',').map((b) => b.trim()).filter(Boolean),
  corsOrigins: [
    ...new Set([
      ...data.CORS_ALLOWED_ORIGINS.split(',').map((o) => o.trim()).filter(Boolean),
      ...localhostOriginsFromPortsFile(),
    ]),
  ],
  isProduction: data.NODE_ENV === 'production',
  isTest: data.NODE_ENV === 'test',
};
