<template>
  <div class="conversation-tracking-page">
    <div class="page-header">
      <h1 class="page-title">对话追踪</h1>
      <p class="page-desc">查看对话记录，追踪执行链路，导出对话数据</p>
    </div>

    <el-card shadow="hover" class="filter-card">
      <el-form :inline="true" :model="queryParams" class="filter-form">
        <el-form-item label="会话 ID">
          <el-input v-model="queryParams.session_id" placeholder="输入会话 ID" clearable style="width: 200px" />
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            style="width: 260px"
          />
        </el-form-item>
        <el-form-item label="话术流程">
          <el-select v-model="queryParams.has_flow" placeholder="全部" clearable style="width: 120px">
            <el-option label="有" :value="true" />
            <el-option label="无" :value="false" />
          </el-select>
        </el-form-item>
        <el-form-item label="护栏触发">
          <el-select v-model="queryParams.has_guardrail" placeholder="全部" clearable style="width: 120px">
            <el-option label="已触发" :value="true" />
            <el-option label="未触发" :value="false" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
          <el-button type="success" @click="handleExport">
            <el-icon><Download /></el-icon>
            导出
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card shadow="hover" class="table-card" v-loading="loading">
      <el-table :data="tableData" style="width: 100%" @row-click="handleRowClick">
        <el-table-column prop="id" label="ID" width="280" show-overflow-tooltip />
        <el-table-column prop="sessionId" label="会话 ID" width="200" show-overflow-tooltip />
        <el-table-column prop="userMessage" label="用户消息" min-width="200" show-overflow-tooltip />
        <el-table-column prop="aiReply" label="AI 回复" min-width="200" show-overflow-tooltip>
          <template #default="scope">
            <span v-if="scope.row.aiReply">{{ scope.row.aiReply }}</span>
            <span v-else class="text-muted">无回复</span>
          </template>
        </el-table-column>
        <el-table-column label="流程" width="80" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.hasFlow" type="success" size="small">有</el-tag>
            <span v-else class="text-muted">-</span>
          </template>
        </el-table-column>
        <el-table-column label="护栏" width="80" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.hasGuardrail" type="danger" size="small">触发</el-tag>
            <span v-else class="text-muted">-</span>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="创建时间" width="180" />
      </el-table>

      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="queryParams.page"
          v-model:page-size="queryParams.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="getList"
          @current-change="getList"
        />
      </div>
    </el-card>

    <el-drawer
      v-model="drawerVisible"
      title="对话详情"
      size="60%"
      destroy-on-close
    >
      <div v-loading="detailLoading" class="detail-container">
        <el-empty v-if="!conversationDetail && !detailLoading" description="暂无详情数据" />
        <div v-else-if="conversationDetail">
          <el-descriptions :column="2" border class="info-descriptions">
            <el-descriptions-item label="对话 ID">{{ conversationDetail.conversationId }}</el-descriptions-item>
            <el-descriptions-item label="会话 ID">{{ conversationDetail.sessionId }}</el-descriptions-item>
            <el-descriptions-item label="执行耗时">{{ conversationDetail.executionTimeMs ? `${conversationDetail.executionTimeMs}ms` : '-' }}</el-descriptions-item>
            <el-descriptions-item label="置信度">{{ conversationDetail.confidence ? `${(conversationDetail.confidence * 100).toFixed(1)}%` : '-' }}</el-descriptions-item>
          </el-descriptions>

          <el-divider content-position="left">用户消息</el-divider>
          <div class="message-box user-message">
            {{ conversationDetail.userMessage }}
          </div>

          <el-divider content-position="left">AI 回复</el-divider>
          <div class="message-box ai-message">
            {{ conversationDetail.aiReply || '无回复' }}
          </div>

          <el-divider content-position="left" v-if="conversationDetail.triggeredRules?.length">触发的规则</el-divider>
          <div v-if="conversationDetail.triggeredRules?.length" class="rules-list">
            <el-tag v-for="rule in conversationDetail.triggeredRules" :key="rule.id" class="rule-tag">
              {{ rule.name }} ({{ rule.responseType }})
            </el-tag>
          </div>

          <el-divider content-position="left" v-if="conversationDetail.usedTemplate">使用的模板</el-divider>
          <div v-if="conversationDetail.usedTemplate" class="template-info">
            <el-tag type="success">{{ conversationDetail.usedTemplate.name }}</el-tag>
          </div>

          <el-divider content-position="left" v-if="conversationDetail.usedFlow">话术流程</el-divider>
          <div v-if="conversationDetail.usedFlow" class="flow-info">
            <el-descriptions :column="2" border size="small">
              <el-descriptions-item label="状态">{{ conversationDetail.usedFlow.status }}</el-descriptions-item>
              <el-descriptions-item label="当前步骤">{{ conversationDetail.usedFlow.currentStep }}</el-descriptions-item>
            </el-descriptions>
          </div>

          <el-divider content-position="left" v-if="conversationDetail.guardrailTriggered">护栏触发</el-divider>
          <div v-if="conversationDetail.guardrailTriggered" class="guardrail-info">
            <el-alert type="warning" :closable="false">
              <template #title>
                触发词汇: {{ conversationDetail.guardrailWords?.join(', ') || '未知' }}
              </template>
            </el-alert>
          </div>

          <el-divider content-position="left" v-if="conversationDetail.executionSteps?.length">执行链路</el-divider>
          <div v-if="conversationDetail.executionSteps?.length" class="execution-steps">
            <el-timeline>
              <el-timeline-item
                v-for="step in conversationDetail.executionSteps"
                :key="step.step"
                :type="getStepStatusType(step.status)"
                :hollow="step.status === 'skipped'"
                size="large"
              >
                <el-card shadow="never" class="step-card" @click="toggleStepDetail(step.step)">
                  <div class="step-header">
                    <div class="step-info">
                      <span class="step-number">Step {{ step.step }}</span>
                      <span class="step-name">{{ getStepName(step.name) }}</span>
                    </div>
                    <div class="step-meta">
                      <el-tag :type="getStepStatusType(step.status)" size="small" effect="plain">
                        {{ step.status }}
                      </el-tag>
                      <span class="step-duration">{{ step.duration_ms }}ms</span>
                    </div>
                  </div>
                  <div v-if="expandedSteps.includes(step.step)" class="step-detail">
                    <el-divider content-position="left">输入</el-divider>
                    <pre class="code-block"><code>{{ JSON.stringify(step.input, null, 2) }}</code></pre>
                    <el-divider content-position="left">输出</el-divider>
                    <pre class="code-block"><code>{{ JSON.stringify(step.output, null, 2) }}</code></pre>
                    <template v-if="step.error">
                      <el-divider content-position="left">错误</el-divider>
                      <el-alert type="error" :closable="false">{{ step.error }}</el-alert>
                    </template>
                  </div>
                </el-card>
              </el-timeline-item>
            </el-timeline>
          </div>
        </div>
      </div>
    </el-drawer>

    <el-dialog v-model="exportDialogVisible" title="导出对话记录" width="500px">
      <el-form :model="exportForm" label-width="100px">
        <el-form-item label="导出格式">
          <el-radio-group v-model="exportForm.format">
            <el-radio value="json">JSON</el-radio>
            <el-radio value="csv">CSV</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="exportForm.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            style="width: 100%"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="exportDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmExport" :loading="exportLoading">确认导出</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="exportStatusDialogVisible" title="导出状态" width="500px">
      <div v-if="exportTask" class="export-status">
        <el-progress
          v-if="exportTask.status === 'processing'"
          :percentage="50"
          :indeterminate="true"
          status="warning"
        />
        <el-result
          v-else-if="exportTask.status === 'completed'"
          icon="success"
          title="导出完成"
          :sub-title="`共导出 ${exportTask.totalRows} 条记录，文件大小 ${formatFileSize(exportTask.fileSize || 0)}`"
        >
          <template #extra>
            <el-button type="primary" @click="downloadExport">下载文件</el-button>
          </template>
        </el-result>
        <el-result
          v-else-if="exportTask.status === 'failed'"
          icon="error"
          title="导出失败"
          :sub-title="exportTask.errorMessage"
        />
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Download } from '@element-plus/icons-vue'
import {
  listConversations,
  getConversationDetail,
  createExportTask,
  getExportStatus,
  getExportDownloadUrl,
  type ConversationItem,
  type ConversationDetail,
  type ExportTaskResponse
} from '@/api/monitoring'

