<template>
  <div class="goods-detail-page">
    <div class="page-header">
      <div class="header-left">
        <el-button @click="goBack" link class="back-btn">
          <el-icon><ArrowLeft /></el-icon> 返回列表
        </el-button>
        <el-divider direction="vertical" />
        <span class="page-title">用户商品详情</span>
        <el-tag v-if="detail" :type="currentTag === '云服务器' ? 'primary' : 'info'" size="small" style="margin-left:8px">{{ detail.tag || detail.good?.tag || '通用' }}</el-tag>
      </div>
      <div class="header-right">
        <el-button plain @click="loadDetail" :loading="loading">
          <el-icon><Refresh /></el-icon> 刷新
        </el-button>
        <el-button type="primary" plain @click="openEdit" :disabled="!detail">
          <el-icon><Edit /></el-icon> 编辑
        </el-button>
        <el-button type="danger" plain @click="handleDelete" :disabled="!detail">
          <el-icon><Delete /></el-icon> 删除
        </el-button>
      </div>
    </div>

    <div class="main-content" v-loading="loading">
      <el-empty v-if="!loading && !detail" description="未找到商品数据" :image-size="160">
        <el-button type="primary" @click="loadDetail">重新加载</el-button>
      </el-empty>

      <template v-if="detail">
        <!-- 已删除提示 -->
        <el-alert
          v-if="isDeleted"
          type="error"
          :closable="false"
          show-icon
          class="deleted-alert"
          title="该用户商品已删除"
          :description="`删除时间：${deletedTime}。已删除商品仅展示上游快照信息（itemArg），不再请求虚拟机等实时详情。`"
        />

        <!-- Hero 概览区 -->
        <div class="hero-section">
          <div class="hero-left">
            <div class="hero-icon">
              <svg viewBox="0 0 48 48" width="44" height="44" fill="none" xmlns="http://www.w3.org/2000/svg">
                <rect x="4" y="8" width="40" height="28" rx="4" stroke="currentColor" stroke-width="2.5" />
                <path d="M16 40h16" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" />
                <path d="M24 36v4" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" />
                <circle cx="24" cy="22" r="6" stroke="currentColor" stroke-width="2" />
                <path d="M24 19v3l2 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
              </svg>
            </div>
            <div class="hero-info">
              <h1 class="hero-name">{{ detail.good?.name || '用户商品 #' + goodsId }}</h1>
              <div class="hero-meta">
                <span class="meta-chip">
                  <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM1 8a7 7 0 1114 0A7 7 0 011 8z" fill="currentColor"/><path d="M8 4v4.5l3 1.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
                  {{ expireLabel }}
                </span>
                <span class="meta-chip" :class="expireStatusClass">
                  <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><circle cx="8" cy="8" r="4" fill="currentColor"/></svg>
                  {{ expireStatusText }}
                </span>
                <span class="meta-chip id-chip">ID: {{ detail.id || goodsId }}</span>
                <span v-if="isDeleted" class="meta-chip status-deleted">
                  <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><circle cx="8" cy="8" r="4" fill="currentColor"/></svg>
                  已删除
                </span>
              </div>
            </div>
          </div>
          <div class="hero-right">
            <div class="price-block">
              <div class="price-label">续费价格</div>
              <div class="price-value">{{ detail.renewPrice ? '¥' + (detail.renewPrice / 100).toFixed(2) : '-' }}</div>
            </div>
            <div class="price-divider"></div>
            <div class="price-block">
              <div class="price-label">基础价格</div>
              <div class="price-value secondary">{{ (detail.basePrice || detail.base_price) ? '¥' + ((detail.basePrice || detail.base_price) / 100).toFixed(2) : '-' }}</div>
            </div>
          </div>
        </div>

        <!-- 数据指标卡片行 -->
        <div class="metrics-row">
          <div class="metric-card is-link" @click="goToUser">
            <div class="metric-icon" style="background:#eef3ff;color:#4f6ef7">
              <svg viewBox="0 0 20 20" width="20" height="20" fill="none"><circle cx="10" cy="7" r="3.5" stroke="currentColor" stroke-width="1.5"/><path d="M3 17c0-2.76 3.13-5 7-5s7 2.24 7 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
            </div>
            <div class="metric-body">
              <div class="metric-label">所属用户</div>
              <div class="metric-value">#{{ detail.userId || detail.user_id || '-' }}</div>
              <div class="metric-name">{{ detail.user?.userName || '-' }}</div>
            </div>
            <div class="metric-arrow">
              <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
            </div>
          </div>
          <div class="metric-card is-link" @click="goToProduct">
            <div class="metric-icon" style="background:#f0faf0;color:#52c41a">
              <svg viewBox="0 0 20 20" width="20" height="20" fill="none"><path d="M17 7l-7-4-7 4v6l7 4 7-4V7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M10 11v7M3 7l7 4 7-4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
            </div>
            <div class="metric-body">
              <div class="metric-label">关联商品</div>
              <div class="metric-value">#{{ detail.goodId || '-' }}</div>
              <div class="metric-name">{{ detail.good?.name || '-' }}</div>
            </div>
            <div class="metric-arrow">
              <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
            </div>
          </div>
          <div class="metric-card is-link" @click="goToOrder">
            <div class="metric-icon" style="background:#fff7ed;color:#f5a623">
              <svg viewBox="0 0 20 20" width="20" height="20" fill="none"><rect x="3" y="3" width="14" height="14" rx="2.5" stroke="currentColor" stroke-width="1.5"/><path d="M6 7h8M6 10h5.5M6 13h3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
            </div>
            <div class="metric-body">
              <div class="metric-label">关联订单</div>
              <div class="metric-value">#{{ detail.orderId || '-' }}</div>
              <div class="metric-name">{{ detail.order?.name || '-' }}</div>
            </div>
            <div class="metric-arrow">
              <svg viewBox="0 0 16 16" width="14" height="14" fill="none"><path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
            </div>
          </div>
          <div class="metric-card">
            <div class="metric-icon" style="background:#fef0f0;color:#f56c6c">
              <svg viewBox="0 0 20 20" width="20" height="20" fill="none"><path d="M10 2l2.47 5.01L18 7.75l-4 3.9.94 5.51L10 14.51l-4.94 2.65.94-5.51-4-3.9 5.53-.74z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
            </div>
            <div class="metric-body">
              <div class="metric-label">套餐ID</div>
              <div class="metric-value">#{{ detail.goodPlanId || detail.good_plan_id || '-' }}</div>
            </div>
          </div>
          <div class="metric-card">
            <div class="metric-icon" style="background:#f5f0ff;color:#722ed1">
              <svg viewBox="0 0 20 20" width="20" height="20" fill="none"><path d="M7 3h6l4 4v9a1 1 0 01-1 1H4a1 1 0 01-1-1V7l4-4z" stroke="currentColor" stroke-width="1.5"/><path d="M7 3v4H3M10 9v5M8 12h4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
            </div>
            <div class="metric-body">
              <div class="metric-label">归属项ID</div>
              <div class="metric-value">#{{ detail.itemId || '-' }}</div>
            </div>
          </div>
        </div>

        <!-- 详细信息折叠区 -->
        <div class="detail-section">
          <div class="section-header" @click="detailExpanded = !detailExpanded">
            <div class="section-header-left">
              <svg viewBox="0 0 20 20" width="18" height="18" fill="none"><rect x="2" y="3" width="16" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/><path d="M6 7h8M6 10h5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
              <span class="section-title">详细信息</span>
            </div>
            <el-icon :class="{ 'is-expanded': detailExpanded }"><ArrowDown /></el-icon>
          </div>
          <transition name="slide">
            <div v-show="detailExpanded" class="section-body">
              <div class="info-grid">
                <div class="info-item">
                  <span class="info-label">商品标签</span>
                  <span class="info-value"><el-tag size="small" type="info">{{ detail.good?.tag || detail.tag || '-' }}</el-tag></span>
                </div>
                <div class="info-item">
                  <span class="info-label">商品Table</span>
                  <span class="info-value">{{ detail.good?.table || '-' }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">备注</span>
                  <span class="info-value">{{ detail.note || '-' }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">订单状态</span>
                  <span class="info-value">
                    <el-tag v-if="detail.order" :type="detail.order.state === 1 ? 'success' : detail.order.state === 0 ? 'warning' : 'info'" size="small">
                      {{ detail.order.state === 1 ? '已支付' : detail.order.state === 0 ? '待支付' : '已失效' }}
                    </el-tag>
                    <span v-else>-</span>
                  </span>
                </div>
                <div class="info-item">
                  <span class="info-label">创建时间</span>
                  <span class="info-value">{{ formatTime(detail.CreatedAt) }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">更新时间</span>
                  <span class="info-value">{{ formatTime(detail.UpdatedAt) }}</span>
                </div>
              </div>
            </div>
          </transition>
        </div>

        <!-- 已删除：展示 itemArg 上游快照信息，不再请求虚拟机详情 -->
        <el-card v-if="isDeleted" shadow="hover" class="related-card">
          <template #header>
            <div class="card-header-row">
              <svg viewBox="0 0 20 20" width="18" height="18" fill="none"><rect x="2" y="3" width="16" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/><path d="M6 7h8M6 10h5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
              <span class="card-title">上游快照信息 (itemArg)</span>
            </div>
          </template>
          <el-descriptions v-if="itemArgEntries.length" :column="2" border size="small">
            <el-descriptions-item v-for="item in itemArgEntries" :key="item.key" :label="item.label">
              {{ item.value }}
            </el-descriptions-item>
          </el-descriptions>
          <el-empty v-else description="该商品无 itemArg 快照信息" :image-size="100" />
        </el-card>

        <!-- 类型适配栏目区域 -->
        <UserVmDetail v-else-if="currentTag === '云服务器'" embedded :goods-id="goodsId" />

        <el-card v-else-if="detail.good" shadow="hover" class="related-card">
          <template #header>
            <div class="card-header-row">
              <svg viewBox="0 0 20 20" width="18" height="18" fill="none"><path d="M10 2l2.47 5.01L18 7.75l-4 3.9.94 5.51L10 14.51l-4.94 2.65.94-5.51-4-3.9 5.53-.74z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
              <span class="card-title">关联信息</span>
            </div>
          </template>
          <el-descriptions :column="2" border size="small">
            <el-descriptions-item label="商品名称">{{ detail.good?.name || '-' }}</el-descriptions-item>
            <el-descriptions-item label="商品Table">{{ detail.good?.table || '-' }}</el-descriptions-item>
            <el-descriptions-item label="商品标签">{{ detail.good?.tag || detail.tag || '-' }}</el-descriptions-item>
            <el-descriptions-item label="订单名称">{{ detail.order?.name || '-' }}</el-descriptions-item>
            <el-descriptions-item label="订单状态">
              <el-tag v-if="detail.order" :type="detail.order.state === 1 ? 'success' : detail.order.state === 0 ? 'warning' : 'info'" size="small">
                {{ detail.order.state === 1 ? '已支付' : detail.order.state === 0 ? '待支付' : '已失效' }}
              </el-tag>
              <span v-else>-</span>
            </el-descriptions-item>
            <el-descriptions-item label="用户ID">{{ detail.userId || '-' }}</el-descriptions-item>
          </el-descriptions>
        </el-card>
      </template>
    </div>

    <!-- 编辑弹窗 -->
    <el-dialog v-model="editVisible" title="编辑用户商品" width="520px" destroy-on-close>
      <el-form :model="editForm" label-width="110px">
        <el-form-item label="备注"><el-input v-model="editForm.note" /></el-form-item>
        <el-form-item label="续费价格">
          <div class="unit-input-row">
            <el-input-number v-model="editForm.renew_price" :min="0" :precision="2" controls-position="right" style="flex:1" />
            <span class="unit-text">元</span>
          </div>
        </el-form-item>
        <el-form-item label="基础价格">
          <div class="unit-input-row">
            <el-input-number v-model="editForm.base_price" :min="0" :precision="2" controls-position="right" style="flex:1" />
            <span class="unit-text">元</span>
          </div>
        </el-form-item>
        <el-form-item label="到期时间"><el-date-picker v-model="editForm.expire_time" type="datetime" placeholder="选择到期时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" /></el-form-item>
        <el-form-item label="归属项">
          <div style="width:100%">
            <template v-if="detail?.good?.table === 'kvm_service'">
              <div class="selector-row" style="margin-bottom:8px">
                <el-input :model-value="editForm._serviceName || (editForm._serviceId ? `主控服务 #${editForm._serviceId}` : '')"
                  readonly placeholder="1. 选择主控服务" style="flex:1" />
                <el-button type="primary" @click="showServiceSelector = true" style="margin-left:8px">选择</el-button>
                <el-button v-if="editForm._serviceId" @click="editForm._serviceId = 0; editForm._serviceName = ''; editForm.item_id = 0; editForm._itemName = ''" style="margin-left:4px">清除</el-button>
              </div>
              <div class="selector-row">
                <el-input :model-value="editForm._itemName || (editForm.item_id ? `虚拟机 #${editForm.item_id}` : '')"
                  readonly placeholder="2. 选择虚拟机" style="flex:1" />
                <el-button type="primary" @click="showVmSelector = true" :disabled="!editForm._serviceId" style="margin-left:8px">选择</el-button>
                <el-button v-if="editForm.item_id" @click="editForm.item_id = 0; editForm._itemName = ''" style="margin-left:4px">清除</el-button>
              </div>
              <div style="font-size:12px;color:#909399;margin-top:4px">归属项为虚拟机ID，需先选择主控服务</div>
            </template>
            <el-input-number v-else v-model="editForm.item_id" :min="0" controls-position="right" style="width:100%" />
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitLoading" @click="submitEdit">确定</el-button>
      </template>
    </el-dialog>

    <VmSelectorPopup v-model="showVmSelector" :service-id="editForm._serviceId || 0"
      @confirm="vm => { editForm.item_id = vm.id; editForm._itemName = vm.name }" />
    <KvmServiceSelector v-model="showServiceSelector"
      @confirm="s => { editForm._serviceId = s.id; editForm._serviceName = s.name; editForm.item_id = 0; editForm._itemName = '' }" />
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onActivated, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, ArrowDown, Refresh, Edit, Delete } from '@element-plus/icons-vue'
import { getUserGoodsDetail, updateUserGoods, deleteUserGoods } from '@/api/admin/userVm'
import { extractApiError } from '@/utils/kvmErrorUtil'
import VmSelectorPopup from '@/components/admin/VmSelectorPopup.vue'
import KvmServiceSelector from '@/components/admin/KvmServiceSelector.vue'
import UserVmDetail from '@/views/user-vm/UserVmDetail.vue'
import dayjs from 'dayjs'

const route = useRoute()
const router = useRouter()
const goodsId = computed(() => parseInt(route.params.id) || 0)

const loading = ref(false)
const submitLoading = ref(false)
const detail = ref(null)
const detailExpanded = ref(false)

const formatTime = (t) => t ? dayjs(t).format('YYYY-MM-DD HH:mm:ss') : '-'
const formatExpireTime = (t) => {
  if (!t) return '-'
  const d = dayjs(t)
  if (d.year() < 2000) return '永久'
  return d.format('YYYY-MM-DD HH:mm:ss')
}

const expireLabel = computed(() => formatExpireTime(detail.value?.expireTime || detail.value?.expire_time))

const expireStatusText = computed(() => {
  const t = detail.value?.expireTime || detail.value?.expire_time
  if (!t) return '未知'
  const d = dayjs(t)
  if (d.year() < 2000) return '永久有效'
  const diff = d.diff(dayjs(), 'day')
  if (diff < 0) return '已到期'
  if (diff <= 7) return `即将到期 (${diff}天)`
  return '正常'
})

const expireStatusClass = computed(() => {
  const t = detail.value?.expireTime || detail.value?.expire_time
  if (!t) return ''
  const d = dayjs(t)
  if (d.year() < 2000) return 'status-forever'
  const diff = d.diff(dayjs(), 'day')
  if (diff < 0) return 'status-expired'
  if (diff <= 7) return 'status-warning'
  return 'status-ok'
})

const goBack = () => router.push('/user-goods/list')

const currentTag = computed(() => (detail.value?.tag || detail.value?.good?.tag || '').toLowerCase())

// 是否已删除（后端返回 deleteAt 字段，有值即已删除）
const isDeleted = computed(() => !!(detail.value?.deleteAt || detail.value?.DeleteAt || detail.value?.deleted_at))
const deletedTime = computed(() => {
  const t = detail.value?.deleteAt || detail.value?.DeleteAt || detail.value?.deleted_at
  return t ? formatTime(t) : '-'
})

// 解析 itemArg（可能是 JSON 字符串或对象），用于已删除商品展示上游快照信息
const parsedItemArg = computed(() => {
  const raw = detail.value?.itemArg ?? detail.value?.ItemArg ?? detail.value?.item_arg
  if (!raw) return null
  if (typeof raw === 'string') {
    try { return JSON.parse(raw) } catch { return null }
  }
  if (typeof raw === 'object') return raw
  return null
})

// itemArg 字段中文标签映射
const itemArgLabelMap = {
  id: '实例ID',
  name: '实例名称',
  vcpu: 'CPU核数',
  memory: '内存',
  status: '运行状态',
  state: '运行状态',
  ips: 'IP地址',
  ip: 'IP地址',
  disk: '磁盘',
  bandwidth: '带宽',
  image: '镜像',
  image_name: '镜像名称',
  os_type: '系统类型'
}

// 将 itemArg 转换为可展示的键值对列表
const itemArgEntries = computed(() => {
  const obj = parsedItemArg.value
  if (!obj || typeof obj !== 'object') return []
  return Object.entries(obj)
    .filter(([, v]) => v !== null && v !== undefined && v !== '' && typeof v !== 'object')
    .map(([k, v]) => ({
      key: k,
      label: itemArgLabelMap[k] || k,
      value: String(v)
    }))
})

const loadDetail = async () => {
  if (!goodsId.value) return
  loading.value = true
  try {
    const res = await getUserGoodsDetail({ id: goodsId.value })
    if (res?.data?.code === 200 && res?.data?.data) {
      detail.value = res.data.data.data ?? res.data.data
    } else ElMessage.error(extractApiError(res?.data, '加载失败'))
  } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '加载失败')) }
  finally { loading.value = false }
}

