import { NextResponse } from 'next/server'
import { join } from 'path'
import { readFileSync, existsSync, readdirSync } from 'fs'
import matter from 'gray-matter'

/**
 * llms.txt - Documentation index for LLMs
 * 
 * Generated from docs.json configuration.
 * Helps LLMs understand and index your documentation structure.
 */

const DOCS_DIR = join(process.cwd(), 'templates', 'starter')
const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'

interface NavigationTab {
  tab: string
  type: 'docs' | 'openapi' | 'changelog'
  path?: string
  groups?: Array<{
    group: string
    pages: string[]
  }>
  versions?: Array<{
    version: string
    spec: string
    default?: boolean
  }>
}

interface DocsConfig {
  name?: string
  navigation?: {
    tabs?: NavigationTab[]
  }
}

interface OpenAPISpec {
  info?: {
    title?: string
    description?: string
    version?: string
  }
  paths?: Record<string, Record<string, {
    summary?: string
    description?: string
    operationId?: string
    tags?: string[]
  }>>
}

function loadDocsConfig(): DocsConfig | null {
  const configPath = join(DOCS_DIR, 'docs.json')
  if (!existsSync(configPath)) return null
  
  try {
    const content = readFileSync(configPath, 'utf-8')
    return JSON.parse(content)
  } catch {
    return null
  }
}

function loadOpenAPISpec(specPath: string): OpenAPISpec | null {
  const fullPath = join(DOCS_DIR, specPath)
  if (!existsSync(fullPath)) return null
  
  try {
    const content = readFileSync(fullPath, 'utf-8')
    return JSON.parse(content)
  } catch {
    return null
  }
}

function getPageFrontmatter(slug: string): { title?: string; description?: string } {
  const extensions = ['.mdx', '.md']
  
  for (const ext of extensions) {
    const filePath = join(DOCS_DIR, `${slug}${ext}`)
    if (existsSync(filePath)) {
      try {
        const content = readFileSync(filePath, 'utf-8')
        const { data } = matter(content)
        return {
          title: data.title as string | undefined,
          description: data.description as string | undefined,
        }
      } catch {
        return {}
      }
    }
  }
  return {}
}

function getChangelogFiles(): Array<{ version: string; title?: string; description?: string }> {
  const changelogDir = join(DOCS_DIR, 'changelog')
  if (!existsSync(changelogDir)) return []
  
  try {
    return readdirSync(changelogDir)
      .filter(f => (f.endsWith('.mdx') || f.endsWith('.md')) && f !== 'latest.mdx')
      .map(f => {
        const version = f.replace(/\.(mdx?|md)$/, '')
        const frontmatter = getPageFrontmatter(`changelog/${version}`)
        return {
          version,
          title: frontmatter.title,
          description: frontmatter.description,
        }
      })
      .sort((a, b) => b.version.localeCompare(a.version))
  } catch {
    return []
  }
}

function generateDocsSection(tab: NavigationTab, lines: string[]) {
  lines.push(`## ${tab.tab}`)
  lines.push('')
  
  if (tab.groups) {
    for (const group of tab.groups) {
      lines.push(`### ${group.group}`)
      lines.push('')
      
      for (const page of group.pages) {
        const frontmatter = getPageFrontmatter(page)
        const title = frontmatter.title || page.split('/').pop() || page
        const urlPath = page === 'index' ? '' : page
        const url = `${BASE_URL}/#${tab.tab.toLowerCase()}/page/${urlPath}`.replace(/\/+$/, '')
        
        if (frontmatter.description) {
          lines.push(`- [${title}](${url}): ${frontmatter.description}`)
        } else {
          lines.push(`- [${title}](${url})`)
        }
      }
      lines.push('')
    }
  }
}

function generateOpenAPISection(tab: NavigationTab, lines: string[]) {
  lines.push(`## ${tab.tab}`)
  lines.push('')
  
  if (tab.versions && tab.versions.length > 0) {
    for (const version of tab.versions) {
      const spec = loadOpenAPISpec(version.spec)
      if (!spec) continue
      
      const versionLabel = version.default ? `${version.version} (current)` : version.version
      lines.push(`### ${versionLabel}`)
      lines.push('')
      
      if (spec.info?.description) {
        lines.push(`> ${spec.info.description}`)
        lines.push('')
      }
      
      // Group endpoints by tag or list all
      if (spec.paths) {
        const endpoints: Array<{ method: string; path: string; summary?: string }> = []
        
        for (const [path, methods] of Object.entries(spec.paths)) {
          for (const [method, details] of Object.entries(methods)) {
            if (['get', 'post', 'put', 'patch', 'delete'].includes(method.toLowerCase())) {
              endpoints.push({
                method: method.toUpperCase(),
                path,
                summary: details.summary || details.description,
              })
            }
          }
        }
        
        for (const endpoint of endpoints) {
          if (endpoint.summary) {
            lines.push(`- **${endpoint.method}** \`${endpoint.path}\`: ${endpoint.summary}`)
          } else {
            lines.push(`- **${endpoint.method}** \`${endpoint.path}\``)
          }
        }
        lines.push('')
      }
    }
  }
}

function generateChangelogSection(tab: NavigationTab, lines: string[]) {
  lines.push(`## ${tab.tab}`)
  lines.push('')
  
  const releases = getChangelogFiles()
  
  if (releases.length > 0) {
    for (const release of releases) {
      const title = release.title || `Version ${release.version}`
      const url = `${BASE_URL}/#changelog/page/changelog/${release.version}`
      
      if (release.description) {
        lines.push(`- [${title}](${url}): ${release.description}`)
      } else {
        lines.push(`- [${title}](${url})`)
      }
    }
  } else {
    lines.push('- No releases found')
  }
  lines.push('')
}

function generateLlmsTxt(config: DocsConfig): string {
  const lines: string[] = []
  
  // Header
  const siteName = config.name || 'Documentation'
  lines.push(`# ${siteName}`)
  lines.push('')
  lines.push('> Documentation index for LLMs. For full content, see /llms-full.txt')
  lines.push('')
  
  // Process each tab from config
  if (config.navigation?.tabs) {
    for (const tab of config.navigation.tabs) {
      switch (tab.type) {
        case 'docs':
          generateDocsSection(tab, lines)
          break
        case 'openapi':
          generateOpenAPISection(tab, lines)
          break
        case 'changelog':
          generateChangelogSection(tab, lines)
          break
      }
    }
  }
  
  return lines.join('\n')
}

export async function GET() {
  try {
    // Check for custom llms.txt first
    const customPath = join(DOCS_DIR, 'llms.txt')
    if (existsSync(customPath)) {
      const customContent = readFileSync(customPath, 'utf-8')
      return new NextResponse(customContent, {
        headers: {
          'Content-Type': 'text/plain; charset=utf-8',
          'Cache-Control': 'public, max-age=3600',
        },
      })
    }
    
    // Generate from docs.json config
    const config = loadDocsConfig()
    if (!config) {
      return new NextResponse('# Documentation\n\nNo docs.json configuration found.', {
        headers: { 'Content-Type': 'text/plain; charset=utf-8' },
      })
    }
    
    const content = generateLlmsTxt(config)
    
    return new NextResponse(content, {
      headers: {
        'Content-Type': 'text/plain; charset=utf-8',
        'Cache-Control': 'public, max-age=3600',
      },
    })
  } catch (error) {
    console.error('Error generating llms.txt:', error)
    return new NextResponse('Error generating llms.txt', { status: 500 })
  }
}