const loading = ref(false)
const tableData = ref<ConversationItem[]>([])
const total = ref(0)
const dateRange = ref<[string, string] | null>(null)

const queryParams = reactive({
  page: 1,
  pageSize: 20,
  session_id: '',
  has_flow: undefined as boolean | undefined,
  has_guardrail: undefined as boolean | undefined
})

const drawerVisible = ref(false)
const detailLoading = ref(false)
const conversationDetail = ref<ConversationDetail | null>(null)
const expandedSteps = ref<number[]>([])

const exportDialogVisible = ref(false)
const exportStatusDialogVisible = ref(false)
const exportLoading = ref(false)
const exportTask = ref<ExportTaskResponse | null>(null)
const exportForm = reactive({
  format: 'json' as 'json' | 'csv',
  dateRange: null as [string, string] | null
})

const stepNameMap: Record<string, string> = {
  'InputScanner': '输入扫描',
  'FlowEngine': '流程引擎',
  'IntentRouter': '意图路由',
  'QueryRewriter': '查询重写',
  'MultiKBRetrieval': '多知识库检索',
  'ResultRanker': '结果排序',
  'PromptBuilder': 'Prompt 构建',
  'LLMGenerate': 'LLM 生成',
  'OutputFilter': '输出过滤',
  'Confidence': '置信度计算',
  'Memory': '记忆存储',
  'Response': '响应返回'
}