const goToUser = () => {
  const uid = detail.value?.userId || detail.value?.user_id
  if (!uid) return
  router.push({ path: '/user/detail', query: { user_id: uid } })
}
const goToProduct = () => {
  const gid = detail.value?.goodId
  if (!gid) return
  router.push({ path: '/product/manage', query: { good_id: gid } })
}
const goToOrder = () => {
  const oid = detail.value?.orderId
  if (!oid) return
  router.push({ path: '/order/list', query: { order_id: oid } })
}

const editVisible = ref(false)
const editForm = reactive({ note: '', renew_price: 0, base_price: 0, expire_time: '', item_id: 0, _serviceId: 0, _serviceName: '', _itemName: '' })
const showVmSelector = ref(false)
const showServiceSelector = ref(false)

const openEdit = () => {
  const rawRenew = detail.value?.renewPrice || detail.value?.renew_price || 0
  const rawBase = detail.value?.basePrice || detail.value?.base_price || 0
  Object.assign(editForm, {
    note: detail.value?.note || '',
    renew_price: rawRenew / 100,
    base_price: rawBase / 100,
    expire_time: detail.value?.expireTime || detail.value?.expire_time
      ? dayjs(detail.value?.expireTime || detail.value?.expire_time).format('YYYY-MM-DD HH:mm:ss')
      : '',
    item_id: detail.value?.itemId || detail.value?.item_id || 0,
    _serviceId: 0,
    _serviceName: '',
    _itemName: detail.value?.itemId ? `虚拟机 #${detail.value.itemId}` : ''
  })
  editVisible.value = true
}

