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

// Get the directory name
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Directory containing JSON files
const databaseDir = path.join(__dirname, 'public', 'data', 'database');
const typesDir = path.join(__dirname, 'src', 'types');

// Get all JSON files in the directory
const jsonFiles = fs.readdirSync(databaseDir).filter(file =>
  file.toLowerCase().endsWith('.json')
);

console.log(`Found ${jsonFiles.length} JSON files to process.`);

// Files we've already created types for
const alreadyCreated = [
  'Races.json',
  'Professions.json',
  'Attributes.json',
  'Advantages.json',
  'AnimistForces.json',
  'ArcaneBardTraditions.json',
  'ArcaneDancerTraditions.json',
  'ArmorTypes.json'
];

// Process each JSON file
jsonFiles.forEach(jsonFile => {
  // Skip files we've already created types for
  if (alreadyCreated.includes(jsonFile)) {
    console.log(`Skipping ${jsonFile} (already created)`);
    return;
  }

  const jsonPath = path.join(databaseDir, jsonFile);
  const typeName = jsonFile.replace('.json', '');
  const singularTypeName = typeName.endsWith('s') ? typeName.slice(0, -1) : typeName;
  const typeFilePath = path.join(typesDir, `${singularTypeName}.ts`);

  try {
    // Read JSON file
    const jsonContent = fs.readFileSync(jsonPath, 'utf8');
    const data = JSON.parse(jsonContent);

    if (!Array.isArray(data) || data.length === 0) {
      console.log(`Skipping ${jsonFile} (empty or not an array)`);
      return;
    }

    // Get the first item to determine the structure
    const firstItem = data[0];
    const properties = Object.keys(firstItem);

    // Generate the interface
    let typeContent = `export interface ${singularTypeName} {\n`;
    properties.forEach(prop => {
      const value = firstItem[prop];
      let type = typeof value;

      // Handle special cases
      if (type === 'object') {
        if (value === null) {
          type = 'null';
        } else if (Array.isArray(value)) {
          type = 'any[]'; // or a more specific type if we can determine it
        } else {
          // Check if it's a nested object with known structure
          if (prop === 'src') {
            typeContent += `  ${prop}: ${singularTypeName}Source[];\n`;
            return;
          } else if (prop === 'name' && 'm' in value && 'f' in value) {
            typeContent += `  ${prop}: GenderedName;\n`;
            return;
          } else {
            type = 'Record<string, any>';
          }
        }
      }

      // Add optional marker if not all items have this property
      const isOptional = data.some(item => !(prop in item));
      typeContent += `  ${prop}${isOptional ? '?' : ''}: ${type};\n`;
    });
    typeContent += '}\n\n';

    // Add source interface if needed
    if (properties.includes('src')) {
      typeContent = `export interface ${singularTypeName}Source {\n  id: string | number;\n  firstPage: number;\n  lastPage?: number;\n}\n\n` + typeContent;
    }

    // Add gendered name interface if needed
    if (properties.includes('name') && typeof firstItem.name === 'object' && 'm' in firstItem.name && 'f' in firstItem.name) {
      typeContent = `export interface GenderedName {\n  m: string;\n  f: string;\n}\n\n` + typeContent;
    }

    // Add the type alias for the array
    typeContent += `export type ${typeName} = ${singularTypeName}[];\n`;

    // Write the type definition file
    fs.writeFileSync(typeFilePath, typeContent);

    console.log(`Created type definition for ${jsonFile} at ${typeFilePath}`);
  } catch (error) {
    console.error(`Error processing ${jsonFile}:`, error);
  }
});

console.log('Type generation complete!');
