<template>
  <div class="debug-page">
    <!-- 顶部标题栏 -->
    <div class="page-header">
      <div class="header-left">
        <a-button type="text" @click="$router.back()">
          <template #icon><ArrowLeftOutlined /></template>
        </a-button>
        <h1>AI接口调试</h1>
        <span class="subtitle">在线测试AI模型接口</span>
      </div>
      <div class="header-right">
        <a-button @click="handleClearAll">
          <template #icon><ClearOutlined /></template>
          重置
        </a-button>
      </div>
    </div>

    <!-- 主内容区 -->
    <div class="main-content">
      <!-- 模型选择区 -->
      <div class="section">
        <div class="section-title">选择模型</div>
        <div class="model-selector">
          <a-select 
            v-model:value="selectedModelId" 
            placeholder="请选择要调试的AI模型"
            show-search
            size="large"
            style="width: 400px;"
            :filter-option="filterOption"
            @change="handleModelChange"
          >
            <a-select-opt-group v-for="group in groupedModels" :key="group.name">
              <template #label>{{ group.name }}</template>
              <a-select-option v-for="model in group.models" :key="model.id" :value="model.id">
                <span>{{ model.name }}</span>
                <span class="model-code">{{ model.code }}</span>
              </a-select-option>
            </a-select-opt-group>
          </a-select>
          
          <div v-if="selectedModel" class="model-meta">
            <span class="meta-item">
              <span class="meta-label">类型</span>
              <span class="meta-value">{{ getTypeLabel(selectedModel.type) }}</span>
            </span>
            <span class="meta-divider">|</span>
            <span class="meta-item">
              <span class="meta-label">积分</span>
              <span class="meta-value">{{ selectedModel.pointsCost }}/次</span>
            </span>
            <span v-if="selectedModel.workflowType !== 'direct'" class="meta-divider">|</span>
            <span v-if="selectedModel.workflowType !== 'direct'" class="meta-item">
              <span class="meta-label">工作流</span>
              <span class="meta-value">{{ selectedModel.workflowType }}</span>
            </span>
          </div>
        </div>
      </div>

      <!-- 参数配置区 -->
      <div class="section">
        <div class="section-title">输入参数</div>
        <div v-if="selectedModel && inputParams.length > 0" class="params-form">
          <a-form layout="vertical">
            <a-row :gutter="24">
              <template v-for="param in inputParams" :key="param.name">
                <!-- 文本输入 -->
                <a-col :span="param.type === 'textarea' ? 24 : 12" v-if="param.type === 'text' || param.type === 'input'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <a-input v-model:value="formData[param.name]" :placeholder="param.placeholder || `请输入${param.label}`" />
                  </a-form-item>
                </a-col>

                <!-- 文本域 -->
                <a-col :span="24" v-else-if="param.type === 'textarea'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <a-textarea v-model:value="formData[param.name]" :placeholder="param.placeholder || `请输入${param.label}`" :rows="4" show-count :maxlength="2000" />
                  </a-form-item>
                </a-col>

                <!-- 下拉选择 -->
                <a-col :span="12" v-else-if="param.type === 'select'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <a-select v-model:value="formData[param.name]" :placeholder="param.placeholder || `请选择${param.label}`">
                      <a-select-option v-for="opt in param.options" :key="opt" :value="opt">{{ opt }}</a-select-option>
                    </a-select>
                  </a-form-item>
                </a-col>

                <!-- 数字输入 -->
                <a-col :span="12" v-else-if="param.type === 'number'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <a-input-number v-model:value="formData[param.name]" :min="param.min" :max="param.max" style="width: 100%;" />
                  </a-form-item>
                </a-col>

                <!-- 单图上传 -->
                <a-col :span="12" v-else-if="param.type === 'image'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <div class="image-upload-area">
                      <a-upload :file-list="getImageFileList(param.name)" list-type="picture-card" :before-upload="(file) => handleBeforeUpload(file, param.name, false)" @remove="() => handleRemoveImage(param.name)" :max-count="1">
                        <div v-if="!formData[param.name]" class="upload-placeholder"><PlusOutlined /><span>上传</span></div>
                      </a-upload>
                      <span class="upload-hint">JPG/PNG/GIF, 最大10MB</span>
                    </div>
                  </a-form-item>
                </a-col>

                <!-- 多图上传 -->
                <a-col :span="24" v-else-if="param.type === 'images'">
                  <a-form-item :required="param.required">
                    <template #label><span class="param-label">{{ param.label }}</span></template>
                    <div class="image-upload-area">
                      <a-upload :file-list="getImagesFileList(param.name)" list-type="picture-card" :before-upload="(file) => handleBeforeUpload(file, param.name, true)" @remove="(file) => handleRemoveImages(param.name, file)" :max-count="param.maxCount || 5" multiple>
                        <div class="upload-placeholder"><PlusOutlined /><span>上传</span></div>
                      </a-upload>
                      <span class="upload-hint">最多{{ param.maxCount || 5 }}张</span>
                    </div>
                  </a-form-item>
                </a-col>
              </template>
            </a-row>
          </a-form>
        </div>
        <div v-else class="empty-params">
          <span class="empty-text">请先选择模型</span>
        </div>

        <!-- 发送按钮 -->
        <div class="submit-area">
          <a-button type="primary" size="large" :loading="debugging" @click="handleDebug" :disabled="!canSubmit">
            <template #icon><SendOutlined /></template>
            {{ debugging ? '请求中...' : '发送请求' }}
          </a-button>
        </div>
      </div>

      <!-- 结果展示区 - 始终显示 -->
      <div class="section result-section">
        <div class="section-header">
          <div class="section-title">调试结果</div>
          <div v-if="debugResult" class="section-actions">
            <a-button size="small" @click="copyToClipboard(JSON.stringify(debugResult.response, null, 2))">
              <template #icon><CopyOutlined /></template>复制
            </a-button>
            <a-button size="small" @click="debugResult = null">
              <template #icon><DeleteOutlined /></template>清除
            </a-button>
          </div>
        </div>

        <!-- 有结果时显示 -->
        <template v-if="debugResult">
          <!-- 状态指示 -->
          <div class="result-status" :class="debugResult.success ? 'success' : 'error'">
            <span class="status-icon">
              <CheckCircleOutlined v-if="debugResult.success" />
              <CloseCircleOutlined v-else />
            </span>
            <span class="status-text">{{ debugResult.success ? '请求成功' : '请求失败' }}</span>
            <span v-if="debugResult.duration" class="status-duration">耗时 {{ debugResult.duration }}</span>
          </div>

          <!-- 提取的结果数据 -->
          <div v-if="debugResult.success && extractedResult" class="extracted-result">
            <div class="extracted-label">提取结果</div>
            <div class="extracted-content">{{ extractedResult }}</div>
          </div>

          <!-- 结果标签页 -->
          <a-tabs v-model:activeKey="activeTab" class="result-tabs">
            <a-tab-pane key="response" tab="响应数据">
              <div class="code-block"><pre>{{ JSON.stringify(debugResult.response, null, 2) }}</pre></div>
            </a-tab-pane>
            
            <a-tab-pane key="request" tab="请求详情">
              <div class="request-info">
                <div class="info-row">
                  <span class="info-label">URL</span>
                  <span class="info-value url">{{ debugResult.request?.url }}</span>
                </div>
                <div class="info-row">
                  <span class="info-label">Method</span>
                  <span class="info-value method">{{ debugResult.request?.method }}</span>
                </div>
                <div class="info-row">
                  <span class="info-label">Headers</span>
                  <div class="code-block small"><pre>{{ JSON.stringify(debugResult.request?.headers, null, 2) }}</pre></div>
                </div>
                <div class="info-row">
                  <span class="info-label">Body</span>
                  <div class="code-block small"><pre>{{ JSON.stringify(debugResult.request?.body, null, 2) }}</pre></div>
                </div>
              </div>
            </a-tab-pane>

            <a-tab-pane key="raw" tab="原始响应">
              <div class="code-block"><pre>{{ debugResult.rawResponse }}</pre></div>
            </a-tab-pane>

            <a-tab-pane v-if="!debugResult.success" key="error" tab="错误信息">
              <div class="error-info">
                <div class="error-message">{{ debugResult.error }}</div>
                <div v-if="debugResult.stackTrace" class="code-block"><pre>{{ debugResult.stackTrace }}</pre></div>
              </div>
            </a-tab-pane>
          </a-tabs>
        </template>

        <!-- 无结果时显示空状态 -->
        <div v-else class="empty-result">
          <div class="empty-icon"><ExperimentOutlined /></div>
          <p>暂无调试结果</p>
          <span class="empty-hint">配置参数后点击发送请求</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, reactive } from 'vue'