const submitEdit = async () => {
  submitLoading.value = true
  try {
    const data = { id: goodsId.value }
    if (editForm.note !== undefined) data.note = editForm.note
    if (editForm.renew_price) data.renew_price = Math.round(editForm.renew_price * 100)
    if (editForm.base_price) data.base_price = Math.round(editForm.base_price * 100)
    if (editForm.expire_time) data.expire_time = editForm.expire_time
    if (editForm.item_id) data.item_id = editForm.item_id
    const res = await updateUserGoods(data)
    if (res?.data?.code === 200) { ElMessage.success('修改成功'); editVisible.value = false; loadDetail() }
    else ElMessage.error(extractApiError(res?.data, '修改失败'))
  } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '修改失败')) }
  finally { submitLoading.value = false }
}

const handleDelete = () => {
  ElMessageBox.confirm('确定删除该用户商品吗？', '删除确认', { type: 'warning' })
    .then(async () => {
      try {
        const res = await deleteUserGoods({ id: goodsId.value })
        if (res?.data?.code === 200) { ElMessage.success('删除成功'); goBack() }
        else ElMessage.error(extractApiError(res?.data, '删除失败'))
      } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
    }).catch(() => {})
}

let isInitialMount = true
onMounted(loadDetail)
onActivated(() => {
  if (isInitialMount) {
    isInitialMount = false
    return
  }
  detail.value = null
  loadDetail()
})
watch(goodsId, (newId, oldId) => {
  if (newId && newId !== oldId) { detail.value = null; loadDetail() }
})
</script>

