<template>
    <div class="space-y-6">
      <!-- 工具栏 -->
      <div class="card p-4">
        <div class="flex items-center justify-between">
          <div class="flex flex-wrap gap-2">
            <button
              @click="sendRequest"
              :disabled="!requestUrl.trim() || isLoading"
              class="btn-primary flex items-center space-x-2"
            >
              <FontAwesomeIcon 
                :icon="isLoading ? ['fas', 'spinner'] : ['fas', 'paper-plane']" 
                :class="isLoading && 'animate-spin'"
              />
              <span>发送请求</span>
            </button>
            
            <button
              @click="clearAll"
              class="btn-secondary flex items-center space-x-2"
            >
              <FontAwesomeIcon :icon="['fas', 'trash']" />
              <span>清空</span>
            </button>
          </div>
        </div>
      </div>
  
      <div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
        <!-- 左侧：请求配置 -->
        <div class="space-y-6">
          <!-- 请求URL和方法 -->
          <div class="card p-4">
            <h3 class="text-lg font-semibold text-primary mb-4">请求配置</h3>
            
            <div class="space-y-3">
              <div class="flex space-x-2">
                <select v-model="requestMethod" class="select-input w-32">
                  <option v-for="method in httpMethods" :key="method" :value="method">
                    {{ method }}
                  </option>
                </select>
                <input
                  v-model="requestUrl"
                  type="url"
                  placeholder="https://api.example.com/users"
                  class="input-field flex-1"
                  @keyup.enter="sendRequest"
                >
              </div>
              
              <!-- 快速URL -->
              <div class="flex flex-wrap gap-2">
                <button
                  v-for="quickUrl in quickUrls"
                  :key="quickUrl.name"
                  @click="setQuickUrl(quickUrl.url)"
                  class="px-3 py-1 text-xs rounded bg-block hover:bg-block-hover text-secondary hover:text-primary transition-colors"
                >
                  {{ quickUrl.name }}
                </button>
              </div>
            </div>
          </div>
  
          <!-- 请求头配置 -->
          <div class="card p-4">
            <div class="flex items-center justify-between mb-3">
              <h4 class="font-medium text-secondary">请求头</h4>
              <button @click="addHeader" class="btn-small">
                <FontAwesomeIcon :icon="['fas', 'plus']" class="mr-1" />
                添加头部
              </button>
            </div>
            
            <div class="space-y-2">
              <div
                v-for="(header, index) in requestHeaders"
                :key="index"
                class="flex space-x-2"
              >
                <input
                  v-model="header.key"
                  type="text"
                  placeholder="Header Name"
                  class="input-field flex-1"
                >
                <input
                  v-model="header.value"
                  type="text"
                  placeholder="Header Value"
                  class="input-field flex-1"
                >
                <button
                  @click="removeHeader(index)"
                  class="p-2 text-error hover:bg-error/10 rounded transition-colors"
                >
                  <FontAwesomeIcon :icon="['fas', 'times']" />
                </button>
              </div>
            </div>
          </div>
  
          <!-- 请求体 -->
          <div v-if="['POST', 'PUT', 'PATCH'].includes(requestMethod)" class="card p-4">
            <div class="flex items-center justify-between mb-3">
              <h4 class="font-medium text-secondary">请求体</h4>
              <select v-model="requestBodyType" class="select-input w-32">
                <option value="json">JSON</option>
                <option value="text">Text</option>
                <option value="form">Form</option>
              </select>
            </div>
            
            <textarea
              v-model="requestBody"
              :placeholder="getBodyPlaceholder()"
              class="textarea-field h-40 font-mono text-sm"
            />
            
            <div v-if="requestBodyType === 'json'" class="flex justify-between items-center mt-2">
              <button @click="formatJsonBody" class="btn-small">
                <FontAwesomeIcon :icon="['fas', 'code']" class="mr-1" />
                格式化
              </button>
              <div class="text-xs text-secondary">
                {{ requestBody.length }} 字符
              </div>
            </div>
          </div>
        </div>
  
        <!-- 右侧：响应结果 -->
        <div class="card p-4 min-h-[600px]">
          <h3 class="text-lg font-semibold text-primary mb-4">响应结果</h3>
          
          <div v-if="isLoading" class="flex flex-col items-center justify-center h-96">
            <FontAwesomeIcon :icon="['fas', 'spinner']" class="text-4xl text-primary animate-spin mb-4" />
            <p class="text-secondary">正在发送请求...</p>
          </div>
          
          <div v-else-if="lastResponse" class="space-y-4">
            <!-- 响应状态栏 -->
            <div class="flex items-center justify-between p-3 rounded-lg bg-secondary/10">
              <div class="flex items-center space-x-3">
                <span :class="[
                  'px-3 py-1 text-sm font-medium rounded',
                  getStatusColor(lastResponse.status)
                ]">
                  {{ lastResponse.status }} {{ lastResponse.statusText }}
                </span>
                <span class="text-sm text-secondary">
                  {{ formatResponseSize(lastResponse.size) }} | {{ lastResponse.time }}ms
                </span>
              </div>
              
              <button @click="copyResponseContent" class="btn-small">
                <FontAwesomeIcon :icon="copied ? ['fas', 'check'] : ['fas', 'copy']" class="mr-1" />
                {{ copied ? '已复制' : '复制' }}
              </button>
            </div>
            
            <!-- 响应内容 -->
            <div class="space-y-3">
              <div class="flex items-center justify-between">
                <span class="text-sm text-secondary">响应内容</span>
                <button 
                  v-if="isJsonResponse"
                  @click="toggleJsonFormat"
                  class="btn-small"
                >
                  <FontAwesomeIcon :icon="['fas', 'code']" class="mr-1" />
                  {{ jsonFormatted ? '原始' : '格式化' }}
                </button>
              </div>
              
              <div class="relative">
                <pre class="bg-secondary/10 p-4 rounded-lg text-sm font-mono overflow-auto max-h-96 whitespace-pre-wrap">{{ formattedResponseData }}</pre>
              </div>
            </div>
          </div>
          
          <div v-else class="flex flex-col items-center justify-center h-96 text-tertiary">
            <FontAwesomeIcon :icon="['fas', 'paper-plane']" class="text-6xl mb-4 opacity-50" />
            <p class="text-lg">暂无响应</p>
            <p class="text-sm">点击发送请求按钮开始测试</p>
          </div>
        </div>
      </div>
  
      <!-- 错误提示 -->
      <div v-if="errorMessage" class="card p-4 bg-error/10 border-error/20">
        <div class="flex items-center space-x-2 text-error">
          <FontAwesomeIcon :icon="['fas', 'exclamation-triangle']" />
          <span>{{ errorMessage }}</span>
        </div>
      </div>
    </div>
  </template>
  
  <script setup lang="ts">
  import { ref, computed } from 'vue'
  
  // 响应式状态
  const requestUrl = ref('https://jsonplaceholder.typicode.com/posts/1')
  const requestMethod = ref('GET')
  const requestHeaders = ref([
    { key: 'Content-Type', value: 'application/json' }
  ])
  const requestBody = ref('')
  const requestBodyType = ref('json')
  
  const isLoading = ref(false)
  const lastResponse = ref(null)
  const errorMessage = ref('')
  const copied = ref(false)
  const jsonFormatted = ref(true)
  
  // HTTP方法列表
  const httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']
  
  // 快速URL列表
  const quickUrls = [
    { name: 'JSONPlaceholder', url: 'https://jsonplaceholder.typicode.com/posts/1' },
    { name: 'GitHub API', url: 'https://api.github.com/users/octocat' },
    { name: 'HTTPBin', url: 'https://httpbin.org/get' }
  ]
  
  // 计算属性
  const isJsonResponse = computed(() => {
    if (!lastResponse.value) return false
    const contentType = lastResponse.value.headers['content-type'] || ''
    return contentType.includes('application/json') || 
           (typeof lastResponse.value.data === 'object' && lastResponse.value.data !== null)
  })
  
  const formattedResponseData = computed(() => {
    if (!lastResponse.value) return ''
    
    if (isJsonResponse.value && jsonFormatted.value) {
      try {
        return JSON.stringify(lastResponse.value.data, null, 2)
      } catch {
        return String(lastResponse.value.data)
      }
    }
    
    return typeof lastResponse.value.data === 'string' 
      ? lastResponse.value.data 
      : JSON.stringify(lastResponse.value.data)
  })
  
  // 请求头管理
  const addHeader = () => {
    requestHeaders.value.push({ key: '', value: '' })
  }
  
  const removeHeader = (index: number) => {
    requestHeaders.value.splice(index, 1)
  }
  
  // 工具函数
  const getBodyPlaceholder = () => {
    switch (requestBodyType.value) {
      case 'json':
        return '{\n  "key": "value"\n}'
      default:
        return '请输入请求体内容...'
    }
  }
  
  const formatJsonBody = () => {
    try {
      const parsed = JSON.parse(requestBody.value)
      requestBody.value = JSON.stringify(parsed, null, 2)
    } catch (error) {
      console.error('JSON格式化失败:', error)
    }
  }
  
  const setQuickUrl = (url: string) => {
    requestUrl.value = url
  }
  
  const getStatusColor = (status: number) => {
    if (status >= 200 && status < 300) return 'bg-success/20 text-success'
    if (status >= 300 && status < 400) return 'bg-warning/20 text-warning'
    if (status >= 400 && status < 500) return 'bg-error/20 text-error'
    if (status >= 500) return 'bg-error/30 text-error'
    return 'bg-secondary/20 text-secondary'
  }
  
  const formatResponseSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
    return `${(bytes / 1024 / 1024).toFixed(1)} MB`
  }
  
  // 发送请求
  const sendRequest = async () => {
    if (!requestUrl.value.trim()) return
  
    isLoading.value = true
    errorMessage.value = ''
    lastResponse.value = null
  
    try {
      const startTime = performance.now()
      
      // 准备请求头
      const headers: Record<string, string> = {}
      requestHeaders.value.forEach(h => {
        if (h.key.trim() && h.value.trim()) {
          headers[h.key] = h.value
        }
      })
  
      // 准备请求体
      let body: string | undefined
      if (['POST', 'PUT', 'PATCH'].includes(requestMethod.value)) {
        body = requestBody.value
      }
  
      // 发送请求
      const response = await fetch(requestUrl.value, {
        method: requestMethod.value,
        headers,
        body
      })
  
      const endTime = performance.now()
      const responseTime = Math.round(endTime - startTime)
  
      // 获取响应头
      const responseHeaders: Record<string, string> = {}
      response.headers.forEach((value, key) => {
        responseHeaders[key] = value
      })
  
      // 解析响应体
      let responseData: any
      const contentType = response.headers.get('content-type') || ''
      
      if (contentType.includes('application/json')) {
        responseData = await response.json()
      } else {
        responseData = await response.text()
      }
  
      // 计算响应大小
      const responseText = typeof responseData === 'string' ? responseData : JSON.stringify(responseData)
      const responseSize = new Blob([responseText]).size
  
      lastResponse.value = {
        status: response.status,
        statusText: response.statusText,
        headers: responseHeaders,
        data: responseData,
        time: responseTime,
        size: responseSize
      }
  
    } catch (error) {
      errorMessage.value = `请求失败: ${(error as Error).message}`
    } finally {
      isLoading.value = false
    }
  }
  
  // 其他功能
  const clearAll = () => {
    requestUrl.value = 'https://jsonplaceholder.typicode.com/posts/1'
    requestMethod.value = 'GET'
    requestHeaders.value = [{ key: 'Content-Type', value: 'application/json' }]
    requestBody.value = ''
    lastResponse.value = null
    errorMessage.value = ''
  }
  
  const copyResponseContent = async () => {
    if (!lastResponse.value) return
    
    try {
      const textToCopy = formattedResponseData.value
      await navigator.clipboard.writeText(textToCopy)
      copied.value = true
      setTimeout(() => {
        copied.value = false
      }, 2000)
    } catch (error) {
      console.error('复制失败:', error)
    }
  }
  
  const toggleJsonFormat = () => {
    jsonFormatted.value = !jsonFormatted.value
  }
  </script>
  
  <style scoped>
  .select-input {
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    border: 1px solid rgba(var(--color-primary), 0.2);
    background-color: rgb(var(--color-bg-card));
    color: rgb(var(--color-text-primary));
    outline: none;
    transition: all 0.2s ease;
  }
  
  .select-input:focus {
    border-color: rgb(var(--color-primary));
    box-shadow: 0 0 0 2px rgba(var(--color-primary), 0.2);
  }
  
  .btn-small {
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem;
    border-radius: 0.375rem;
    background-color: rgb(var(--color-bg-secondary));
    color: rgb(var(--color-primary-light));
    border: 1px solid rgb(var(--color-primary));
    transition: all 0.2s ease;
    cursor: pointer;
  }
  
  .btn-small:hover {
    background-color: rgba(var(--color-primary), 0.1);
    border-color: rgb(var(--color-primary-hover));
  }
  </style>