#!/usr/bin/env tsx

/**
 * TimeSafari Asset Configuration Generator
 * Generates capacitor-assets configuration files with deterministic outputs
 * Author: Matthew Raymer
 * 
 * Usage: tsx scripts/assets-config.ts
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const PROJECT_ROOT = path.dirname(__dirname);

// TypeScript interfaces for asset configuration
interface AdaptiveIconConfig {
  foreground: string;
  background: string;
  monochrome: string;
}

interface AndroidIconConfig {
  adaptive: AdaptiveIconConfig;
  target: string;
}

interface IOSIconConfig {
  padding: number;
  target: string;
}

interface WebIconConfig {
  target: string;
}

interface IconConfig {
  source: string;
  android: AndroidIconConfig;
  ios: IOSIconConfig;
  web: WebIconConfig;
}

interface AndroidSplashConfig {
  scale: string;
  target: string;
}

interface IOSSplashConfig {
  useStoryBoard: boolean;
  target: string;
}

interface SplashConfig {
  source: string;
  darkSource: string;
  android: AndroidSplashConfig;
  ios: IOSSplashConfig;
}

interface AssetConfig {
  icon: IconConfig;
  splash: SplashConfig;
}

/**
 * Generate deterministic capacitor-assets configuration
 * @returns Sorted, stable configuration object
 */
function generateAssetConfig(): AssetConfig {
  const config: AssetConfig = {
    icon: {
      source: "resources/icon.png",
      android: {
        adaptive: {
          foreground: "resources/icon.png",
          background: "#121212",
          monochrome: "resources/icon.png"
        },
        target: "android/app/src/main/res"
      },
      ios: {
        padding: 0,
        target: "ios/App/App/Assets.xcassets/AppIcon.appiconset"
      },
      web: {
        target: "public/img/icons"
      }
    },
    splash: {
      source: "resources/splash.png",
      darkSource: "resources/splash_dark.png",
      android: {
        scale: "cover",
        target: "android/app/src/main/res"
      },
      ios: {
        useStoryBoard: true,
        target: "ios/App/App/Assets.xcassets"
      }
    }
  };

  return sortObjectKeys(config);
}

/**
 * Sort object keys recursively for deterministic output
 * @param obj - Object to sort
 * @returns Object with sorted keys
 */
function sortObjectKeys(obj: any): any {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(sortObjectKeys);
  }

  const sorted: any = {};
  Object.keys(obj)
    .sort()
    .forEach(key => {
      sorted[key] = sortObjectKeys(obj[key]);
    });

  return sorted;
}

/**
 * Validate that required source files exist
 */
function validateSourceFiles(): void {
  const requiredFiles = [
    'resources/icon.png',
    'resources/splash.png',
    'resources/splash_dark.png'
  ];

  const missingFiles = requiredFiles.filter(file => {
    const filePath = path.join(PROJECT_ROOT, file);
    return !fs.existsSync(filePath);
  });

  if (missingFiles.length > 0) {
    console.error('❌ Missing required source files:');
    missingFiles.forEach(file => console.error(`   ${file}`));
    process.exit(1);
  }

  console.log('✅ All required source files found');
}

/**
 * Write configuration to file with consistent formatting
 * @param config - Configuration object
 * @param outputPath - Output file path
 */
function writeConfig(config: AssetConfig, outputPath: string): void {
  const jsonString = JSON.stringify(config, null, 2);
  
  // Ensure consistent line endings and no trailing whitespace
  const cleanJson = jsonString
    .split('\n')
    .map(line => line.trimEnd())
    .join('\n') + '\n';

  fs.writeFileSync(outputPath, cleanJson, 'utf8');
  console.log(`✅ Configuration written to: ${outputPath}`);
}

/**
 * Main execution function
 */
function main(): void {
  console.log('🔄 Generating TimeSafari asset configuration...');
  console.log(`📁 Project root: ${PROJECT_ROOT}`);
  console.log(`📅 Generated: ${new Date().toISOString()}`);

  try {
    // Validate source files exist
    validateSourceFiles();

    // Generate configuration
    const config = generateAssetConfig();

    // Ensure config directory exists
    const configDir = path.join(PROJECT_ROOT, 'config', 'assets');
    if (!fs.existsSync(configDir)) {
      fs.mkdirSync(configDir, { recursive: true });
    }

    // Write configuration files
    const capacitorAssetsConfigPath = path.join(configDir, 'capacitor-assets.config.json');
    writeConfig(config, capacitorAssetsConfigPath);

    // Copy to root for capacitor-assets discovery
    const rootConfigPath = path.join(PROJECT_ROOT, 'capacitor-assets.config.json');
    writeConfig(config, rootConfigPath);

    console.log('🎉 Asset configuration generation completed successfully!');
    console.log('');
    console.log('📋 Next steps:');
    console.log('   1. Review the generated configuration');
    console.log('   2. Commit the configuration files');
    console.log('   3. Run "npm run assets:validate" to verify');
    console.log('   4. Use "npm run build:native" for builds');

  } catch (error) {
    console.error('❌ Configuration generation failed:', error instanceof Error ? error.message : String(error));
    process.exit(1);
  }
}

// Run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
  main();
}

export { generateAssetConfig, sortObjectKeys, validateSourceFiles, AssetConfig };
