/**
 * Vue File Parser
 * Extracts <template>, <script setup>, <style> from .vue files
 * and converts them into VueComponentDefinition objects.
 */

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

export interface VueComponentDefinition {
  id: string
  name: string
  template: string
  setup?: string
  style?: string
  props?: string[]
  imports?: string[]
  tags?: string[]
  folder: string
}

export interface ComponentMeta {
  name?: string
  tags?: string[]
  props?: string[]
  imports?: string[]
}

/**
 * Parse a .vue file content into template, setup, style sections
 */
export function parseVueFile(content: string): { template: string; setup: string; style: string } {
  const templateMatch = content.match(/<template>([\s\S]*?)<\/template>/)
  const scriptMatch = content.match(/<script\s+setup[^>]*>([\s\S]*?)<\/script>/)
  const styleMatch = content.match(/<style[^>]*>([\s\S]*?)<\/style>/)

  return {
    template: templateMatch?.[1]?.trim() || '',
    setup: scriptMatch?.[1]?.trim() || '',
    style: styleMatch?.[1]?.trim() || ''
  }
}

/**
 * Read optional meta.json from a component folder
 */
export function readMetaJson(folderPath: string): ComponentMeta | null {
  const metaPath = join(folderPath, 'meta.json')
  if (!existsSync(metaPath)) return null

  try {
    const raw = readFileSync(metaPath, 'utf-8')
    return JSON.parse(raw) as ComponentMeta
  } catch {
    return null
  }
}

/**
 * Parse a component folder into a VueComponentDefinition
 * Convention: user-components/counter-widget/CounterWidget.vue + optional meta.json
 */
export function parseComponentFolder(baseDir: string, folderName: string): VueComponentDefinition | null {
  const folderPath = join(baseDir, folderName)

  if (!existsSync(folderPath) || !statSync(folderPath).isDirectory()) return null

  // Find the .vue file in the folder
  const files = readdirSync(folderPath)
  const vueFile = files.find(f => f.endsWith('.vue'))
  if (!vueFile) return null

  const vueContent = readFileSync(join(folderPath, vueFile), 'utf-8')
  const { template, setup, style } = parseVueFile(vueContent)

  if (!template) return null

  const meta = readMetaJson(folderPath)

  // Derive name from meta or filename (CounterWidget.vue -> CounterWidget)
  const nameFromFile = vueFile.replace('.vue', '')
  const name = meta?.name || nameFromFile

  return {
    id: folderName,
    name,
    template,
    setup: setup || undefined,
    style: style || undefined,
    props: meta?.props,
    imports: meta?.imports,
    tags: meta?.tags,
    folder: folderName
  }
}

/**
 * List all component subdirectories and parse them
 */
export function listAllComponents(baseDir: string): VueComponentDefinition[] {
  if (!existsSync(baseDir)) return []

  const entries = readdirSync(baseDir)
  const components: VueComponentDefinition[] = []

  for (const entry of entries) {
    const fullPath = join(baseDir, entry)
    if (!statSync(fullPath).isDirectory()) continue

    const component = parseComponentFolder(baseDir, entry)
    if (component) {
      components.push(component)
    }
  }

  return components
}