const getStepName = (name: string) => {
  return stepNameMap[name] || name
}

const getStepStatusType = (status: string) => {
  switch (status) {
    case 'success': return 'success'
    case 'failed': return 'danger'
    case 'skipped': return 'info'
    default: return 'warning'
  }
}

const toggleStepDetail = (step: number) => {
  const index = expandedSteps.value.indexOf(step)
  if (index > -1) {
    expandedSteps.value.splice(index, 1)
  } else {
    expandedSteps.value.push(step)
  }
}

const formatFileSize = (bytes: number) => {
  if (bytes < 1024) return bytes + ' B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
  return (bytes / (1024 * 1024)).toFixed(2) + ' MB'
}

const getList = async () => {
  loading.value = true
  try {
    const params: any = {
      page: queryParams.page,
      pageSize: queryParams.pageSize
    }
    if (queryParams.session_id) {
      params.session_id = queryParams.session_id
    }
    if (queryParams.has_flow !== undefined) {
      params.has_flow = queryParams.has_flow
    }
    if (queryParams.has_guardrail !== undefined) {
      params.has_guardrail = queryParams.has_guardrail
    }
    if (dateRange.value && dateRange.value.length === 2) {
      params.start_date = dateRange.value[0]
      params.end_date = dateRange.value[1]
    }

    const res = await listConversations(params)
    tableData.value = res.data || []
    total.value = res.total || 0
  } catch (error) {
    console.error('Failed to fetch conversations:', error)
  } finally {
    loading.value = false
  }
}

const handleQuery = () => {
  queryParams.page = 1
  getList()
}

const resetQuery = () => {
  queryParams.session_id = ''
  queryParams.has_flow = undefined
  queryParams.has_guardrail = undefined
  dateRange.value = null
  handleQuery()
}

