import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(__dirname, '..')

interface JSONComponent {
  type: string
  jsonCompatible?: boolean
  wrapperRequired?: boolean
  load?: {
    path: string
    export: string
    lazy?: boolean
  }
  props?: Record<string, unknown>
  metadata?: {
    notes?: string
  }
}

interface RegistryEntry {
  type: string
  name: string
  category: string
  canHaveChildren: boolean
  description: string
  status: 'supported' | 'deprecated'
  source: 'atoms' | 'molecules' | 'organisms' | 'ui' | 'wrappers' | 'custom'
  jsonCompatible: boolean
  wrapperRequired?: boolean
  load?: {
    path: string
    export: string
    lazy?: boolean
  }
  metadata?: {
    conversionDate?: string
    autoGenerated?: boolean
    notes?: string
  }
}

interface Registry {
  version: string
  categories: Record<string, string>
  sourceRoots: Record<string, string[]>
  components: RegistryEntry[]
  statistics: {
    total: number
    supported: number
    jsonCompatible: number
    byCategory: Record<string, number>
    bySource: Record<string, number>
  }
}

/**
 * Determine component category based on name and source
 */
function determineCategory(componentName: string, source: string): string {
  const name = componentName.toLowerCase()

  // Layout components
  if (/container|section|stack|flex|grid|layout|panel|sidebar|header|footer/.test(name)) {
    return 'layout'
  }

  // Input components
  if (/input|select|checkbox|radio|slider|switch|form|textarea|date|file|number|password|search/.test(name)) {
    return 'input'
  }

  // Navigation components
  if (/nav|menu|breadcrumb|tab|link|pagination/.test(name)) {
    return 'navigation'
  }

  // Feedback components
  if (/alert|toast|notification|spinner|loading|progress|skeleton|badge|indicator/.test(name)) {
    return 'feedback'
  }

  // Data display components
  if (/table|list|card|chart|graph|tree|timeline|avatar|image/.test(name)) {
    return 'data'
  }

  // Display components
  if (/text|heading|label|code|icon|divider|separator|spacer/.test(name)) {
    return 'display'
  }

  // Default to custom for organisms and complex components
  if (source === 'organisms' || source === 'molecules') {
    return 'custom'
  }

  return 'display'
}

/**
 * Determine if component can have children
 */
function canHaveChildren(componentName: string): boolean {
  const name = componentName.toLowerCase()

  // These typically don't have children
  const noChildren = /input|select|checkbox|radio|slider|switch|image|icon|divider|separator|spacer|spinner|progress|badge|dot/

  return !noChildren.test(name)
}

/**
 * Generate description for component
 */
function generateDescription(componentName: string, category: string): string {
  const descriptions: Record<string, string> = {
    layout: 'Layout container component',
    input: 'Form input component',
    navigation: 'Navigation component',
    feedback: 'Feedback and status component',
    data: 'Data display component',
    display: 'Display component',
    custom: 'Custom component',
  }

  return descriptions[category] || 'Component'
}

/**
 * Read all JSON files from a directory and create registry entries
 */
async function processDirectory(
  dir: string,
  source: 'atoms' | 'molecules' | 'organisms' | 'ui' | 'custom'
): Promise<RegistryEntry[]> {
  const entries: RegistryEntry[] = []

  try {
    const files = await fs.readdir(dir)
    const jsonFiles = files.filter(f => f.endsWith('.json'))

    for (const file of jsonFiles) {
      const filePath = path.join(dir, file)
      const content = await fs.readFile(filePath, 'utf-8')
      const jsonComponent: JSONComponent = JSON.parse(content)

      const componentName = jsonComponent.type
      if (!componentName) continue

      const category = determineCategory(componentName, source)

      const entry: RegistryEntry = {
        type: componentName,
        name: componentName,
        category,
        canHaveChildren: canHaveChildren(componentName),
        description: generateDescription(componentName, category),
        status: 'supported',
        source,
        jsonCompatible: jsonComponent.jsonCompatible !== false,
        wrapperRequired: jsonComponent.wrapperRequired || false,
        metadata: {
          conversionDate: new Date().toISOString().split('T')[0],
          autoGenerated: true,
          notes: jsonComponent.metadata?.notes,
        },
      }

      if (jsonComponent.load) {
        entry.load = jsonComponent.load
      }

      entries.push(entry)
    }
  } catch (error) {
    console.error(`Error processing ${dir}:`, error)
  }

  return entries
}

/**
 * Update the registry with new components
 */
async function updateRegistry() {
  console.log('📝 Updating json-components-registry.json...\n')

  const registryPath = path.join(rootDir, 'json-components-registry.json')

  // Read existing registry
  const registryContent = await fs.readFile(registryPath, 'utf-8')
  const registry: Registry = JSON.parse(registryContent)

  console.log(`   Current components: ${registry.components.length}`)

  // Process each directory
  const newEntries: RegistryEntry[] = []

  const directories = [
    { dir: path.join(rootDir, 'src/config/pages/atoms'), source: 'atoms' as const },
    { dir: path.join(rootDir, 'src/config/pages/molecules'), source: 'molecules' as const },
    { dir: path.join(rootDir, 'src/config/pages/organisms'), source: 'organisms' as const },
    { dir: path.join(rootDir, 'src/config/pages/ui'), source: 'ui' as const },
    { dir: path.join(rootDir, 'src/config/pages/components'), source: 'custom' as const },
  ]

  for (const { dir, source } of directories) {
    const entries = await processDirectory(dir, source)
    newEntries.push(...entries)
    console.log(`   Processed ${source}: ${entries.length} components`)
  }

  // Merge with existing components (remove duplicates)
  const existingTypes = new Set(registry.components.map(c => c.type))
  const uniqueNewEntries = newEntries.filter(e => !existingTypes.has(e.type))

  console.log(`\n   New unique components: ${uniqueNewEntries.length}`)
  console.log(`   Skipped duplicates: ${newEntries.length - uniqueNewEntries.length}`)

  // Add new components
  registry.components.push(...uniqueNewEntries)

  // Update statistics
  const byCategory: Record<string, number> = {}
  const bySource: Record<string, number> = {}

  for (const component of registry.components) {
    byCategory[component.category] = (byCategory[component.category] || 0) + 1
    bySource[component.source] = (bySource[component.source] || 0) + 1
  }

  registry.statistics = {
    total: registry.components.length,
    supported: registry.components.filter(c => c.status === 'supported').length,
    jsonCompatible: registry.components.filter(c => c.jsonCompatible).length,
    byCategory,
    bySource,
  }

  // Sort components by type
  registry.components.sort((a, b) => a.type.localeCompare(b.type))

  // Write updated registry
  await fs.writeFile(registryPath, JSON.stringify(registry, null, 2) + '\n')

  console.log(`\n✅ Registry updated successfully!`)
  console.log(`   Total components: ${registry.statistics.total}`)
  console.log(`   JSON compatible: ${registry.statistics.jsonCompatible}`)
  console.log(`\n📊 By source:`)
  for (const [source, count] of Object.entries(bySource)) {
    console.log(`   ${source.padEnd(12)}: ${count}`)
  }
  console.log(`\n📊 By category:`)
  for (const [category, count] of Object.entries(byCategory)) {
    console.log(`   ${category.padEnd(12)}: ${count}`)
  }
}

updateRegistry().catch(console.error)
