<template>
  <div class="api-tester">
    <h2 class="page-title">API接口调用</h2>
    
    <!-- 请求配置区域 -->
    <el-card class="request-card">
      <template #header>
        <div class="card-header">
          <span>请求配置</span>
          <el-button type="primary" @click="sendRequest" :loading="loading">
            发送请求
          </el-button>
        </div>
      </template>
      
      <!-- 请求方法和URL -->
      <el-form :model="requestForm" label-width="100px">
        <el-row :gutter="20">
          <el-col :span="4">
            <el-form-item label="请求方法">
              <el-select v-model="requestForm.method" style="width: 100%">
                <el-option label="GET" value="GET" />
                <el-option label="POST" value="POST" />
                <el-option label="PUT" value="PUT" />
                <el-option label="DELETE" value="DELETE" />
                <el-option label="PATCH" value="PATCH" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="20">
            <el-form-item label="接口路径">
              <el-input 
                v-model="requestForm.url" 
                placeholder="请输入接口路径，如：/api/user-profile/migrateLifeEvents"
                clearable
              >
                <template #prepend>{{ baseUrl }}</template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      
      <!-- 参数配置标签页 -->
      <el-tabs v-model="activeTab" type="border-card">
        <!-- Query参数 -->
        <el-tab-pane label="Query参数" name="query">
          <div class="params-header">
            <span class="params-tip">URL查询参数（?key=value&key2=value2）</span>
            <el-button type="primary" size="small" @click="addQueryParam">
              添加参数
            </el-button>
          </div>
          <el-table :data="requestForm.queryParams" border size="small">
            <el-table-column label="参数名" min-width="150">
              <template #default="{ row }">
                <el-input v-model="row.key" placeholder="参数名" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="参数值" min-width="200">
              <template #default="{ row }">
                <el-input v-model="row.value" placeholder="参数值" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="描述" min-width="150">
              <template #default="{ row }">
                <el-input v-model="row.description" placeholder="描述（可选）" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" align="center">
              <template #default="{ $index }">
                <el-button type="danger" link size="small" @click="removeQueryParam($index)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        
        <!-- 请求头 -->
        <el-tab-pane label="请求头" name="headers">
          <div class="params-header">
            <span class="params-tip">自定义请求头（Authorization已自动添加）</span>
            <el-button type="primary" size="small" @click="addHeader">
              添加请求头
            </el-button>
          </div>
          <el-table :data="requestForm.headers" border size="small">
            <el-table-column label="Header名" min-width="150">
              <template #default="{ row }">
                <el-input v-model="row.key" placeholder="Header名" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="Header值" min-width="200">
              <template #default="{ row }">
                <el-input v-model="row.value" placeholder="Header值" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="描述" min-width="150">
              <template #default="{ row }">
                <el-input v-model="row.description" placeholder="描述（可选）" size="small" />
              </template>
            </el-table-column>
            <el-table-column label="操作" width="80" align="center">
              <template #default="{ $index }">
                <el-button type="danger" link size="small" @click="removeHeader($index)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        
        <!-- 请求体 -->
        <el-tab-pane label="请求体" name="body">
          <div class="params-header">
            <span class="params-tip">请求体内容（JSON格式）</span>
            <div class="body-actions">
              <el-button type="success" size="small" @click="formatRequestBody">
                格式化JSON
              </el-button>
              <el-button type="warning" size="small" @click="compressRequestBody">
                压缩JSON
              </el-button>
              <el-button size="small" @click="clearRequestBody">
                清空
              </el-button>
            </div>
          </div>
          <el-input
            v-model="requestForm.body"
            type="textarea"
            :rows="10"
            placeholder='请输入JSON格式的请求体，如：{"key": "value"}'
            class="body-textarea"
          />
          <div v-if="bodyError" class="body-error">
            <el-alert :title="bodyError" type="error" :closable="false" />
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- 响应结果区域 -->
    <el-card class="response-card" v-if="responseData">
      <template #header>
        <div class="card-header">
          <span>响应结果</span>
          <div class="response-info">
            <el-tag :type="getStatusType(responseData.status)" size="small">
              状态码: {{ responseData.status }}
            </el-tag>
            <el-tag type="info" size="small">
              耗时: {{ responseData.duration }}ms
            </el-tag>
            <el-button type="primary" size="small" @click="copyResponse">
              复制响应
            </el-button>
          </div>
        </div>
      </template>
      
      <el-tabs v-model="responseTab" type="border-card">
        <!-- 响应体 -->
        <el-tab-pane label="响应体" name="body">
          <div class="response-body">
            <pre class="json-display">{{ formatJson(responseData.data) }}</pre>
          </div>
        </el-tab-pane>
        
        <!-- 响应头 -->
        <el-tab-pane label="响应头" name="headers">
          <el-table :data="responseHeaders" border size="small">
            <el-table-column prop="key" label="Header名" min-width="200" />
            <el-table-column prop="value" label="Header值" min-width="300" />
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    
    <!-- 历史记录区域 -->
    <el-card class="history-card">
      <template #header>
        <div class="card-header">
          <span>请求历史（最近10条）</span>
          <el-button type="danger" size="small" @click="clearHistory" :disabled="history.length === 0">
            清空历史
          </el-button>
        </div>
      </template>
      
      <el-table :data="history" border size="small" v-if="history.length > 0">
        <el-table-column label="方法" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="getMethodType(row.method)" size="small">
              {{ row.method }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="url" label="接口路径" min-width="300" show-overflow-tooltip />
        <el-table-column label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)" size="small">
              {{ row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="duration" label="耗时" width="100" align="center">
          <template #default="{ row }">
            {{ row.duration }}ms
          </template>
        </el-table-column>
        <el-table-column prop="time" label="时间" width="180" />
        <el-table-column label="操作" width="120" align="center">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="loadFromHistory(row)">
              加载
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-empty v-else description="暂无请求历史" />
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'

/**
 * 参数项接口
 */
interface ParamItem {
  key: string
  value: string
  description: string
}

/**
 * 请求表单接口
 */
interface RequestForm {
  method: string
  url: string
  queryParams: ParamItem[]
  headers: ParamItem[]
  body: string
}

/**
 * 响应数据接口
 */
interface ResponseData {
  status: number
  data: any
  headers: Record<string, string>
  duration: number
}

/**
 * 历史记录接口
 */
interface HistoryItem {
  method: string
  url: string
  status: number
  duration: number
  time: string
  queryParams: ParamItem[]
  headers: ParamItem[]
  body: string
}

// 基础URL
const baseUrl = computed(() => import.meta.env.VITE_APP_BASE_API || '')

// 加载状态
const loading = ref(false)

// 当前激活的标签页
const activeTab = ref('query')
const responseTab = ref('body')

// 请求表单
const requestForm = reactive<RequestForm>({
  method: 'GET',
  url: '',
  queryParams: [],
  headers: [],
  body: ''
})

// 响应数据
const responseData = ref<ResponseData | null>(null)

// 请求体错误信息
const bodyError = ref('')

// 历史记录
const history = ref<HistoryItem[]>([])

// 响应头列表
const responseHeaders = computed(() => {
  if (!responseData.value?.headers) return []
  return Object.entries(responseData.value.headers).map(([key, value]) => ({
    key,
    value: String(value)
  }))
})

/**
 * 添加Query参数
 */
const addQueryParam = () => {
  requestForm.queryParams.push({ key: '', value: '', description: '' })
}

/**
 * 移除Query参数
 */
const removeQueryParam = (index: number) => {
  requestForm.queryParams.splice(index, 1)
}

/**
 * 添加请求头
 */
const addHeader = () => {
  requestForm.headers.push({ key: '', value: '', description: '' })
}

/**
 * 移除请求头
 */
const removeHeader = (index: number) => {
  requestForm.headers.splice(index, 1)
}

/**
 * 格式化请求体JSON
 */
const formatRequestBody = () => {
  if (!requestForm.body.trim()) return
  try {
    const parsed = JSON.parse(requestForm.body)
    requestForm.body = JSON.stringify(parsed, null, 2)
    bodyError.value = ''
    ElMessage.success('格式化成功')
  } catch (e) {
    bodyError.value = 'JSON格式错误: ' + (e as Error).message
    ElMessage.error('JSON格式错误')
  }
}

/**
 * 压缩请求体JSON
 */
const compressRequestBody = () => {
  if (!requestForm.body.trim()) return
  try {
    const parsed = JSON.parse(requestForm.body)
    requestForm.body = JSON.stringify(parsed)
    bodyError.value = ''
    ElMessage.success('压缩成功')
  } catch (e) {
    bodyError.value = 'JSON格式错误: ' + (e as Error).message
    ElMessage.error('JSON格式错误')
  }
}

/**
 * 清空请求体
 */
const clearRequestBody = () => {
  requestForm.body = ''
  bodyError.value = ''
}

/**
 * 格式化JSON显示
 */
const formatJson = (data: any): string => {
  try {
    return JSON.stringify(data, null, 2)
  } catch {
    return String(data)
  }
}

/**
 * 获取状态码对应的标签类型
 */
const getStatusType = (status: number): string => {
  if (status >= 200 && status < 300) return 'success'
  if (status >= 400 && status < 500) return 'warning'
  if (status >= 500) return 'danger'
  return 'info'
}

/**
 * 获取请求方法对应的标签类型
 */
const getMethodType = (method: string): string => {
  const types: Record<string, string> = {
    GET: 'success',
    POST: 'primary',
    PUT: 'warning',
    DELETE: 'danger',
    PATCH: 'info'
  }
  return types[method] || 'info'
}

/**
 * 发送请求
 */
const sendRequest = async () => {
  if (!requestForm.url.trim()) {
    ElMessage.warning('请输入接口路径')
    return
  }

  // 验证请求体JSON格式
  if (requestForm.body.trim() && ['POST', 'PUT', 'PATCH'].includes(requestForm.method)) {
    try {
      JSON.parse(requestForm.body)
      bodyError.value = ''
    } catch (e) {
      bodyError.value = 'JSON格式错误: ' + (e as Error).message
      ElMessage.error('请求体JSON格式错误')
      return
    }
  }

  loading.value = true
  const startTime = Date.now()

  try {
    // 获取token
    const token = localStorage.getItem('adminToken')
    
    // 构建请求头
    const headers: Record<string, string> = {
      'Content-Type': 'application/json'
    }
    if (token) {
      headers['Authorization'] = `Bearer ${token}`
    }
    // 添加自定义请求头
    requestForm.headers.forEach(h => {
      if (h.key.trim()) {
        headers[h.key] = h.value
      }
    })

    // 构建Query参数
    const params: Record<string, string> = {}
    requestForm.queryParams.forEach(p => {
      if (p.key.trim()) {
        params[p.key] = p.value
      }
    })

    // 构建请求体
    let data = undefined
    if (requestForm.body.trim() && ['POST', 'PUT', 'PATCH'].includes(requestForm.method)) {
      data = JSON.parse(requestForm.body)
    }

    // 发送请求
    const response = await axios({
      method: requestForm.method.toLowerCase(),
      url: baseUrl.value + requestForm.url,
      headers,
      params,
      data,
      validateStatus: () => true // 不抛出HTTP错误
    })

    const duration = Date.now() - startTime

    // 保存响应数据
    responseData.value = {
      status: response.status,
      data: response.data,
      headers: response.headers as Record<string, string>,
      duration
    }

    // 添加到历史记录
    addToHistory({
      method: requestForm.method,
      url: requestForm.url,
      status: response.status,
      duration,
      time: new Date().toLocaleString(),
      queryParams: [...requestForm.queryParams],
      headers: [...requestForm.headers],
      body: requestForm.body
    })

    if (response.status >= 200 && response.status < 300) {
      ElMessage.success(`请求成功 (${response.status})`)
    } else {
      ElMessage.warning(`请求完成，状态码: ${response.status}`)
    }
  } catch (error: any) {
    const duration = Date.now() - startTime
    responseData.value = {
      status: 0,
      data: { error: error.message || '请求失败' },
      headers: {},
      duration
    }
    ElMessage.error('请求失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

/**
 * 添加到历史记录
 */
const addToHistory = (item: HistoryItem) => {
  history.value.unshift(item)
  // 只保留最近10条
  if (history.value.length > 10) {
    history.value = history.value.slice(0, 10)
  }
  // 保存到localStorage
  localStorage.setItem('apiTesterHistory', JSON.stringify(history.value))
}

/**
 * 从历史记录加载
 */
const loadFromHistory = (item: HistoryItem) => {
  requestForm.method = item.method
  requestForm.url = item.url
  requestForm.queryParams = item.queryParams ? [...item.queryParams] : []
  requestForm.headers = item.headers ? [...item.headers] : []
  requestForm.body = item.body || ''
  ElMessage.success('已加载历史请求')
}

/**
 * 清空历史记录
 */
const clearHistory = () => {
  history.value = []
  localStorage.removeItem('apiTesterHistory')
  ElMessage.success('历史记录已清空')
}

/**
 * 复制响应内容
 */
const copyResponse = async () => {
  if (!responseData.value) return
  try {
    const text = formatJson(responseData.value.data)
    await navigator.clipboard.writeText(text)
    ElMessage.success('已复制到剪贴板')
  } catch {
    ElMessage.error('复制失败')
  }
}

// 初始化时加载历史记录
const initHistory = () => {
  const saved = localStorage.getItem('apiTesterHistory')
  if (saved) {
    try {
      history.value = JSON.parse(saved)
    } catch {
      history.value = []
    }
  }
}

initHistory()
</script>

<style scoped lang="scss">
.api-tester {
  .page-title {
    margin-bottom: 20px;
    font-size: 24px;
    color: var(--ls-text);
  }

  .request-card,
  .response-card,
  .history-card {
    margin-bottom: 20px;
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .params-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    .params-tip {
      color: rgba(226, 232, 240, 0.6);
      font-size: 12px;
    }

    .body-actions {
      display: flex;
      gap: 8px;
    }
  }

  .body-textarea {
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
    
    :deep(.el-textarea__inner) {
      font-family: inherit;
      line-height: 1.5;
    }
  }

  .body-error {
    margin-top: 10px;
  }

  .response-info {
    display: flex;
    align-items: center;
    gap: 10px;
  }

  .response-body {
    max-height: 500px;
    overflow: auto;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: var(--ls-radius-md);
    padding: 10px;
  }

  .json-display {
    margin: 0;
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
    font-size: 13px;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-all;
    color: rgba(226, 232, 240, 0.9);
  }
}
</style>
