/**
 * Strapi Content Migration Script
 * 
 * This script exports content from the old Strapi server and imports it to the new one.
 * 
 * Usage:
 * 1. Set environment variables:
 *    
 *    NEW_STRAPI_URL=https://your-new-strapi-server.com
 *    NEW_STRAPI_API_TOKEN=your-api-token (if authentication is required)
 * 
 * 2. Run: node scripts/migrate-strapi.js
 */

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

// Configuration from environment variables
const OLD_STRAPI_URL = process.env.NEXT_PUBLIC_STRAPI_BASE_URL;
const NEW_STRAPI_URL = process.env.NEW_STRAPI_URL || '';
const NEW_STRAPI_API_TOKEN = process.env.NEW_STRAPI_API_TOKEN || '';

// Content types to migrate
const CONTENT_TYPES = [
  'schoolforschools',
  'whyschoolforschools'
];

// Directory to store exported data
const EXPORT_DIR = path.join(__dirname, 'strapi-export');

/**
 * Fetch all entries from a Strapi content type (handles pagination)
 */
async function fetchStrapiContent(contentType, baseUrl) {
  console.log(`\n📥 Fetching ${contentType} from ${baseUrl}...`);
  
  try {
    let allData = [];
    let page = 1;
    let hasMore = true;
    const pageSize = 100;

    while (hasMore) {
      const url = `${baseUrl}/api/${contentType}?pagination[page]=${page}&pagination[pageSize]=${pageSize}&populate=*`;
      const response = await fetch(url, {
        headers: {
          'Accept': 'application/json',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      
      // Handle Strapi v4 format with pagination
      if (data.data) {
        allData = allData.concat(data.data);
        
        // Check if there are more pages
        if (data.meta?.pagination) {
          const { page: currentPage, pageCount } = data.meta.pagination;
          hasMore = currentPage < pageCount;
          page++;
        } else {
          hasMore = false;
        }
      } else if (Array.isArray(data)) {
        // Handle Strapi v3 format or direct array (no pagination)
        allData = data;
        hasMore = false;
      } else {
        hasMore = false;
      }
    }

    console.log(`   Found ${allData.length} entries`);
    return allData;
  } catch (error) {
    console.error(`❌ Error fetching ${contentType}:`, error.message);
    return [];
  }
}

/**
 * Export content to JSON files
 */
async function exportContent() {
  console.log('🚀 Starting Strapi content export...');
  console.log(`📡 Source: ${OLD_STRAPI_URL}\n`);

  // Create export directory
  if (!fs.existsSync(EXPORT_DIR)) {
    fs.mkdirSync(EXPORT_DIR, { recursive: true });
  }

  const exportData = {};

  for (const contentType of CONTENT_TYPES) {
    const content = await fetchStrapiContent(contentType, OLD_STRAPI_URL);
    exportData[contentType] = content;

    // Save individual file
    const filePath = path.join(EXPORT_DIR, `${contentType}.json`);
    fs.writeFileSync(filePath, JSON.stringify(content, null, 2));
    console.log(`✅ Exported ${content.length} entries for ${contentType}`);
  }

  // Save combined export
  const combinedPath = path.join(EXPORT_DIR, 'all-content.json');
  fs.writeFileSync(combinedPath, JSON.stringify(exportData, null, 2));
  
  console.log(`\n✅ Export complete! Data saved to: ${EXPORT_DIR}`);
  return exportData;
}

/**
 * Upload content to new Strapi server
 */
async function uploadToStrapi(contentType, entries, baseUrl, apiToken) {
  console.log(`\n📤 Uploading ${entries.length} entries for ${contentType}...`);

  const headers = {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  };

  if (apiToken) {
    headers['Authorization'] = `Bearer ${apiToken}`;
  }

  let successCount = 0;
  let errorCount = 0;

  for (const entry of entries) {
    try {
      // Remove id and other Strapi-specific fields that shouldn't be sent
      const { id, createdAt, updatedAt, publishedAt, ...entryData } = entry;

      // Handle nested relations - you may need to adjust this based on your schema
      const payload = {
        data: entryData
      };

      const response = await fetch(`${baseUrl}/api/${contentType}`, {
        method: 'POST',
        headers,
        body: JSON.stringify(payload)
      });

      if (response.ok) {
        successCount++;
        process.stdout.write('.');
      } else {
        const errorText = await response.text();
        console.error(`\n❌ Failed to upload entry ${id}: ${response.status} - ${errorText}`);
        errorCount++;
      }
    } catch (error) {
      console.error(`\n❌ Error uploading entry:`, error.message);
      errorCount++;
    }
  }

  console.log(`\n✅ ${successCount} entries uploaded, ${errorCount} errors`);
  return { successCount, errorCount };
}

/**
 * Import content from exported files
 */
async function importContent() {
  if (!NEW_STRAPI_URL) {
    console.error('❌ NEW_STRAPI_URL environment variable is required for import');
    return;
  }

  console.log('\n🚀 Starting Strapi content import...');
  console.log(`📡 Destination: ${NEW_STRAPI_URL}\n`);

  const combinedPath = path.join(EXPORT_DIR, 'all-content.json');
  
  if (!fs.existsSync(combinedPath)) {
    console.error(`❌ Export file not found: ${combinedPath}`);
    console.log('💡 Run export first by calling exportContent()');
    return;
  }

  const exportData = JSON.parse(fs.readFileSync(combinedPath, 'utf8'));

  for (const contentType of CONTENT_TYPES) {
    if (exportData[contentType]) {
      await uploadToStrapi(contentType, exportData[contentType], NEW_STRAPI_URL, NEW_STRAPI_API_TOKEN);
    }
  }

  console.log('\n✅ Import complete!');
}

/**
 * Main execution
 */
async function main() {
  const command = process.argv[2] || 'export';

  if (command === 'export') {
    await exportContent();
  } else if (command === 'import') {
    await importContent();
  } else if (command === 'migrate') {
    // Export first, then import
    const exportData = await exportContent();
    console.log('\n⏳ Waiting 2 seconds before import...\n');
    await new Promise(resolve => setTimeout(resolve, 2000));
    await importContent();
  } else {
    console.log(`
Usage: node scripts/migrate-strapi.js [command]

Commands:
  export   - Export content from old Strapi server (default)
  import   - Import content to new Strapi server
  migrate  - Export and import in one go

Environment Variables:
  OLD_STRAPI_URL         - Source Strapi server URL
  NEW_STRAPI_URL         - Destination Strapi server URL (required for import)
  NEW_STRAPI_API_TOKEN   - API token for new Strapi server (if authentication required)

Example:
  OLD_STRAPI_URL=https://old-server.com NEW_STRAPI_URL=https://new-server.com NEW_STRAPI_API_TOKEN=xxx node scripts/migrate-strapi.js migrate
    `);
  }
}

// Run if executed directly
if (require.main === module) {
  main().catch(console.error);
}

module.exports = { exportContent, importContent };

