<template>
  <div class="dashboard-panel">
    <t-card title="" :bordered="false" header-bordered>
      <template #title>
        <div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;">
          <h2 style="margin:0;">📈 运营数据看板</h2>
          <t-space size="small">
            <t-button :variant="rangeDays === 7 ? 'base' : 'outline'" theme="primary" size="small" @click="setRange(7)">近7天</t-button>
            <t-button :variant="rangeDays === 30 ? 'base' : 'outline'" theme="primary" size="small" @click="setRange(30)">近30天</t-button>
            <t-divider layout="vertical" />
            <t-date-picker v-model="customStart" size="small" style="width:140px;" />
            <span style="color:var(--td-text-color-placeholder);">至</span>
            <t-date-picker v-model="customEnd" size="small" style="width:140px;" />
            <t-button variant="outline" size="small" @click="loadCustomRange" :disabled="!customStart || !customEnd">查询</t-button>
          </t-space>
        </div>
      </template>

      <!-- 4 指标卡片 -->
      <t-row :gutter="16" style="margin-bottom:16px;">
        <t-col :span="6"><t-card :bordered="true"><t-statistic title="今日对话数" :value="overview.conversationCount ?? 0" /></t-card></t-col>
        <t-col :span="6"><t-card :bordered="true"><t-statistic title="满意率" :value="formatPercent(overview.satisfactionRate)" unit="%" :color="satisfactionColor" /></t-card></t-col>
        <t-col :span="6"><t-card :bordered="true"><t-statistic title="知识库命中率" :value="formatPercent(overview.ragHitRate)" unit="%" color="green" /></t-card></t-col>
        <t-col :span="6"><t-card :bordered="true"><t-statistic title="平均响应时间" :value="overview.avgResponseTime ?? 0" unit="ms" /></t-card></t-col>
      </t-row>

      <!-- 图表 -->
      <t-row :gutter="16" style="margin-bottom:16px;">
        <t-col :span="6"><t-card title="📊 对话量趋势" :bordered="true"><div style="height:260px;"><canvas ref="conversationChartRef"></canvas></div></t-card></t-col>
        <t-col :span="6"><t-card title="📊 满意度趋势" :bordered="true"><div style="height:260px;"><canvas ref="satisfactionChartRef"></canvas></div></t-card></t-col>
      </t-row>

      <!-- 知识库分析 -->
      <t-row :gutter="16">
        <t-col :span="6">
          <t-card title="📚 文档命中排行 TOP-10" :bordered="true">
            <t-table :data="topHitDocuments" :columns="hitColumns" row-key="idx" v-if="topHitDocuments.length" />
            <t-empty v-else description="暂无数据" />
          </t-card>
        </t-col>
        <t-col :span="6">
          <t-card title="❓ 未命中问题收集" :bordered="true">
            <div v-if="missQuestions.length" style="max-height:400px;overflow-y:auto;">
              <div v-for="(item, idx) in missQuestions" :key="idx" style="padding:8px 12px;border-bottom:1px solid var(--td-border-level-1-color);font-size:13px;display:flex;align-items:center;gap:8px;">
                <span style="color:var(--td-text-color-placeholder);flex:none;">{{ idx + 1 }}.</span>
                <span style="flex:1;word-break:break-all;">{{ item.user_query }}</span>
                <span v-if="item.last_time" style="color:var(--td-text-color-placeholder);font-size:11px;flex:none;">{{ formatDateShort(item.last_time) }}</span>
              </div>
            </div>
            <t-empty v-else description="暂无数据" />
          </t-card>
        </t-col>
      </t-row>

      <t-loading v-if="loading" text="加载中..." style="text-align:center;padding:20px;" />
    </t-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { getDashboardOverview, getDashboardTrend, getDashboardKnowledge, getDashboardCustom } from '@/api/dashboard'
import { palette } from '@/utils/palette'

const loading = ref(false)
const rangeDays = ref(7)
const customStart = ref('')
const customEnd = ref('')
const overview = ref<any>({})
const trendData = ref<any[]>([])
const topHitDocuments = ref<any[]>([])
const missQuestions = ref<any[]>([])

let conversationChart: any = null
let satisfactionChart: any = null
const conversationChartRef = ref<HTMLCanvasElement | null>(null)
const satisfactionChartRef = ref<HTMLCanvasElement | null>(null)

const hitColumns = [
  { colKey: 'idx', title: '排名', width: 50, cell: (_h: any, { rowIndex }: any) => rowIndex + 1 },
  { colKey: 'document_title', title: '文档标题', ellipsis: true },
  { colKey: 'hit_count', title: '命中次数', width: 80, cell: (_h: any, { row }: any) => row.hit_count ?? row.cnt ?? 0 },
  { colKey: 'avg_score', title: '平均得分', width: 80, cell: (_h: any, { row }: any) => row.avg_score != null ? Number(row.avg_score).toFixed(3) : '-' },
]

