<template>
  <div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 p-4">
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-6xl h-full max-h-[95vh] flex flex-col">
      <!-- Header -->
      <div class="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
        <div class="flex items-center gap-3">
          <Icon name="ic:outline-code" size="24" class="text-primary-600" />
          <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Code Generation</h3>
        </div>
        <rs-button
          variant="text"
          size="sm"
          @click="$emit('close')"
          class="p-2"
        >
          <Icon name="ic:outline-close" size="16" />
        </rs-button>
      </div>

      <!-- Content -->
      <div class="flex flex-1 overflow-hidden min-h-0">
        <!-- Language/Framework Selector -->
        <div class="w-64 border-r border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex-shrink-0 flex flex-col">
          <div class="p-4 border-b border-gray-200 dark:border-gray-700">
            <h4 class="font-medium text-gray-900 dark:text-white">Select Language</h4>
          </div>
          <div class="flex-1 overflow-y-auto p-4 space-y-1">
            <button
              v-for="lang in languages"
              :key="lang.id"
              @click="selectedLanguage = lang.id"
              :class="[
                'w-full text-left p-3 rounded-lg transition-colors flex items-center gap-3',
                selectedLanguage === lang.id
                  ? 'bg-primary-100 text-primary-900 dark:bg-primary-900 dark:text-primary-100'
                  : 'hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300'
              ]"
            >
              <Icon :name="lang.icon" size="20" />
              <div class="min-w-0">
                <div class="font-medium truncate">{{ lang.name }}</div>
                <div class="text-xs opacity-70 truncate">{{ lang.description }}</div>
              </div>
            </button>
          </div>
        </div>

        <!-- Code Display -->
        <div class="flex-1 flex flex-col min-w-0">
          <!-- Code Header -->
          <div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex-shrink-0">
            <div class="flex items-center justify-between">
              <div class="flex items-center gap-2 min-w-0">
                <Icon :name="currentLanguage.icon" size="16" />
                <span class="font-medium text-gray-900 dark:text-white truncate">{{ currentLanguage.name }}</span>
                <rs-badge variant="secondary" size="sm">{{ generatedCode.split('\n').length }} lines</rs-badge>
              </div>
              <div class="flex items-center gap-2 flex-shrink-0">
                <rs-button
                  variant="secondary-outline"
                  size="sm"
                  @click="copyToClipboard"
                  class="flex items-center gap-2"
                >
                  <Icon name="ic:outline-content-copy" size="16" />
                  Copy
                </rs-button>
                <rs-button
                  variant="secondary-outline"
                  size="sm"
                  @click="downloadCode"
                  class="flex items-center gap-2"
                >
                  <Icon name="ic:outline-download" size="16" />
                  Download
                </rs-button>
              </div>
            </div>
          </div>

          <!-- Code Content -->
          <div class="flex-1 overflow-hidden p-4 min-h-0">
            <pre 
              class="text-sm bg-gray-50 dark:bg-gray-900 p-4 rounded-lg whitespace-pre-wrap border font-mono leading-relaxed w-full h-full overflow-auto resize-none"
              :class="`language-${currentLanguage.highlightLanguage}`"
            >{{ generatedCode }}</pre>
          </div>
        </div>
      </div>

      <!-- Footer -->
      <div class="flex items-center justify-between p-6 border-t border-gray-200 dark:border-gray-700 flex-shrink-0">
        <div class="text-sm text-gray-500 dark:text-gray-400">
          Generated from current request configuration
        </div>
        <rs-button
          variant="primary"
          @click="$emit('close')"
        >
          Done
        </rs-button>
      </div>
    </div>
  </div>
</template>

<script setup>
const emit = defineEmits(['close'])

const {
  httpMethod,
  requestUrl,
  requestParams,
  requestHeaders,
  requestAuth,
  requestBody,
  showNotification
} = useApiPlatform()

const { copyToClipboard: copyToClipboardUtil } = useApiRequest()

const selectedLanguage = ref('curl')

