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

/**
 * llms-full.txt - Full documentation content for LLMs
 * 
 * Generated from docs.json configuration.
 * Combines all documentation into a single file for LLM consumption.
 */

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
    parameters?: Array<{
      name: string
      in: string
      description?: string
      required?: boolean
      schema?: { type?: string }
    }>
    requestBody?: {
      description?: string
      content?: Record<string, { schema?: object }>
    }
    responses?: Record<string, {
      description?: 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 getPageContent(slug: string): { title?: string; description?: string; content: string } | null {
  const extensions = ['.mdx', '.md']
  
  for (const ext of extensions) {
    const filePath = join(DOCS_DIR, `${slug}${ext}`)
    if (existsSync(filePath)) {
      try {
        const fileContent = readFileSync(filePath, 'utf-8')
        const { data, content } = matter(fileContent)
        
        // Clean MDX content - remove JSX components
        const cleanedContent = content
          .replace(/<[A-Z][a-zA-Z]*[^>]*\/>/g, '')  // Self-closing JSX
          .replace(/<[A-Z][a-zA-Z]*[^>]*>[\s\S]*?<\/[A-Z][a-zA-Z]*>/g, '')  // JSX with children
          .replace(/<!--[\s\S]*?-->/g, '')  // HTML comments
          .replace(/\n{3,}/g, '\n\n')  // Extra blank lines
          .trim()
        
        return {
          title: data.title as string | undefined,
          description: data.description as string | undefined,
          content: cleanedContent,
        }
      } catch {
        return null
      }
    }
  }
  return null
}

function getChangelogFiles(): 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 => f.replace(/\.(mdx?|md)$/, ''))
      .sort()
      .reverse()
  } catch {
    return []
  }
}

function generateDocsContent(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 pageData = getPageContent(page)
        if (pageData) {
          lines.push(`### ${pageData.title || page}`)
          lines.push('')
          
          if (pageData.description) {
            lines.push(`> ${pageData.description}`)
            lines.push('')
          }
          
          const urlPath = page === 'index' ? '' : page
          lines.push(`URL: ${BASE_URL}/#${tab.tab.toLowerCase()}/page/${urlPath}`)
          lines.push('')
          
          if (pageData.content) {
            lines.push(pageData.content)
            lines.push('')
          }
          
          lines.push('---')
          lines.push('')
        }
      }
    }
  }
}

function generateOpenAPIContent(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?.title) {
        lines.push(`**${spec.info.title}**`)
        lines.push('')
      }
      
      if (spec.info?.description) {
        lines.push(spec.info.description)
        lines.push('')
      }
      
      // List all endpoints with details
      if (spec.paths) {
        lines.push('### Endpoints')
        lines.push('')
        
        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())) continue
            
            lines.push(`#### ${method.toUpperCase()} ${path}`)
            lines.push('')
            
            if (details.summary) {
              lines.push(`**${details.summary}**`)
              lines.push('')
            }
            
            if (details.description) {
              lines.push(details.description)
              lines.push('')
            }
            
            // Parameters
            if (details.parameters && details.parameters.length > 0) {
              lines.push('**Parameters:**')
              for (const param of details.parameters) {
                const required = param.required ? ' (required)' : ''
                const desc = param.description ? `: ${param.description}` : ''
                lines.push(`- \`${param.name}\` (${param.in})${required}${desc}`)
              }
              lines.push('')
            }
            
            // Request body
            if (details.requestBody?.description) {
              lines.push(`**Request Body:** ${details.requestBody.description}`)
              lines.push('')
            }
            
            // Responses
            if (details.responses) {
              lines.push('**Responses:**')
              for (const [code, response] of Object.entries(details.responses)) {
                lines.push(`- ${code}: ${response.description || 'No description'}`)
              }
              lines.push('')
            }
            
            lines.push('---')
            lines.push('')
          }
        }
      }
    }
  }
}

function generateChangelogContent(tab: NavigationTab, lines: string[]) {
  lines.push(`# ${tab.tab}`)
  lines.push('')
  
  const versions = getChangelogFiles()
  
  for (const version of versions) {
    const pageData = getPageContent(`changelog/${version}`)
    if (pageData) {
      lines.push(`## ${pageData.title || `Version ${version}`}`)
      lines.push('')
      
      if (pageData.description) {
        lines.push(`> ${pageData.description}`)
        lines.push('')
      }
      
      if (pageData.content) {
        lines.push(pageData.content)
        lines.push('')
      }
      
      lines.push('---')
      lines.push('')
    }
  }
}

function generateLlmsFullTxt(config: DocsConfig): string {
  const lines: string[] = []
  
  // Header
  const siteName = config.name || 'Documentation'
  lines.push(`# ${siteName} - Full Documentation`)
  lines.push('')
  lines.push('> Complete documentation content for LLM consumption.')
  lines.push('')
  lines.push('---')
  lines.push('')
  
  // Process each tab from config
  if (config.navigation?.tabs) {
    for (const tab of config.navigation.tabs) {
      switch (tab.type) {
        case 'docs':
          generateDocsContent(tab, lines)
          break
        case 'openapi':
          generateOpenAPIContent(tab, lines)
          break
        case 'changelog':
          generateChangelogContent(tab, lines)
          break
      }
    }
  }
  
  return lines.join('\n')
}

export async function GET() {
  try {
    // Check for custom llms-full.txt first
    const customPath = join(DOCS_DIR, 'llms-full.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 = generateLlmsFullTxt(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-full.txt:', error)
    return new NextResponse('Error generating llms-full.txt', { status: 500 })
  }
}
