import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, IsOptional, IsString, validateSync } from 'class-validator';

/**
 * Environment variables validation schema
 * مخطط التحقق من صحة متغيرات البيئة
 * 
 * This ensures the app doesn't start if critical config is missing
 * يضمن هذا عدم بدء تشغيل التطبيق إذا كانت الإعدادات الهامة مفقودة
 */
enum Environment {
  Development = 'development',
  Production = 'production',
  Test = 'test',
}

class EnvironmentVariables {
  @IsEnum(Environment)
  @IsOptional()
  NODE_ENV: Environment = Environment.Development;

  @IsNumber()
  @IsOptional()
  PORT: number = 3001;

  @IsString()
  META_API_VERSION: string;

  @IsString()
  META_ACCESS_TOKEN: string;

  @IsString()
  META_AD_ACCOUNT_ID: string;

  // Meta App (OAuth)
  @IsString()
  META_APP_ID: string;

  @IsString()
  META_APP_SECRET: string;

  @IsString()
  META_REDIRECT_URI: string;

  // Database | قاعدة البيانات
  @IsString()
  DB_HOST: string;

  @IsNumber()
  DB_PORT: number;

  @IsString()
  DB_USER: string;

  @IsString()
  DB_PASSWORD: string;

  @IsString()
  DB_NAME: string;

  @IsString()
  GEMINI_API_KEY: string;

  // TikTok Ads
  @IsString()
  @IsOptional()
  TIKTOK_APP_ID: string;

  @IsString()
  @IsOptional()
  TIKTOK_SECRET: string;

  @IsString()
  @IsOptional()
  TIKTOK_REDIRECT_URI: string;

  // Google Ads
  @IsString()
  @IsOptional()
  GOOGLE_CLIENT_ID: string;

  @IsString()
  @IsOptional()
  GOOGLE_CLIENT_SECRET: string;

  @IsString()
  @IsOptional()
  GOOGLE_REDIRECT_URI: string;

  @IsString()
  @IsOptional()
  GOOGLE_DEVELOPER_TOKEN: string;

  // Paymob
  @IsString()
  @IsOptional()
  PAYMOB_API_KEY: string;

  @IsString()
  @IsOptional()
  PAYMOB_CARD_INTEGRATION_ID: string;

  @IsString()
  @IsOptional()
  PAYMOB_WALLET_INTEGRATION_ID: string;

  @IsString()
  @IsOptional()
  PAYMOB_HMAC_SECRET: string;

  // Binance Pay
  @IsString()
  @IsOptional()
  BINANCE_API_KEY: string;

  @IsString()
  @IsOptional()
  BINANCE_SECRET_KEY: string;

  @IsString()
  @IsOptional()
  TELEGRAM_BOT_TOKEN: string;

  @IsString()
  @IsOptional()
  TELEGRAM_CHAT_ID: string;

  @IsString()
  @IsOptional()
  SLACK_WEBHOOK_URL: string;

  @IsString()
  @IsOptional()
  FIREBASE_SERVICE_ACCOUNT_JSON: string;

  @IsString()
  @IsOptional()
  REDIS_HOST: string;

  @IsNumber()
  @IsOptional()
  REDIS_PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToInstance(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  // add explain this line
  // validateSync(validatedConfig, { skipMissingProperties: false });
  // this line is used to validate the environment variables
  // if the environment variables are not valid, it will throw an error
  // skipMissingProperties: false means that all environment variables are required
  // if skipMissingProperties is true, it will not throw an error if the environment variables are not valid
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
