/**
 * Example: Using FileSystemUpload class
 * 
 * This example demonstrates uploading files from the local file system to AEM.
 * The FileSystemUpload class is ideal for:
 * - Uploading files from a local directory
 * - Maintaining directory structures
 * - Simple bulk uploads
 */

const { FileSystemUpload, FileSystemUploadOptions } = require('@adobe/aem-upload');
const fs = require('fs');
const path = require('path');
const { validateConfig, getUploadOptions, getTargetFolder } = require('../src/config');
const { 
  logSuccess, 
  logError, 
  logInfo, 
  createSpinner,
  handleUploadProgress,
  getAemAssetsUrl
} = require('../src/utils');
const { 
  analyzeUploadResult, 
  displayUploadSummary, 
  displayErrorSummary, 
  logException 
} = require('../src/errorHandler');

/**
 * Main function to demonstrate FileSystemUpload
 */
async function main() {
  try {
    // Validate configuration
    validateConfig();
    logSuccess('Configuration validated successfully');

    // Get upload options (now async to support service credentials)
    const options = await getUploadOptions();
    const targetFolder = getTargetFolder();

    logInfo(`AEM URL: ${options.url}`);
    logInfo(`Target folder: ${targetFolder}`);

    // Get sample files to upload
    const localDirectory = path.join(__dirname, '../sample-assets');
    
    if (!fs.existsSync(localDirectory)) {
      logError(`Sample assets directory not found: ${localDirectory}`);
      process.exit(1);
    }

    // Get subdirectories and root files to upload (not the parent folder itself)
    // This ensures we upload the contents directly to the target folder
    function getUploadPaths(dir) {
      const entries = fs.readdirSync(dir, { withFileTypes: true });
      const paths = [];
      
      for (const entry of entries) {
        if (entry.name.startsWith('.')) continue; // Skip hidden files/folders
        
        const fullPath = path.join(dir, entry.name);
        if (entry.isDirectory()) {
          // Add subdirectories (they'll be uploaded with their contents)
          paths.push(fullPath);
        } else if (entry.isFile()) {
          // Add root-level files
          paths.push(fullPath);
        }
      }
      
      return paths;
    }

    const uploadPaths = getUploadPaths(localDirectory);
    
    if (uploadPaths.length === 0) {
      logError('No files or directories found in sample-assets directory');
      process.exit(1);
    }

    logInfo(`Source directory: ${localDirectory}`);
    logInfo(`Found ${uploadPaths.length} item(s) to upload (directories + files)`);
    logInfo(`Upload mode: Deep (includes subdirectories)`);

    console.log('\n--- Starting Upload ---\n');

    // Initialize FileSystemUpload
    const upload = new FileSystemUpload();

    const startTime = Date.now();
    const spinner = createSpinner('Preparing upload...');

    // Upload options for this specific upload
    // For FileSystemUpload, the url should include the target folder path
    const fullUrl = `${options.url}${targetFolder}`;
    
    const uploadOptions = new FileSystemUploadOptions()
      .withUrl(fullUrl)
      .withDeepUpload(true);  // Enable recursive upload of subdirectories
    
    // Add HTTP options including headers (auth is already in headers from config)
    uploadOptions.withHttpOptions({
      headers: {
        ...options.headers,
        'X-Upload-Source': 'FileSystemUpload-Example'
      }
    });

    spinner.stop();

    // Attach progress event handlers to the upload instance
    handleUploadProgress(upload);

    // Perform the upload and wait for completion
    // Upload the contents (subdirectories and files) not the parent folder
    const uploadResult = await upload.upload(uploadOptions, uploadPaths);
    const totalTime = Date.now() - startTime;

    // Analyze results using shared function
    const analysis = analyzeUploadResult(uploadResult);

    // Display summary
    displayUploadSummary(analysis, totalTime);

    // Check for errors
    if (analysis.hasErrors) {
      // Show error details
      displayErrorSummary(analysis.errorSummary);
      logError('\nUpload failed. Please fix the errors above and try again.');
      console.log('');
      process.exit(1);
    } else {
      logSuccess('\nAll files uploaded successfully!');
      
      // Display uploaded file paths in AEM with clickable folder URL
      if (analysis.successfulFiles.length > 0) {
        const folderUrl = getAemAssetsUrl(options.url, targetFolder);
        console.log(`\n✅ Successfully uploaded to AEM: ${folderUrl}`);
        analysis.successfulFiles.forEach(fileInfo => {
          // Extract the relative path from targetFile
          if (fileInfo.targetFile) {
            const relativePath = fileInfo.targetFile.replace(`${targetFolder}/`, '');
            console.log(`  → ${relativePath}`);
          } else {
            const fileName = fileInfo.fileName || 'Unknown';
            console.log(`  → ${fileName}`);
          }
        });
      }
      console.log('');
      process.exit(0);
    }

  } catch (error) {
    logException(error, 'Upload failed');
    process.exit(1);
  }
}

// Run the example
if (require.main === module) {
  console.log('\n=== FileSystemUpload Example ===\n');
  main();
}

module.exports = { main };