const handleRowClick = async (row: ConversationItem) => {
  drawerVisible.value = true
  detailLoading.value = true
  expandedSteps.value = []
  
  try {
    conversationDetail.value = await getConversationDetail(row.id)
  } catch (error) {
    console.error('Failed to fetch conversation detail:', error)
    ElMessage.error('获取对话详情失败')
  } finally {
    detailLoading.value = false
  }
}

const handleExport = () => {
  exportForm.format = 'json'
  exportForm.dateRange = dateRange.value
  exportDialogVisible.value = true
}

const confirmExport = async () => {
  exportLoading.value = true
  try {
    const data: any = {
      format: exportForm.format
    }
    if (exportForm.dateRange && exportForm.dateRange.length === 2) {
      data.start_date = exportForm.dateRange[0]
      data.end_date = exportForm.dateRange[1]
    }

    const task = await createExportTask(data)
    exportTask.value = task
    exportDialogVisible.value = false
    exportStatusDialogVisible.value = true

    if (task.status === 'processing') {
      pollExportStatus(task.taskId)
    }
  } catch (error) {
    console.error('Failed to create export task:', error)
    ElMessage.error('创建导出任务失败')
  } finally {
    exportLoading.value = false
  }
}

const pollExportStatus = async (taskId: string) => {
  const poll = async () => {
    try {
      const status = await getExportStatus(taskId)
      exportTask.value = status

      if (status.status === 'processing') {
        setTimeout(poll, 2000)
      }
    } catch (error) {
      console.error('Failed to poll export status:', error)
    }
  }

  await poll()
}

const downloadExport = () => {
  if (exportTask.value) {
    const url = getExportDownloadUrl(exportTask.value.taskId)
    const link = document.createElement('a')
    const baseURL = import.meta.env.VITE_APP_BASE_API || '/api'
    link.href = baseURL + url
    link.download = exportTask.value.fileName || 'export.json'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  }
}

onMounted(() => {
  getList()
})
</script>

<style scoped>
.conversation-tracking-page {
  padding: 24px;
  min-height: calc(100vh - 60px);
}

.page-header {
  margin-bottom: 24px;
}

.page-title {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.5px;
}

.page-desc {
  margin: 0;
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
}

.filter-card {
  margin-bottom: 20px;
}

.filter-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.table-card {
  animation: fadeInUp 0.5s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.text-muted {
  color: var(--text-tertiary);
}

.pagination-wrapper {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.detail-container {
  padding: 0 20px;
}

.info-descriptions {
  margin-bottom: 20px;
}

.message-box {
  padding: 16px;
  border-radius: 12px;
  font-size: 14px;
  line-height: 1.7;
}

.user-message {
  background-color: var(--primary-lighter);
  color: var(--text-primary);
}

.ai-message {
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
}

.rules-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rule-tag {
  margin-right: 8px;
}

.execution-steps {
  max-height: 500px;
  overflow-y: auto;
}

.step-card {
  cursor: pointer;
  transition: all 0.2s ease;
}

.step-card:hover {
  background-color: var(--bg-tertiary);
}

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

.step-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.step-number {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-tertiary);
  background-color: var(--bg-tertiary);
  padding: 2px 8px;
  border-radius: 4px;
}

.step-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}

.step-meta {
  display: flex;
  align-items: center;
  gap: 12px;
}

.step-duration {
  font-size: 12px;
  color: var(--text-tertiary);
}

.step-detail {
  margin-top: 16px;
}

.code-block {
  background-color: var(--bg-tertiary);
  padding: 12px;
  border-radius: 8px;
  font-size: 12px;
  overflow-x: auto;
  margin: 0;
}

.code-block code {
  font-family: var(--font-mono);
  white-space: pre-wrap;
  word-wrap: break-word;
}

.export-status {
  padding: 20px;
}

@media (max-width: 768px) {
  .conversation-tracking-page {
    padding: 16px;
  }

  .page-title {
    font-size: 20px;
  }

  .filter-form {
    flex-direction: column;
  }
}
</style>
