<script setup>
import { computed } from 'vue'
import { ServerOutline, DocumentTextOutline, GitNetworkOutline, OptionsOutline } from '@vicons/ionicons5'
import { NButton, NIcon, NSwitch, NInputNumber, NSelect } from 'naive-ui'

const props = defineProps({
  enabled: Object,
  topK: Number,
  strategy: String,
  busy: Boolean,
  structuredSourceId: [String, Number],
  graphSourceId: [String, Number],
  structuredSourceName: String,
  structuredProfile: Object,
  structuredProfileLoading: Boolean,
  graphReadiness: Object,
  graphReadinessLoading: Boolean,
  structuredSourceOptions: { type: Array, default: () => [] },
  graphSourceOptions: { type: Array, default: () => [] }
})
const emit = defineEmits(['update:enabled', 'update:topK', 'update:strategy', 'update:structuredSourceId', 'update:graphSourceId', 'refreshStructuredSources', 'refreshStructuredProfile', 'refreshGraphReadiness'])

const graphStats = computed(() => {
  if (props.graphReadinessLoading) return '图谱画像加载中'
  if (!props.graphReadiness) return '尚未选择图谱数据源'
  if (props.graphReadiness.nodeCount != null || props.graphReadiness.relationshipCount != null) {
    return `节点 ${props.graphReadiness.nodeCount ?? '-'}　|　关系 ${props.graphReadiness.relationshipCount ?? '-'}`
  }
  return `Labels ${props.graphReadiness.labels ?? '-'}　|　关系模式 ${props.graphReadiness.relationshipPatterns ?? '-'}`
})

const cards = computed(() => [
  { key: 'document', title: '文档知识库', subtitle: 'Milvus', detail: 'bge-m3 (dense)  |  BM25 (sparse)', stats: '文档 128　|　Chunk 12,480', icon: DocumentTextOutline, tone: 'blue' },
  { key: 'structured', title: '结构化数据', subtitle: props.structuredSourceName || '请选择数据源', detail: '真实 Schema / Text2SQL', stats: props.structuredProfile ? `画像 ${props.structuredProfile.scanStatus || '-'}　|　表 ${props.structuredProfile.tableCount ?? '-'}` : '尚未选择结构化数据源', icon: ServerOutline, tone: 'green' },
  { key: 'graph', title: '知识图谱', subtitle: 'Neo4j', detail: '节点 / 关系 / 路径', stats: graphStats.value, icon: GitNetworkOutline, tone: 'purple' }
])

function toggle(key, value) {
  emit('update:enabled', { ...props.enabled, [key]: value })
}
</script>

<template>
  <section class="panel source-panel">
    <h2><n-icon><OptionsOutline /></n-icon> 数据源编排 / 检索配置</h2>
    <div class="source-list">
      <article v-for="card in cards" :key="card.key" class="source-card" :class="card.tone">
        <div class="source-icon"><n-icon><component :is="card.icon" /></n-icon></div>
        <div class="source-copy">
          <strong>{{ card.title }}</strong>
          <span>{{ card.subtitle }}</span>
          <small>{{ card.detail }}</small>
          <small>{{ card.stats }}</small>
        </div>
        <div class="source-toggle">
          <em>{{ enabled[card.key] ? '已启用' : '已停用' }}</em>
          <n-switch :value="enabled[card.key]" :disabled="busy" @update:value="toggle(card.key, $event)" />
        </div>
      </article>
    </div>
    <div class="config-card">
      <h3>检索配置</h3>
      <div class="config-row source-picker"><span>结构化数据源</span><div class="picker-actions"><n-select :value="structuredSourceId" :options="structuredSourceOptions" :disabled="busy || !enabled.structured" size="small" placeholder="请选择数据源" @update:value="emit('update:structuredSourceId', $event)" /><n-button size="tiny" :disabled="busy" @click="emit('refreshStructuredSources')">刷新</n-button></div></div>
      <div v-if="structuredSourceId != null" class="profile-status"><span>Text2SQL画像</span><b>{{ structuredProfileLoading ? '加载中' : (structuredProfile?.scanStatus || 'UNKNOWN') }}</b><small>表 {{ structuredProfile?.tableCount ?? '-' }}　物理关系 {{ structuredProfile?.physicalRelationships ?? '-' }}　推断关系 {{ structuredProfile?.inferredRelationships ?? '-' }}</small><n-button size="tiny" :loading="structuredProfileLoading" :disabled="busy" @click="emit('refreshStructuredProfile')">刷新画像</n-button></div>
      <label><span>图谱数据源</span><n-select :value="graphSourceId" :options="graphSourceOptions" :disabled="busy || !enabled.graph" size="small" placeholder="请选择" @update:value="emit('update:graphSourceId', $event)" /></label>
      <div v-if="graphSourceId != null" class="profile-status"><span>图谱画像</span><b>{{ graphReadinessLoading ? '加载中' : `就绪度 ${graphReadiness?.readinessScore ?? '-'}` }}</b><small>Labels {{ graphReadiness?.labels ?? '-' }}　关系模式 {{ graphReadiness?.relationshipPatterns ?? '-' }}　查询模式 {{ graphReadiness?.supportedQueryModes?.length ?? '-' }}</small><n-button size="tiny" :loading="graphReadinessLoading" :disabled="busy" @click="emit('refreshGraphReadiness')">刷新图谱</n-button></div>
      <label><span>TopK</span><n-input-number :value="topK" :min="1" :max="20" size="small" @update:value="emit('update:topK', $event)" /></label>
      <label><span>检索策略</span><n-select :value="strategy" :options="[{label:'Hybrid',value:'hybrid'},{label:'Dense',value:'dense'}]" size="small" @update:value="emit('update:strategy', $event)" /></label>
      <label><span>父级上下文扩展</span><b>L2</b></label>
      <label><span>调试模式</span><b class="on">开</b></label>
    </div>
  </section>
