const swaggerAutogen = require('swagger-autogen')();
const path = require('path');
const fs = require('fs');

const outputFile = path.join(__dirname, '..', 'docs', 'openapi.json');

// Import route mappings (Single Source of Truth - keine Router-Imports!)
const routeMappings = require('./routes/routeMappings');

// Use mappings directly (already has file + prefix)
const routerMappings = routeMappings;

const routesDir = path.join(__dirname, 'routes');
const endpointsFiles = routerMappings.map(r => path.join(routesDir, r.file));

const doc = {
  info: {
    title: 'Project Image Uploader API',
    version: '2.0.0',
    description: 'Auto-generated OpenAPI spec with correct mount prefixes'
  },
  host: 'localhost:5001',
  schemes: ['http'],
  // Add base path hints per router (swagger-autogen doesn't natively support per-file prefixes,
  // so we'll post-process or use @swagger annotations in route files)
};

console.log('Generating OpenAPI spec...');

// Generate specs for each router separately with correct basePath
async function generateWithPrefixes() {
  const allPaths = {};
  const allTags = new Set();
  
  for (const mapping of routerMappings) {
    console.log(`� Processing ${mapping.file} with prefix: "${mapping.prefix || '/'}"...`);
    
    const uniqueName = mapping.name || mapping.file.replace('.js', '');
    const tempOutput = path.join(__dirname, '..', 'docs', `.temp-${uniqueName}.json`);
    const routeFile = path.join(routesDir, mapping.file);
    
    const tempDoc = {
      ...doc,
      basePath: mapping.prefix || '/'
    };
    
    await swaggerAutogen(tempOutput, [routeFile], tempDoc);
    
    // Read the generated spec
    const tempSpec = JSON.parse(fs.readFileSync(tempOutput, 'utf8'));
    
    // Merge paths - prepend prefix to each path
    for (const [routePath, pathObj] of Object.entries(tempSpec.paths || {})) {
      const fullPath = mapping.prefix + routePath;
      allPaths[fullPath] = pathObj;
      
      // Collect tags
      Object.values(pathObj).forEach(methodObj => {
        if (methodObj.tags) {
          methodObj.tags.forEach(tag => allTags.add(tag));
        }
      });
    }
    
    // Clean up temp file
    fs.unlinkSync(tempOutput);
  }
  
  // Write final merged spec
  const finalSpec = {
    openapi: '3.0.0',
    info: doc.info,
    servers: [
      { url: 'http://localhost:5001', description: 'Development server (dev compose backend)' }
    ],
    tags: Array.from(allTags).map(name => ({ name })),
    paths: allPaths
  };
  
  fs.writeFileSync(outputFile, JSON.stringify(finalSpec, null, 2));
  
  console.log('\n✅ OpenAPI spec generated successfully!');
  console.log(`📊 Total paths: ${Object.keys(allPaths).length}`);
  console.log(`📋 Tags: ${Array.from(allTags).join(', ')}`);
}

// Export for programmatic usage (e.g., from server.js)
module.exports = generateWithPrefixes;

// Run directly when called from CLI
if (require.main === module) {
  generateWithPrefixes().catch(err => {
    console.error('❌ Failed to generate OpenAPI spec:', err);
    process.exit(1);
  });
}