<style scoped>
.goods-detail-page { padding: 0; }

/* ---- Page Header ---- */
.page-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 20px; background: #fff; border-bottom: 1px solid #ebeef5; }
.header-left { display: flex; align-items: center; gap: 0; }
.back-btn { font-size: 14px; color: #606266; }
.back-btn:hover { color: #409eff; }
.page-title { font-size: 16px; font-weight: 600; color: #303133; }
.header-right { display: flex; gap: 8px; }

/* ---- Main Content ---- */
.main-content { padding: 20px; min-height: 300px; }

/* ---- Hero Section ---- */
.hero-section {
  display: flex; justify-content: space-between; align-items: center;
  background: linear-gradient(135deg, #f0f5ff 0%, #f8faff 60%, #fff 100%);
  border: 1px solid #e1e8f0; border-radius: 10px;
  padding: 24px 28px; gap: 24px;
}
.hero-left { display: flex; align-items: center; gap: 20px; flex: 1; min-width: 0; }
.hero-icon {
  width: 72px; height: 72px; border-radius: 16px;
  background: linear-gradient(135deg, #409eff 0%, #6366f1 100%);
  color: #fff; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; box-shadow: 0 6px 16px rgba(64, 158, 255, 0.25);
}
.hero-info { min-width: 0; flex: 1; }
.hero-name { font-size: 20px; font-weight: 700; color: #1a1a2e; margin: 0 0 10px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hero-meta { display: flex; gap: 10px; flex-wrap: wrap; }
.meta-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: #606266; background: #fff; border: 1px solid #e8e8e8;
  padding: 3px 10px; border-radius: 20px; white-space: nowrap;
}
.meta-chip.id-chip { font-family: 'SF Mono', 'Consolas', monospace; letter-spacing: 0.3px; }
.meta-chip.status-ok { color: #52c41a; border-color: #b7eb8f; background: #f6ffed; }
.meta-chip.status-warning { color: #fa8c16; border-color: #ffd591; background: #fff7e6; }
.meta-chip.status-expired { color: #f5222d; border-color: #ffa39e; background: #fff1f0; }
.meta-chip.status-forever { color: #722ed1; border-color: #d3adf7; background: #f9f0ff; }
.meta-chip.status-deleted { color: #f5222d; border-color: #ffa39e; background: #fff1f0; }

.deleted-alert { margin-bottom: 16px; }

.hero-right { display: flex; align-items: center; gap: 0; flex-shrink: 0; }
.price-block { text-align: center; padding: 0 20px; }
.price-label { font-size: 12px; color: #909399; margin-bottom: 6px; }
.price-value { font-size: 22px; font-weight: 700; color: #1a1a2e; }
.price-value.secondary { color: #606266; font-weight: 600; }
.price-divider { width: 1px; height: 36px; background: #e0e0e0; }

/* ---- Metrics Row ---- */
.metrics-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-top: 16px; }
.metric-card {
  display: flex; align-items: center; gap: 12px;
  background: #fff; border: 1px solid #ebeef5; border-radius: 8px;
  padding: 14px 16px; transition: all 0.2s; position: relative;
}
.metric-card:hover { border-color: #d0d5dd; box-shadow: 0 2px 8px rgba(0,0,0,0.04); }
.metric-card.is-link { cursor: pointer; }
.metric-card.is-link:hover { border-color: #409eff; background: #f8fbff; box-shadow: 0 2px 12px rgba(64, 158, 255, 0.08); }
.metric-card.is-link:hover .metric-arrow { color: #409eff; transform: translateX(2px); }
.metric-card.is-link:hover .metric-value { color: #409eff; }
.metric-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.metric-body { min-width: 0; flex: 1; }
.metric-label { font-size: 12px; color: #909399; margin-bottom: 2px; }
.metric-value { font-size: 15px; font-weight: 600; color: #303133; font-family: 'SF Mono', 'Consolas', monospace; transition: color 0.2s; }
.metric-name { font-size: 12px; color: #909399; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.metric-arrow { color: #c0c4cc; transition: all 0.2s; flex-shrink: 0; }

/* ---- Detail Section (collapsible) ---- */
.detail-section {
  margin-top: 16px; background: #fff; border: 1px solid #ebeef5; border-radius: 8px;
  overflow: hidden;
}
.section-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px; cursor: pointer; user-select: none;
  transition: background 0.15s;
}
.section-header:hover { background: #fafbfc; }
.section-header-left { display: flex; align-items: center; gap: 8px; color: #303133; }
.section-title { font-size: 14px; font-weight: 600; }
.section-header .el-icon { transition: transform 0.25s; color: #909399; font-size: 14px; }
.section-header .el-icon.is-expanded { transform: rotate(180deg); }
.section-body { padding: 0 18px 18px; }
.info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px 24px; }
.info-item { display: flex; flex-direction: column; gap: 4px; }
.info-label { font-size: 12px; color: #909399; }
.info-value { font-size: 14px; color: #303133; font-weight: 500; }

.slide-enter-active, .slide-leave-active { transition: all 0.25s ease; overflow: hidden; }
.slide-enter-from, .slide-leave-to { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; }
.slide-enter-to, .slide-leave-from { opacity: 1; max-height: 300px; }

/* ---- Related Card (fallback for non-VM) ---- */
.related-card { margin-top: 16px; border: 1px solid #ebeef5; border-radius: 8px; }
.card-header-row { display: flex; align-items: center; gap: 8px; color: #303133; }
.card-title { font-size: 15px; font-weight: 600; color: #303133; }

/* ---- Shared ---- */
.selector-row { display: flex; align-items: center; width: 100%; }
.unit-input-row { display: flex; align-items: center; gap: 6px; width: 100%; }
.unit-text { font-size: 13px; color: #606266; flex-shrink: 0; white-space: nowrap; }

:deep(.el-descriptions__label) { font-weight: 500; color: #606266; }
</style>
