/**
 * Translation Registry Generator
 *
 * Generates translation-registry.ts
 *
 * @module core/scripts/build/registry/generators/translation-registry
 */

import { existsSync, readdirSync, statSync } from 'fs'
import { join } from 'path'

/**
 * Detect locale entries from a messages directory
 * Supports both directory pattern (en/, es/ with index.ts) and flat file pattern (en.json, es.json)
 * Directory pattern takes precedence if both exist
 *
 * @param {string} messagesDir - Path to the messages directory
 * @returns {Array<{locale: string, isDirectory: boolean}>} Detected locales with their type
 */
function detectLocales(messagesDir) {
  if (!existsSync(messagesDir)) {
    return []
  }

  const entries = readdirSync(messagesDir)
  const locales = new Map() // Use Map to ensure directory takes precedence

  entries.forEach(entry => {
    const entryPath = join(messagesDir, entry)
    const stat = statSync(entryPath)

    if (stat.isDirectory()) {
      // Directory pattern: check for index.ts
      const indexPath = join(entryPath, 'index.ts')
      if (existsSync(indexPath)) {
        // Directory pattern takes precedence
        locales.set(entry, { locale: entry, isDirectory: true })
      }
    } else if (entry.endsWith('.json')) {
      // Flat file pattern (only if directory doesn't exist)
      const locale = entry.replace(/\.json$/, '')
      if (!locales.has(locale)) {
        locales.set(locale, { locale, isDirectory: false })
      }
    }
  })

  return Array.from(locales.values())
}

/**
 * Generate Translation Registry
 * Auto-generates lazy-loading functions for theme translations
 * Preserves i18n performance (only loads active locale)
 * Ensures ZERO runtime string interpolation in dynamic imports
 *
 * @param {Array} themes - Discovered themes
 * @param {object} config - Configuration object from getConfig()
 * @returns {string} Generated TypeScript content
 */