const satisfactionColor = computed(() => {
  const rate = overview.value.satisfactionRate || 0
  if (rate > 0 && rate < 0.5) return 'red'
  if (rate >= 0.5 && rate < 0.8) return 'orange'
  return 'green'
})

function formatPercent(v: any) { if (v == null) return '0.0'; const n = Number(v); return (n * 100).toFixed(1) }
function formatDateShort(d: any) { if (!d) return ''; const dt = new Date(d); if (isNaN(dt.getTime())) return ''; return `${dt.getMonth() + 1}/${dt.getDate()}` }

async function setRange(days: number) { rangeDays.value = days; await loadTrend(days) }
async function loadOverview() {
  try { const r = await getDashboardOverview(); if (r.success) overview.value = r.data } catch { /* silent */ }
  // API 降级逻辑（后端已降级但前端不感知）—— 如果今日无数据，错误态 toast 提示
  if (overview.value?.conversationCount === 0 && overview.value?.messageCount === 0) {
    import('tdesign-vue-next').then(({ MessagePlugin }) => {
      MessagePlugin.warning('今日暂无数据，概览指标展示近 7 天汇总')
    }).catch(() => {})
  }
}

async function loadTrend(days: number) {
  try { const r = await getDashboardTrend(days); if (r.success) { trendData.value = r.data || []; await nextTick(); renderCharts() } } catch { /* */ }
}

async function loadCustomRange() {
  if (!customStart.value || !customEnd.value) return; loading.value = true
  try { const r = await getDashboardCustom(customStart.value, customEnd.value); if (r.success) { trendData.value = r.data || []; rangeDays.value = 0; await nextTick(); renderCharts() } } catch { /* */ }
  finally { loading.value = false }
}

async function loadKnowledge() {
  try { const r = await getDashboardKnowledge(); if (r.success) { topHitDocuments.value = r.data?.topHitDocuments || []; missQuestions.value = r.data?.missQuestions || [] } } catch { /* */ }
}

// Chart.js 渲染
async function renderCharts() {
  const { Chart, LineController, LineElement, PointElement, LinearScale, CategoryScale, Tooltip, Legend, Filler } = await import('chart.js')
  Chart.register(LineController, LineElement, PointElement, LinearScale, CategoryScale, Tooltip, Legend, Filler)

  const labels = trendData.value.map((s: any) => { const d = new Date(s.snapshotDate || s.snapshot_date); return `${d.getMonth() + 1}/${d.getDate()}` })

  if (conversationChart) conversationChart.destroy()
  if (conversationChartRef.value) {
    conversationChart = new Chart(conversationChartRef.value, {
      type: 'line', data: { labels, datasets: [
        { label: '对话数', data: trendData.value.map((s: any) => s.conversationCount ?? s.conversation_count ?? 0), borderColor: palette.blue, backgroundColor: `rgba(${palette.blueRgb},0.1)`, fill: true, tension: 0.3, pointRadius: 4 },
        { label: '消息数', data: trendData.value.map((s: any) => s.messageCount ?? s.message_count ?? 0), borderColor: palette.purple, backgroundColor: `rgba(${palette.purpleRgb},0.1)`, fill: true, tension: 0.3, pointRadius: 4 }] },
      options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom', labels: { boxWidth: 12, font: { size: 12 } } } }, scales: { y: { beginAtZero: true }, x: { grid: { display: false } } } },
    })
  }

  if (satisfactionChart) satisfactionChart.destroy()
  if (satisfactionChartRef.value) {
    satisfactionChart = new Chart(satisfactionChartRef.value, {
      type: 'line', data: { labels, datasets: [
        { label: '👍 有帮助', data: trendData.value.map((s: any) => s.thumbsUpCount ?? s.thumbs_up_count ?? 0), borderColor: palette.green, backgroundColor: `rgba(${palette.greenRgb},0.1)`, fill: true, tension: 0.3, pointRadius: 4 },
        { label: '👎 没帮助', data: trendData.value.map((s: any) => s.thumbsDownCount ?? s.thumbs_down_count ?? 0), borderColor: palette.red, backgroundColor: `rgba(${palette.redRgb},0.1)`, fill: true, tension: 0.3, pointRadius: 4 }] },
      options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'bottom', labels: { boxWidth: 12, font: { size: 12 } } } }, scales: { y: { beginAtZero: true }, x: { grid: { display: false } } } },
    })
  }
}

function destroyCharts() { if (conversationChart) { conversationChart.destroy(); conversationChart = null }; if (satisfactionChart) { satisfactionChart.destroy(); satisfactionChart = null } }

onMounted(async () => { loading.value = true; await Promise.all([loadOverview(), loadTrend(7), loadKnowledge()]); loading.value = false })
onBeforeUnmount(() => destroyCharts())
</script>
