/**
 * Code Generation Utility
 * Generates code snippets for API requests in various languages
 * Uses server-side API route to run httpsnippet (avoids browser compatibility issues)
 */

import type { BrainfishRESTRequest } from '../types'
import { buildHarRequest } from './har'
import { CodegenDefinitions, findCodegenByName, type CodegenName } from './definitions'

export { CodegenDefinitions, findCodegenByName, getCodegenByCategory } from './definitions'
export type { CodegenName, CodegenDefinition, CodegenCategory } from './definitions'

export interface CodegenResult {
  success: boolean
  code?: string
  error?: string
}

/**
 * Generate code snippet for a request (async - calls server API)
 * @param codegenName The codegen target name (e.g., 'shell-curl', 'javascript-fetch')
 * @param request The Brainfish REST request to generate code for
 * @returns Promise<CodegenResult> with generated code or error
 */
export async function generateCodeAsync(
  codegenName: CodegenName,
  request: BrainfishRESTRequest
): Promise<CodegenResult> {
  try {
    const codegenInfo = findCodegenByName(codegenName)
    
    if (!codegenInfo) {
      return {
        success: false,
        error: `Unknown code generator: ${codegenName}`,
      }
    }

    // Build HAR request from Brainfish request
    const harRequest = buildHarRequest(request)

    // Call server-side API to generate code
    const response = await fetch('/api/codegen', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        harRequest,
        lang: codegenInfo.lang,
        client: codegenInfo.client,
      }),
    })

    const result = await response.json()
    
    if (result.success) {
      return {
        success: true,
        code: result.code,
      }
    }

    return {
      success: false,
      error: result.error || 'Code generation failed',
    }
  } catch (error) {
    console.error('Code generation error:', error)
    return {
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error during code generation',
    }
  }
}

/**
 * Synchronous version that returns a placeholder - use generateCodeAsync for actual code
 * This exists for backwards compatibility with synchronous code
 */
export function generateCode(
  codegenName: CodegenName,
  request: BrainfishRESTRequest
): CodegenResult {
  // For synchronous calls, we can't make API requests
  // Return a placeholder that indicates async is needed
  const codegenInfo = findCodegenByName(codegenName)
  
  if (!codegenInfo) {
    return {
      success: false,
      error: `Unknown code generator: ${codegenName}`,
    }
  }

  // Generate a simple placeholder based on the request
  // This will be replaced by the async version in the UI
  const url = request.endpoint
  const method = request.method

  // Simple cURL as fallback
  let code = `curl --request ${method} \\\n  --url '${url}'`
  
  request.headers.filter(h => h.active).forEach(h => {
    code += ` \\\n  --header '${h.key}: ${h.value}'`
  })

  if (request.body.body && method !== 'GET' && method !== 'HEAD') {
    const bodyStr = typeof request.body.body === 'string' 
      ? request.body.body 
      : JSON.stringify(request.body.body)
    code += ` \\\n  --data '${bodyStr}'`
  }

  return {
    success: true,
    code,
  }
}

/**
 * Get the Monaco editor language for a codegen target
 */
export function getMonacoLanguage(codegenName: CodegenName): string {
  const def = findCodegenByName(codegenName)
  if (!def) return 'plaintext'

  const languageMap: Record<string, string> = {
    shell: 'shell',
    javascript: 'javascript',
    node: 'javascript',
    python: 'python',
    go: 'go',
    java: 'java',
    csharp: 'csharp',
    ruby: 'ruby',
    php: 'php',
    swift: 'swift',
    kotlin: 'kotlin',
    rust: 'rust',
    c: 'c',
    powershell: 'powershell',
    clojure: 'clojure',
    objc: 'objective-c',
    ocaml: 'plaintext', // Monaco doesn't have OCaml
    r: 'r',
    http: 'plaintext',
  }

  return languageMap[def.lang] || 'plaintext'
}

/**
 * Get all available codegen targets
 */
export function getAvailableCodegens(): typeof CodegenDefinitions {
  return CodegenDefinitions
}