const languages = [
  {
    id: 'curl',
    name: 'cURL',
    description: 'Command line tool',
    icon: 'ic:outline-terminal',
    highlightLanguage: 'bash'
  },
  {
    id: 'javascript-fetch',
    name: 'JavaScript (Fetch)',
    description: 'Modern JavaScript',
    icon: 'ic:outline-javascript',
    highlightLanguage: 'javascript'
  },
  {
    id: 'javascript-axios',
    name: 'JavaScript (Axios)',
    description: 'Popular HTTP client',
    icon: 'ic:outline-javascript',
    highlightLanguage: 'javascript'
  },
  {
    id: 'python-requests',
    name: 'Python (Requests)',
    description: 'Python HTTP library',
    icon: 'ic:outline-data-object',
    highlightLanguage: 'python'
  },
  {
    id: 'php-curl',
    name: 'PHP (cURL)',
    description: 'PHP with cURL',
    icon: 'ic:outline-language',
    highlightLanguage: 'php'
  },
  {
    id: 'node-http',
    name: 'Node.js (HTTP)',
    description: 'Native Node.js',
    icon: 'ic:outline-settings',
    highlightLanguage: 'javascript'
  },
  {
    id: 'java-okhttp',
    name: 'Java (OkHttp)',
    description: 'Java HTTP client',
    icon: 'ic:outline-coffee',
    highlightLanguage: 'java'
  },
  {
    id: 'go-http',
    name: 'Go (net/http)',
    description: 'Go standard library',
    icon: 'ic:outline-speed',
    highlightLanguage: 'go'
  }
]

const currentLanguage = computed(() => {
  return languages.find(lang => lang.id === selectedLanguage.value) || languages[0]
})

// Generate code based on current request
const generatedCode = computed(() => {
  const url = requestUrl.value || 'https://api.example.com/endpoint'
  const method = httpMethod.value
  const headers = requestHeaders.value.filter(h => h.active && h.key)
  const params = requestParams.value.filter(p => p.active && p.key)
  const body = requestBody.value
  const auth = requestAuth.value

  switch (selectedLanguage.value) {
    case 'curl':
      return generateCurl(url, method, headers, params, body, auth)
    case 'javascript-fetch':
      return generateJavaScriptFetch(url, method, headers, params, body, auth)
    case 'javascript-axios':
      return generateJavaScriptAxios(url, method, headers, params, body, auth)
    case 'python-requests':
      return generatePythonRequests(url, method, headers, params, body, auth)
    case 'php-curl':
      return generatePhpCurl(url, method, headers, params, body, auth)
    case 'node-http':
      return generateNodeHttp(url, method, headers, params, body, auth)
    case 'java-okhttp':
      return generateJavaOkHttp(url, method, headers, params, body, auth)
    case 'go-http':
      return generateGoHttp(url, method, headers, params, body, auth)
    default:
      return '// Code generation not available for this language'
  }
})

// Code generation functions
const generateCurl = (url, method, headers, params, body, auth) => {
  let code = `curl -X ${method}`
  
  // Add URL with params
  if (params.length > 0) {
    const queryString = params.map(p => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`).join('&')
    url += `?${queryString}`
  }
  code += ` \\\n  "${url}"`

  // Add headers
  headers.forEach(header => {
    code += ` \\\n  -H "${header.key}: ${header.value}"`
  })

  // Add auth
  if (auth.type === 'bearer' && auth.bearer) {
    code += ` \\\n  -H "Authorization: Bearer ${auth.bearer}"`
  } else if (auth.type === 'basic' && auth.basic.username) {
    code += ` \\\n  -u "${auth.basic.username}:${auth.basic.password}"`
  } else if (auth.type === 'apiKey' && auth.apiKey.key) {
    if (auth.apiKey.addTo === 'header') {
      code += ` \\\n  -H "${auth.apiKey.key}: ${auth.apiKey.value}"`
    }
  }

  // Add body
  if (body.type === 'raw' && body.raw) {
    code += ` \\\n  -H "Content-Type: application/json"`
    code += ` \\\n  -d '${body.raw}'`
  } else if (body.type === 'x-www-form-urlencoded' && body.urlEncoded.some(item => item.active && item.key)) {
    const formData = body.urlEncoded.filter(item => item.active && item.key)
      .map(item => `${encodeURIComponent(item.key)}=${encodeURIComponent(item.value)}`)
      .join('&')
    code += ` \\\n  -H "Content-Type: application/x-www-form-urlencoded"`
    code += ` \\\n  -d "${formData}"`
  }

  return code
}

const generateJavaScriptFetch = (url, method, headers, params, body, auth) => {
  let code = '// Using fetch API\n'
  
  // Build URL with params
  if (params.length > 0) {
    const queryString = params.map(p => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`).join('&')
    url += `?${queryString}`
  }

  code += `const url = '${url}';\n\n`

  // Build options object
  code += 'const options = {\n'
  code += `  method: '${method}',\n`
  
  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  } else if (auth.type === 'apiKey' && auth.apiKey.key && auth.apiKey.addTo === 'header') {
    allHeaders.push({ key: auth.apiKey.key, value: auth.apiKey.value })
  }

  if (allHeaders.length > 0) {
    code += '  headers: {\n'
    allHeaders.forEach(header => {
      code += `    '${header.key}': '${header.value}',\n`
    })
    code += '  },\n'
  }

  // Body
  if (body.type === 'raw' && body.raw) {
    code += `  body: ${body.raw}\n`
  } else if (body.type === 'x-www-form-urlencoded' && body.urlEncoded.some(item => item.active && item.key)) {
    const formData = body.urlEncoded.filter(item => item.active && item.key)
      .map(item => `${encodeURIComponent(item.key)}=${encodeURIComponent(item.value)}`)
      .join('&')
    code += `  body: '${formData}'\n`
  }

  code += '};\n\n'

  code += `fetch(url, options)\n`
  code += `  .then(response => response.json())\n`
  code += `  .then(data => console.log(data))\n`
  code += `  .catch(error => console.error('Error:', error));`

  return code
}

