<template>
  <Teleport to="body">
    <transition name="panel-slide">
      <div v-if="visible" class="info-panel">
        <div class="panel-hd">
          <span class="panel-title">{{ title }}</span>
          <el-icon class="panel-close" @click="close"><Close /></el-icon>
        </div>
        <div class="panel-tabs">
          <el-tabs v-model="activeTab" type="border-card">
            <el-tab-pane v-for="tab in tabs" :key="tab.name" :label="tab.name" :name="tab.name">
              <div class="tab-content" v-loading="tab.loading">
                <!-- 键值对布局 -->
                <template v-if="tab.type === 'kv'">
                  <div class="kv-list">
                    <div class="kv-row" v-for="(v, k) in tab.data" :key="k">
                      <span class="kv-key">{{ tab.labelMap?.[k] || k }}</span>
                      <span class="kv-value">{{ formatVal(v) }}</span>
                    </div>
                  </div>
                </template>
                <!-- 表格数据 -->
                <template v-else-if="tab.type === 'table' && tab.data">
                  <el-table :data="Array.isArray(tab.data) ? tab.data : [tab.data]" border size="small" max-height="420">
                    <el-table-column v-for="col in tab.columns" :key="col.key"
                      :prop="col.key" :label="col.label" :width="col.width"
                      :show-overflow-tooltip="true" />
                  </el-table>
                </template>
                <!-- HTML 内容 -->
                <template v-else-if="tab.type === 'html'">
                  <div v-html="tab.html" />
                </template>
                <!-- 空 -->
                <template v-else>
                  <el-empty description="暂无数据" />
                </template>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </transition>
  </Teleport>
</template>

<script setup>
import { ref } from 'vue'

const visible = ref(false)
const title = ref('')
const activeTab = ref('')
const tabs = ref([])

const show = (opts) => {
  title.value = opts.title || '详情'
  tabs.value = opts.tabs || [{ name: '基本信息', type: 'table', data: opts.attributes, loading: false }]
  activeTab.value = tabs.value[0]?.name || ''
  visible.value = true
}

const close = () => { visible.value = false }

const updateTab = (tabName, data) => {
  const tab = tabs.value.find(t => t.name === tabName)
  if (tab) {
    tab.data = data
    tab.loading = false
  }
}

const formatVal = (v) => {
  if (v === null || v === undefined) return '-'
  return String(v)
}

defineExpose({ show, close, updateTab })
</script>

<style scoped>
.info-panel {
  position: fixed; right: 0; top: 0; bottom: 0; width: 420px; z-index: 1001;
  background: #fff; box-shadow: -4px 0 20px rgba(0,0,0,.15);
  display: flex; flex-direction: column;
}
.panel-hd {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; background: #409EFF; color: #fff;
  font-size: 15px; font-weight: 500; flex-shrink: 0;
}
.panel-close { cursor: pointer; font-size: 18px; }
.panel-tabs { flex: 1; overflow: hidden; }
.panel-tabs :deep(.el-tabs) { height: 100%; display: flex; flex-direction: column; }
.panel-tabs :deep(.el-tabs__content) { flex: 1; overflow-y: auto; padding: 8px; }
.tab-content { min-height: 200px; }

.kv-list { padding: 4px 0; }
.kv-row {
  display: flex; align-items: flex-start; padding: 6px 0;
  border-bottom: 1px dashed #e8e8e8; font-size: 13px;
}
.kv-key {
  min-width: 90px; max-width: 130px; color: #888; flex-shrink: 0;
  text-align: right; padding-right: 12px; word-break: break-all;
}
.kv-value {
  color: #333; flex: 1; word-break: break-all;
}

.panel-slide-enter-active { transition: transform .3s ease; }
.panel-slide-leave-active { transition: transform .25s ease; }
.panel-slide-enter-from { transform: translateX(100%); }
.panel-slide-leave-to { transform: translateX(100%); }
</style>