export function generateTranslationRegistry(themes, config) {
  // Discover all translation files from themes
  const themeTranslations = []
  // Discover entity translations
  const entityTranslations = []

  themes.forEach(theme => {
    const messagesDir = join(config.contentsDir, 'themes', theme.name, 'messages')
    const entitiesDir = join(config.contentsDir, 'themes', theme.name, 'entities')

    // Scan theme-level translations
    const locales = detectLocales(messagesDir)
    locales.forEach(({ locale, isDirectory }) => {
      // For directory pattern, import from the directory (index.ts)
      // For flat file pattern, import the .json file
      const filePath = isDirectory
        ? `@/contents/themes/${theme.name}/messages/${locale}`
        : `@/contents/themes/${theme.name}/messages/${locale}.json`

      themeTranslations.push({
        themeName: theme.name,
        locale,
        filePath,
        isDirectory,
        importKey: `theme_${theme.name.replace(/-/g, '_')}_${locale.replace(/-/g, '_')}`
      })
    })

    // Scan entity-level translations
    if (existsSync(entitiesDir)) {
      const entityDirs = readdirSync(entitiesDir).filter(entry => {
        const entryPath = join(entitiesDir, entry)
        return statSync(entryPath).isDirectory()
      })

      entityDirs.forEach(entityName => {
        const entityMessagesDir = join(entitiesDir, entityName, 'messages')
        if (existsSync(entityMessagesDir)) {
          const entityLocaleFiles = readdirSync(entityMessagesDir).filter(f => f.endsWith('.json'))

          entityLocaleFiles.forEach(file => {
            const locale = file.replace(/\.json$/, '')
            entityTranslations.push({
              themeName: theme.name,
              entityName,
              locale,
              filePath: `@/contents/themes/${theme.name}/entities/${entityName}/messages/${file}`,
              importKey: `entity_${theme.name.replace(/-/g, '_')}_${entityName.replace(/-/g, '_')}_${locale.replace(/-/g, '_')}`
            })
          })
        }
      })
    }
  })

  // Generate theme loader functions (lazy-loading for performance)
  const loaderEntries = {}

  themeTranslations.forEach(translation => {
    if (!loaderEntries[translation.themeName]) {
      loaderEntries[translation.themeName] = []
    }
    loaderEntries[translation.themeName].push(
      `    '${translation.locale}': () => import('${translation.filePath}')`
    )
  })

  const loadersCode = Object.entries(loaderEntries)
    .map(([themeName, loaders]) => {
      return `  '${themeName}': {\n${loaders.join(',\n')}\n  }`
    })
    .join(',\n')

  // Generate entity loader functions
  // Structure: { themeName: { entityName: { locale: loader } } }
  const entityLoaderEntries = {}

  entityTranslations.forEach(translation => {
    if (!entityLoaderEntries[translation.themeName]) {
      entityLoaderEntries[translation.themeName] = {}
    }
    if (!entityLoaderEntries[translation.themeName][translation.entityName]) {
      entityLoaderEntries[translation.themeName][translation.entityName] = []
    }
    entityLoaderEntries[translation.themeName][translation.entityName].push(
      `      '${translation.locale}': () => import('${translation.filePath}')`
    )
  })

  const entityLoadersCode = Object.entries(entityLoaderEntries)
    .map(([themeName, entities]) => {
      const entitiesCode = Object.entries(entities)
        .map(([entityName, loaders]) => {
          return `    '${entityName}': {\n${loaders.join(',\n')}\n    }`
        })
        .join(',\n')
      return `  '${themeName}': {\n${entitiesCode}\n  }`
    })
    .join(',\n')

  // Count unique entities
  const uniqueEntities = new Set(entityTranslations.map(t => `${t.themeName}:${t.entityName}`))

  return `/**
 * Auto-generated Translation Registry
 *
 * Generated at: ${new Date().toISOString()}
 * Themes with translations: ${Object.keys(loaderEntries).length}
 * Total theme translation files: ${themeTranslations.length}
 * Total entity translation files: ${entityTranslations.length}
 * Total entities with translations: ${uniqueEntities.size}
 *
 * DO NOT EDIT - This file is auto-generated by scripts/build-registry.mjs
 *
 * ZERO runtime string interpolation - all translation paths resolved at build time.
 * Preserves lazy-loading performance (only loads active locale).
 * Provides build-time validation and type safety.
 */

export type TranslationLoader = () => Promise<{ default: Record<string, unknown> } | Record<string, unknown>>

/**
 * Theme Translation Loaders Registry
 * Access: THEME_TRANSLATION_LOADERS['theme-name']['locale']()
 *
 * Returns lazy-loading functions that only execute when called.
 * This preserves i18n performance - only active locale is loaded.
 */
export const THEME_TRANSLATION_LOADERS: Record<string, Record<string, TranslationLoader>> = {
${loadersCode || '  // No theme translations discovered'}
}

/**
 * Entity Translation Loaders Registry
 * Access: ENTITY_TRANSLATION_LOADERS['theme-name']['entity-name']['locale']()
 *
 * Returns lazy-loading functions for entity-specific translations.
 * Structure: theme -> entity -> locale -> loader
 */
export const ENTITY_TRANSLATION_LOADERS: Record<string, Record<string, Record<string, TranslationLoader>>> = {
${entityLoadersCode || '  // No entity translations discovered'}
}

/**
 * Translation registry metadata
 */
export const TRANSLATION_METADATA = {
  totalThemes: ${Object.keys(loaderEntries).length},
  totalThemeTranslations: ${themeTranslations.length},
  totalEntityTranslations: ${entityTranslations.length},
  totalEntitiesWithTranslations: ${uniqueEntities.size},
  generatedAt: '${new Date().toISOString()}',
  themes: [${Object.keys(loaderEntries).map(t => `'${t}'`).join(', ')}],
  entities: [${Array.from(uniqueEntities).map(e => `'${e}'`).join(', ')}]
}
`
}