const generateJavaScriptAxios = (url, method, headers, params, body, auth) => {
  let code = '// Using Axios\n'
  code += "import axios from 'axios';\n\n"

  code += 'const config = {\n'
  code += `  method: '${method.toLowerCase()}',\n`
  code += `  url: '${url}',\n`

  // Params
  if (params.length > 0) {
    code += '  params: {\n'
    params.forEach(param => {
      code += `    '${param.key}': '${param.value}',\n`
    })
    code += '  },\n'
  }

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  } else if (auth.type === 'apiKey' && auth.apiKey.key && auth.apiKey.addTo === 'header') {
    allHeaders.push({ key: auth.apiKey.key, value: auth.apiKey.value })
  }

  if (allHeaders.length > 0) {
    code += '  headers: {\n'
    allHeaders.forEach(header => {
      code += `    '${header.key}': '${header.value}',\n`
    })
    code += '  },\n'
  }

  // Body
  if (body.type === 'raw' && body.raw) {
    code += `  data: ${body.raw}\n`
  }

  code += '};\n\n'

  code += 'axios(config)\n'
  code += '  .then(response => console.log(response.data))\n'
  code += '  .catch(error => console.error(error));'

  return code
}

const generatePythonRequests = (url, method, headers, params, body, auth) => {
  let code = '# Using requests library\n'
  code += 'import requests\n\n'

  code += `url = "${url}"\n\n`

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  } else if (auth.type === 'apiKey' && auth.apiKey.key && auth.apiKey.addTo === 'header') {
    allHeaders.push({ key: auth.apiKey.key, value: auth.apiKey.value })
  }

  if (allHeaders.length > 0) {
    code += 'headers = {\n'
    allHeaders.forEach(header => {
      code += `    "${header.key}": "${header.value}",\n`
    })
    code += '}\n\n'
  }

  // Params
  if (params.length > 0) {
    code += 'params = {\n'
    params.forEach(param => {
      code += `    "${param.key}": "${param.value}",\n`
    })
    code += '}\n\n'
  }

  // Body
  if (body.type === 'raw' && body.raw) {
    code += `data = ${body.raw}\n\n`
  }

  // Request
  code += `response = requests.${method.toLowerCase()}(url`
  if (allHeaders.length > 0) code += ', headers=headers'
  if (params.length > 0) code += ', params=params'
  if (body.type === 'raw' && body.raw) code += ', json=data'
  code += ')\n\n'

  code += 'print(response.json())'

  return code
}

const generatePhpCurl = (url, method, headers, params, body, auth) => {
  let code = '<?php\n'
  code += '// Using cURL\n\n'

  // Build URL with params
  if (params.length > 0) {
    const queryString = params.map(p => `${p.key}=${p.value}`).join('&')
    url += `?${queryString}`
  }

  code += `$url = "${url}";\n\n`

  code += '$curl = curl_init();\n\n'

  code += 'curl_setopt_array($curl, [\n'
  code += '    CURLOPT_URL => $url,\n'
  code += '    CURLOPT_RETURNTRANSFER => true,\n'
  code += `    CURLOPT_CUSTOMREQUEST => "${method}",\n`

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  }

  if (allHeaders.length > 0) {
    code += '    CURLOPT_HTTPHEADER => [\n'
    allHeaders.forEach(header => {
      code += `        "${header.key}: ${header.value}",\n`
    })
    code += '    ],\n'
  }

  // Body
  if (body.type === 'raw' && body.raw) {
    code += `    CURLOPT_POSTFIELDS => '${body.raw}',\n`
  }

  code += ']);\n\n'

  code += '$response = curl_exec($curl);\n'
  code += 'curl_close($curl);\n\n'
  code += 'echo $response;'

  return code
}