</template>

<style scoped>
.panel{height:100%;padding:18px;border:1px solid rgba(72,142,220,.28);border-radius:12px;background:rgba(4,18,40,.74);overflow:auto}.panel h2{display:flex;align-items:center;gap:9px;font-size:16px;margin-bottom:16px}.panel h2 .n-icon{color:#2aa8ff}.source-list{display:flex;flex-direction:column;gap:10px}.source-card{position:relative;display:grid;grid-template-columns:54px 1fr auto;gap:12px;align-items:start;padding:14px;border:1px solid rgba(58,133,214,.35);border-radius:11px;background:linear-gradient(135deg,rgba(12,43,79,.8),rgba(8,26,50,.72))}.source-card.green{border-color:rgba(30,190,123,.3);background:linear-gradient(135deg,rgba(9,63,57,.7),rgba(7,29,42,.75))}.source-card.purple{border-color:rgba(139,92,246,.32);background:linear-gradient(135deg,rgba(49,34,97,.72),rgba(11,26,51,.75))}.source-icon{width:50px;height:50px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:28px;color:#42b6ff;background:rgba(24,115,220,.22)}.green .source-icon{color:#52e1a2;background:rgba(25,180,116,.2)}.purple .source-icon{color:#b792ff;background:rgba(126,76,220,.2)}.source-copy{display:flex;flex-direction:column;min-width:0}.source-copy strong{font-size:16px}.source-copy span{font-size:14px;margin:2px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.source-copy small{color:#8ea6c5;font-size:11px;line-height:1.6}.source-toggle{display:flex;align-items:center;gap:7px}.source-toggle em{font-style:normal;color:#25dc8d;font-size:11px;white-space:nowrap}.config-card{margin-top:14px;padding:15px;border:1px solid rgba(67,131,210,.25);border-radius:10px;background:rgba(9,29,58,.72)}.config-card h3{font-size:14px;margin-bottom:10px}.config-card label,.config-card .config-row{min-height:38px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid rgba(86,134,190,.14);font-size:12px;color:#9db1cc}.config-card label:last-child{border:0}.config-card .n-input-number,.config-card .n-select{width:105px}.config-card b{color:#d6e5f8;font-weight:500}.config-card .on{color:#34d399}.source-picker{align-items:flex-start!important;padding:8px 0}.picker-actions{display:flex;align-items:center;gap:6px}.picker-actions .n-select{width:205px}.profile-status{margin:6px 0 10px;padding:9px;border:1px solid rgba(46,190,129,.25);border-radius:7px;background:rgba(10,57,51,.45);display:grid;grid-template-columns:1fr auto;gap:5px 8px;font-size:11px}.profile-status span{color:#a9bdd6}.profile-status b{color:#38dc93}.profile-status small{grid-column:1/-1;color:#8fa9c4}.profile-status .n-button{justify-self:end}
</style>
