import fs from 'fs/promises'
import path from 'path'

interface JsonObject {
  [key: string]: any
}

/**
 * Recursively flattens a JSON object into dot-notation paths with array indices
 * Example: { a: { b: ["x", "y"] } } => ["a.b[0]", "a.b[1]"]
 */
function flattenKeys(obj: JsonObject, prefix = ''): string[] {
  const keys: string[] = []

  for (const [key, value] of Object.entries(obj)) {
    const newPrefix = prefix ? `${prefix}.${key}` : key

    if (Array.isArray(value)) {
      // For arrays, create keys with indices
      value.forEach((_, index) => {
        keys.push(`${newPrefix}[${index}]`)
      })
    } else if (typeof value === 'object' && value !== null) {
      // Recursively process nested objects
      keys.push(...flattenKeys(value, newPrefix))
    } else {
      // Leaf node (string/number/boolean/null)
      keys.push(newPrefix)
    }
  }

  return keys
}

/**
 * Reads all JSON files from a directory and returns flattened keys
 */
async function getKeysFromDirectory(dirPath: string): Promise<Set<string>> {
  const allKeys = new Set<string>()

  try {
    const entries = await fs.readdir(dirPath, { withFileTypes: true })

    for (const entry of entries) {
      const fullPath = path.join(dirPath, entry.name)

      if (entry.isDirectory()) {
        // Recursively process subdirectories
        const subKeys = await getKeysFromDirectory(fullPath)
        subKeys.forEach(key => allKeys.add(key))
      } else if (entry.isFile() && entry.name.endsWith('.json')) {
        // Process JSON file
        const content = await fs.readFile(fullPath, 'utf-8')
        const json = JSON.parse(content)
        const keys = flattenKeys(json)
        keys.forEach(key => allKeys.add(key))
      }
    }
  } catch (error) {
    console.error(`Error reading directory ${dirPath}:`, error)
  }

  return allKeys
}

export async function generateLanguageTypes(rootDir: string) {
  const localesDir = path.join(rootDir, 'packages/functions/locales')

  // Get all unique translation keys
  const allKeys = await getKeysFromDirectory(localesDir)

  // Sort keys for consistent output
  const sortedKeys = Array.from(allKeys).sort()

  // Generate TypeScript type definition
  const typeDefinition = `/**
 * Auto-generated translation token types
 * @generated - DO NOT EDIT MANUALLY
 */

export type TranslationTokens =
${sortedKeys.map(key => `  | '${key}'`).join('\n')}

/**
 * Alias for backwards compatibility
 */
export type Tokens = TranslationTokens
`

  // Write to file
  const outputPath = path.join(rootDir, 'packages/functions/src/engines/language.types.gen.d.ts')
  await fs.writeFile(outputPath, typeDefinition, 'utf-8')

  console.log(`✅ Generated language types with ${sortedKeys.length} tokens`)
  console.log(`📝 Output: ${outputPath}`)
}