const generateNodeHttp = (url, method, headers, params, body, auth) => {
  let code = '// Using Node.js http module\n'
  code += "const http = require('http');\n"
  code += "const https = require('https');\n"
  code += "const { URL } = require('url');\n\n"

  code += `const url = new URL('${url}');\n\n`

  // Add params
  if (params.length > 0) {
    params.forEach(param => {
      code += `url.searchParams.append('${param.key}', '${param.value}');\n`
    })
    code += '\n'
  }

  code += 'const options = {\n'
  code += '  hostname: url.hostname,\n'
  code += '  port: url.port,\n'
  code += '  path: url.pathname + url.search,\n'
  code += `  method: '${method}',\n`

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  }

  if (allHeaders.length > 0) {
    code += '  headers: {\n'
    allHeaders.forEach(header => {
      code += `    '${header.key}': '${header.value}',\n`
    })
    code += '  }\n'
  }

  code += '};\n\n'

  code += 'const req = (url.protocol === "https:" ? https : http).request(options, (res) => {\n'
  code += '  let data = "";\n'
  code += '  res.on("data", (chunk) => { data += chunk; });\n'
  code += '  res.on("end", () => { console.log(JSON.parse(data)); });\n'
  code += '});\n\n'

  if (body.type === 'raw' && body.raw) {
    code += `req.write(${body.raw});\n`
  }

  code += 'req.end();'

  return code
}

const generateJavaOkHttp = (url, method, headers, params, body, auth) => {
  let code = '// Using OkHttp\n'
  code += 'import okhttp3.*;\n\n'

  code += 'OkHttpClient client = new OkHttpClient();\n\n'

  // Build URL with params
  if (params.length > 0) {
    const queryString = params.map(p => `${p.key}=${p.value}`).join('&')
    url += `?${queryString}`
  }

  // Request builder
  code += 'Request.Builder builder = new Request.Builder()\n'
  code += `    .url("${url}")\n`

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  }

  allHeaders.forEach(header => {
    code += `    .addHeader("${header.key}", "${header.value}")\n`
  })

  // Body and method
  if (body.type === 'raw' && body.raw) {
    code += `    .${method.toLowerCase()}(RequestBody.create(MediaType.parse("application/json"), ${body.raw}));\n\n`
  } else {
    code += `    .${method.toLowerCase()}();\n\n`
  }

  code += 'Request request = builder.build();\n\n'

  code += 'try {\n'
  code += '    Response response = client.newCall(request).execute();\n'
  code += '    System.out.println(response.body().string());\n'
  code += '} catch (IOException e) {\n'
  code += '    e.printStackTrace();\n'
  code += '}'

  return code
}

const generateGoHttp = (url, method, headers, params, body, auth) => {
  let code = '// Using Go net/http\n'
  code += 'package main\n\n'
  code += 'import (\n'
  code += '    "fmt"\n'
  code += '    "net/http"\n'
  code += '    "io/ioutil"\n'
  if (body.type === 'raw' && body.raw) {
    code += '    "strings"\n'
  }
  code += ')\n\n'

  code += 'func main() {\n'

  // Build URL with params
  if (params.length > 0) {
    const queryString = params.map(p => `${p.key}=${p.value}`).join('&')
    url += `?${queryString}`
  }

  code += `    url := "${url}"\n\n`

  // Create request
  if (body.type === 'raw' && body.raw) {
    code += `    payload := strings.NewReader(${JSON.stringify(body.raw)})\n`
    code += '    req, _ := http.NewRequest("${method}", url, payload)\n\n'
  } else {
    code += `    req, _ := http.NewRequest("${method}", url, nil)\n\n`
  }

  // Headers
  const allHeaders = [...headers]
  if (auth.type === 'bearer' && auth.bearer) {
    allHeaders.push({ key: 'Authorization', value: `Bearer ${auth.bearer}` })
  }

  allHeaders.forEach(header => {
    code += `    req.Header.Add("${header.key}", "${header.value}")\n`
  })

  code += '\n    res, _ := http.DefaultClient.Do(req)\n'
  code += '    defer res.Body.Close()\n'
  code += '    body, _ := ioutil.ReadAll(res.Body)\n\n'
  code += '    fmt.Println(string(body))\n'
  code += '}'

  return code
}

const copyToClipboard = async () => {
  await copyToClipboardUtil(generatedCode.value, 'Code copied to clipboard', { showNotification })
}

const downloadCode = () => {
  const extension = getFileExtension(selectedLanguage.value)
  const filename = `api-request.${extension}`
  
  const blob = new Blob([generatedCode.value], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  
  showNotification(`Code downloaded as ${filename}`, 'success')
}

const getFileExtension = (languageId) => {
  const extensions = {
    'curl': 'sh',
    'javascript-fetch': 'js',
    'javascript-axios': 'js',
    'python-requests': 'py',
    'php-curl': 'php',
    'node-http': 'js',
    'java-okhttp': 'java',
    'go-http': 'go'
  }
  return extensions[languageId] || 'txt'
}
</script> 