#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

// --ensure flag: create empty placeholder if env.generated.ts doesn't exist, skip otherwise
const ensureOnly = process.argv.includes('--ensure');
const configDir = path.join(process.cwd(), 'src/app/config');
const outputPath = path.join(configDir, 'env.generated.ts');
if (ensureOnly) {
  if (fs.existsSync(outputPath)) {
    process.exit(0);
  }
  if (!fs.existsSync(configDir)) {
    fs.mkdirSync(configDir, { recursive: true });
  }
  fs.writeFileSync(
    outputPath,
    `// This file is auto-generated by tools/load-env.js\n// Run 'npm run env' to populate with values from .env\n\nexport const ENV = {} as const;\n\nexport type EnvVars = typeof ENV;\n`,
  );
  console.log(`✅ Created placeholder ${outputPath}`);
  process.exit(0);
}

const dotenv = require('dotenv');

// Define keys that should always be included in types for backwards compatibility
// These are checked with getEnv() which requires strict typing
const REQUIRED_ENV_KEYS = [
  // Currently empty - add keys here that should always be in the type definition
];

// Define optional keys that might be provided
// These can be accessed with getEnvOptional() without strict typing
const OPTIONAL_ENV_KEYS = [
  'UNSPLASH_KEY',
  'UNSPLASH_CLIENT_ID',
  'ONEDRIVE_CLIENT_ID',
  'GOOGLE_DRIVE_TOKEN',
  'DROPBOX_API_KEY',
  'WEBDAV_URL',
  'WEBDAV_USERNAME',
  'WEBDAV_PASSWORD',
];

const ALL_KEYS = [...REQUIRED_ENV_KEYS, ...OPTIONAL_ENV_KEYS];

// Start with system environment variables
const env = {};
ALL_KEYS.forEach((key) => {
  if (process.env[key]) {
    env[key] = process.env[key];
  }
});

// Load and override with .env file values if they exist
const envPath = path.join(process.cwd(), '.env');
const envConfig = dotenv.config({ path: envPath });
if (envConfig.parsed) {
  // Add all values from .env file, not just the predefined keys
  Object.assign(env, envConfig.parsed);
}

// Log what we found
const foundKeys = Object.keys(env);
if (foundKeys.length > 0) {
  console.log(`✅ Found ${foundKeys.length} environment variable(s)`);
} else {
  console.warn('⚠️  No environment variables found');
}

// Create ENV object with all found keys plus required keys (undefined if not set)
const allEnvKeys = new Set([...REQUIRED_ENV_KEYS, ...Object.keys(env)]);
const envEntries = Array.from(allEnvKeys)
  .sort()
  .map((key) => {
    const value = env[key];
    if (value !== undefined) {
      // Escape backslashes first, then quotes
      const escapedValue = value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
      return `  ${key}: '${escapedValue}',`;
    } else if (REQUIRED_ENV_KEYS.includes(key)) {
      throw new Error(`Required env key ${key} not found`);
    }
  });

// Generate TypeScript content
const tsContent = `// This file is auto-generated by tools/load-env.js
// Do not modify directly - edit .env file instead

/**
 * Environment variables loaded from .env file
 * Access these constants instead of process.env in your Angular app
 */
export const ENV = {
${envEntries.join('\n')}
} as const;

// Type-safe helper to ensure all expected env vars are defined
export type EnvVars = typeof ENV;
`;

// Ensure the config directory exists
if (!fs.existsSync(configDir)) {
  fs.mkdirSync(configDir, { recursive: true });
}

// Only write if content actually changed
const existingContent = fs.existsSync(outputPath)
  ? fs.readFileSync(outputPath, 'utf8')
  : null;

if (existingContent !== tsContent) {
  fs.writeFileSync(outputPath, tsContent);
  console.log(`✅ Generated ${outputPath}`);
} else {
  console.log(`✅ ${outputPath} is up to date`);
}

// Pass through to the next command
const extraArgs = process.argv.slice(2).filter((arg) => !arg.startsWith('--'));
if (extraArgs.length > 0) {
  // Execute the rest of the command
  const { spawn } = require('child_process');
  const command = extraArgs[0];
  const args = extraArgs.slice(1);

  const child = spawn(command, args, {
    stdio: 'inherit',
    shell: true,
  });

  child.on('exit', (code) => {
    process.exit(code);
  });
}