import { useRoute } from 'vue-router'
import { message } from 'ant-design-vue'
import { ArrowLeftOutlined, ClearOutlined, SendOutlined, PlusOutlined, DeleteOutlined, CopyOutlined, ExperimentOutlined, CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons-vue'
import { getAiModels, debugAiModel, getAiModelTypes } from '@/api/ai'
import { uploadImage } from '@/api/upload'

const route = useRoute()
const selectedModelId = ref(null)
const selectedModel = ref(null)
const models = ref([])
const modelTypes = ref([])
const formData = reactive({})
const debugging = ref(false)
const debugResult = ref(null)
const activeTab = ref('response')

// 按厂商分组模型
const groupedModels = computed(() => {
  const groups = {}
  models.value.forEach(model => {
    const providerName = model.providerName || '未知厂商'
    if (!groups[providerName]) {
      groups[providerName] = { name: providerName, models: [] }
    }
    groups[providerName].models.push(model)
  })
  return Object.values(groups)
})

// 解析输入参数配置
const inputParams = computed(() => {
  if (!selectedModel.value || !selectedModel.value.inputParams) return []
  try {
    return JSON.parse(selectedModel.value.inputParams)
  } catch (e) {
    return []
  }
})

// 检查是否可以提交
const canSubmit = computed(() => {
  if (!selectedModel.value) return false
  const missingParams = inputParams.value.filter(p => p.required && !formData[p.name])
  return missingParams.length === 0
})

// 提取的结果数据
const extractedResult = computed(() => {
  if (!debugResult.value || !debugResult.value.success || !debugResult.value.response) return null
  if (!selectedModel.value || !selectedModel.value.responseMapping) return null
  
  try {
    const mapping = JSON.parse(selectedModel.value.responseMapping)
    const resultPath = mapping.result
    if (!resultPath) return null
    
    // 解析路径提取数据，如 "data" 或 "choices[0].message.content"
    const response = debugResult.value.response
    return extractByPath(response, resultPath)
  } catch (e) {
    return null
  }
})

// 根据路径提取数据
const extractByPath = (obj, path) => {
  if (!obj || !path) return null
  const parts = path.replace(/\[(\d+)\]/g, '.$1').split('.')
  let result = obj
  for (const part of parts) {
    if (result === null || result === undefined) return null
    result = result[part]
  }
  return typeof result === 'object' ? JSON.stringify(result, null, 2) : result
}

const getTypeLabel = (typeValue) => {
  const type = modelTypes.value.find(t => t.value === typeValue)
  return type ? type.label : typeValue
}

const loadModels = async () => {
  try {
    const res = await getAiModels({ status: 1 })
    models.value = res.records || []
  } catch (e) {
    message.error('获取模型列表失败')
  }
}

const loadModelTypes = async () => {
  try {
    const res = await getAiModelTypes()
    modelTypes.value = res || []
  } catch (e) {}
}

const filterOption = (input, option) => {
  const text = option.children?.[0]?.children || ''
  return text.toLowerCase().includes(input.toLowerCase())
}

const handleModelChange = (modelId) => {
  selectedModel.value = models.value.find(m => m.id === modelId)
  Object.keys(formData).forEach(key => delete formData[key])
  debugResult.value = null
  inputParams.value.forEach(param => {
    if (param.default) formData[param.name] = param.default
    else if (param.type === 'images') formData[param.name] = []
  })
}

const getImageFileList = (paramName) => {
  const url = formData[paramName]
  if (!url) return []
  return [{ uid: '-1', name: 'image.png', status: 'done', url }]
}

const getImagesFileList = (paramName) => {
  const urls = formData[paramName] || []
  return urls.map((url, index) => ({ uid: `-${index}`, name: `image-${index}.png`, status: 'done', url }))
}

const handleBeforeUpload = async (file, paramName, isMultiple) => {
  if (!file.type.startsWith('image/')) { message.error('只能上传图片'); return false }
  if (file.size / 1024 / 1024 > 10) { message.error('图片不能超过10MB'); return false }
  try {
    message.loading({ content: '上传中...', key: 'upload' })
    const url = await uploadImage(file)
    if (isMultiple) {
      if (!formData[paramName]) formData[paramName] = []
      formData[paramName].push(url)
    } else {
      formData[paramName] = url
    }
    message.success({ content: '上传成功', key: 'upload' })
  } catch (e) {
    message.error({ content: '上传失败', key: 'upload' })
  }
  return false
}

const handleRemoveImage = (paramName) => { delete formData[paramName] }
const handleRemoveImages = (paramName, file) => {
  const urls = formData[paramName] || []
  const index = urls.findIndex(url => url === file.url)
  if (index > -1) urls.splice(index, 1)
}

const handleDebug = async () => {
  const missingParams = inputParams.value.filter(p => p.required && !formData[p.name]).map(p => p.label)
  if (missingParams.length > 0) { message.warning(`请填写: ${missingParams.join(', ')}`); return }
  
  debugging.value = true
  debugResult.value = null
  try {
    const result = await debugAiModel(selectedModelId.value, formData)
    debugResult.value = result
    activeTab.value = result.success ? 'response' : 'error'
    message[result.success ? 'success' : 'error'](result.success ? '请求成功' : '请求失败')
  } catch (e) {
    message.error('请求失败: ' + e.message)
    debugResult.value = { success: false, error: e.message, stackTrace: e.toString() }
  } finally {
    debugging.value = false
  }
}

const copyToClipboard = (text) => {
  navigator.clipboard.writeText(text).then(() => message.success('已复制')).catch(() => message.error('复制失败'))
}

const handleClearAll = () => {
  selectedModelId.value = null
  selectedModel.value = null
  Object.keys(formData).forEach(key => delete formData[key])
  debugResult.value = null
}

onMounted(async () => {
  await Promise.all([loadModels(), loadModelTypes()])
  const modelIdFromQuery = route.query.modelId
  if (modelIdFromQuery) {
    const modelId = parseInt(modelIdFromQuery)
    if (models.value.find(m => m.id === modelId)) {
      selectedModelId.value = modelId
      handleModelChange(modelId)
    }
  }
})
</script>

<style scoped>
.debug-page {
  min-height: 100vh;
  background: #f7f8fa;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  background: #fff;
  border-bottom: 1px solid #e8e8e8;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-left h1 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1a1a1a;
}

.subtitle {
  color: #8c8c8c;
  font-size: 14px;
}

.main-content {
  padding: 24px;
}

.section {
  background: #fff;
  border-radius: 8px;
  padding: 24px;
  margin-bottom: 16px;
  border: 1px solid #e8e8e8;
}

.section-title {
  font-size: 15px;
  font-weight: 600;
  color: #1a1a1a;
  margin-bottom: 16px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

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

.model-selector {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.model-code {
  margin-left: 8px;
  color: #8c8c8c;
  font-size: 12px;
}

.model-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background: #fafafa;
  border-radius: 6px;
  font-size: 13px;
}

.meta-item {
  display: flex;
  gap: 6px;
}

.meta-label {
  color: #8c8c8c;
}

.meta-value {
  color: #1a1a1a;
  font-weight: 500;
}

.meta-divider {
  color: #d9d9d9;
}

.params-form {
  margin-bottom: 20px;
}

.param-label {
  font-weight: 500;
  color: #262626;
}

.empty-params {
  padding: 40px 0;
  text-align: center;
}

.empty-text {
  color: #bfbfbf;
  font-size: 14px;
}

.image-upload-area {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: #8c8c8c;
  font-size: 12px;
}

.upload-hint {
  font-size: 12px;
  color: #bfbfbf;
}

.submit-area {
  display: flex;
  justify-content: center;
  padding-top: 8px;
}

.result-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-radius: 6px;
  margin-bottom: 16px;
}

.result-status.success {
  background: #f6ffed;
  border: 1px solid #b7eb8f;
}

.result-status.error {
  background: #fff2f0;
  border: 1px solid #ffccc7;
}

.status-icon {
  font-size: 18px;
}

.result-status.success .status-icon {
  color: #52c41a;
}

.result-status.error .status-icon {
  color: #ff4d4f;
}

.status-text {
  font-weight: 500;
  color: #262626;
}

.status-duration {
  margin-left: auto;
  color: #8c8c8c;
  font-size: 13px;
}

/* 提取结果样式 */
.extracted-result {
  background: #f0f9eb;
  border: 1px solid #c2e7b0;
  border-radius: 6px;
  padding: 16px;
  margin-bottom: 16px;
}

.extracted-label {
  font-size: 12px;
  font-weight: 600;
  color: #67c23a;
  margin-bottom: 8px;
  text-transform: uppercase;
}

.extracted-content {
  font-size: 14px;
  color: #262626;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-all;
}

.empty-result {
  text-align: center;
  padding: 48px 0;
  color: #bfbfbf;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.empty-hint {
  font-size: 12px;
  color: #d9d9d9;
}

.code-block {
  background: #fafafa;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 16px;
  overflow: auto;
  max-height: 400px;
}

.code-block.small {
  max-height: 200px;
  padding: 12px;
}

.code-block pre {
  margin: 0;
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  font-size: 13px;
  line-height: 1.6;
  color: #262626;
  white-space: pre-wrap;
  word-break: break-all;
}

.request-info {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.info-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-label {
  font-size: 12px;
  font-weight: 600;
  color: #8c8c8c;
  text-transform: uppercase;
}

.info-value {
  font-size: 14px;
  color: #262626;
}

.info-value.url {
  font-family: 'SF Mono', monospace;
  font-size: 13px;
  word-break: break-all;
}

.info-value.method {
  display: inline-block;
  padding: 2px 8px;
  background: #f0f0f0;
  border-radius: 4px;
  font-weight: 500;
}

.error-info {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.error-message {
  padding: 12px 16px;
  background: #fff2f0;
  border: 1px solid #ffccc7;
  border-radius: 6px;
  color: #cf1322;
}

:deep(.ant-tabs-nav) {
  margin-bottom: 16px;
}

:deep(.ant-upload-list-picture-card-container),
:deep(.ant-upload-select-picture-card) {
  width: 80px;
  height: 80px;
}

:deep(.ant-form-item) {
  margin-bottom: 16px;
}

:deep(.ant-input),
:deep(.ant-select-selector),
:deep(.ant-input-number) {
  border-radius: 6px;
}

:deep(.ant-input:focus),
:deep(.ant-select-focused .ant-select-selector) {
  border-color: #595959;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.05);
}

:deep(.ant-btn-primary) {
  background: #262626;
  border-color: #262626;
  border-radius: 6px;
  height: 40px;
  padding: 0 32px;
}

:deep(.ant-btn-primary:hover) {
  background: #434343;
  border-color: #434343;
}

:deep(.ant-btn-primary:disabled) {
  background: #d9d9d9;
  border-color: #d9d9d9;
}

.code-block::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.code-block::-webkit-scrollbar-track {
  background: #f0f0f0;
}

.code-block::-webkit-scrollbar-thumb {
  background: #d9d9d9;
  border-radius: 3px;
}
</style>
