<template>
  <BaseCard :title="cardTitle">
    <template v-if="showDetailView" #headerExtra>
      <button class="back-btn" type="button" @click="closeDetail">
        <span class="back-chevron">&lt;</span>
        返回
      </button>
    </template>

    <div class="supply-panel" :class="{ expanded: isExpanded, 'detail-open': showDetailView }">
      <!-- 单条详情 -->
      <div v-if="showDetailView" class="detail-panel">
        <div v-if="detailLoading" class="state-box">加载中...</div>
        <div v-else-if="detailData" class="detail-content">
          <div class="detail-subtitle">
            <i class="subtitle-dot"></i>
            <span class="subtitle-name">{{ detailData.name }}</span>
            <span class="subtitle-dash">-</span>
            <span class="subtitle-highlight">详细信息</span>
          </div>

          <section class="detail-section">
            <div class="section-tab">
              <span class="section-tab-text">基本信息</span>
            </div>
            <div class="info-panel">
              <div
                v-for="(row, index) in basicInfoRows"
                :key="index"
                class="info-row-bar"
              >
                <div class="info-item">
                  <span class="info-label">{{ row.left.label }}:</span>
                  <span class="info-value">{{ row.left.value }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">{{ row.right.label }}:</span>
                  <span class="info-value">{{ row.right.value }}</span>
                </div>
              </div>
            </div>
          </section>

          <section class="detail-section stat-section">
            <div class="section-tab">
              <span class="section-tab-text">交易统计</span>
            </div>
            <div class="stat-cards">
              <div
                v-for="item in statMetrics"
                :key="item.key"
                class="stat-card"
                :class="item.theme"
              >
                <img class="stat-icon-img" :src="item.icon" :alt="item.label" />
                <span class="stat-label">{{ item.label }}</span>
                <span class="stat-number">{{ item.value }}</span>
                <span class="stat-unit">{{ item.unit }}</span>
              </div>
            </div>
          </section>

          <section class="detail-section">
            <div class="section-tab">
              <span class="section-tab-text">证件照片</span>
            </div>
            <div class="photo-row">
              <div
                v-for="photo in detailPhotos"
                :key="photo.key"
                class="photo-box"
              >
                <div
                  class="photo-frame"
                  :class="{ clickable: !!photo.url }"
                  @click="photo.url && openPhotoPreview(photo.url, photo.label)"
                >
                  <img
                    v-if="photo.url && !photoLoadErrors[photo.key]"
                    :src="photo.url"
                    :alt="photo.label"
                    @error="markPhotoError(photo.key)"
                  />
                  <span v-else class="photo-empty">暂无照片</span>
                  <span class="photo-caption">{{ photo.label }}</span>
                </div>
              </div>
            </div>
          </section>

          <section class="detail-section">
            <div class="section-tab">
              <span class="section-tab-text">成交订单</span>
            </div>
            <div v-if="!detailData.orders?.length" class="empty-orders">暂无成交订单</div>
            <div v-else class="orders-table">
              <div class="orders-head">
                <span>买方</span>
                <span>卖方</span>
                <span>交易时间</span>
                <span>交易数量</span>
                <span>称重照片</span>
                <span>称重重量</span>
              </div>
              <div v-for="order in detailData.orders" :key="order.id" class="orders-row">
                <span>{{ order.buyer || '--' }}</span>
                <span>{{ order.seller || detailData.name }}</span>
                <span>{{ order.tradeTime }}</span>
                <span>{{ order.quantity }}头</span>
                <span>
                  <img
                    v-if="orderWeightPhoto(order) && !weightPhotoErrors[order.id]"
                    class="weight-thumb clickable"
                    :src="orderWeightPhoto(order)"
                    alt="称重照片"
                    @click.stop="openPhotoPreview(orderWeightPhoto(order), '称重照片')"
                    @error="markWeightPhotoError(order.id)"
                  />
                  <span v-else class="weight-placeholder">--</span>
                </span>
                <span>{{ order.weight }}kg</span>
              </div>
            </div>
          </section>
        </div>
      </div>

      <div
        v-if="photoPreview.visible"
        class="photo-preview-mask"
        @click="closePhotoPreview"
      >
        <div class="photo-preview-panel" @click.stop>
          <div class="photo-preview-title">{{ photoPreview.title }}</div>
          <img class="photo-preview-img" :src="photoPreview.url" :alt="photoPreview.title" />
          <button type="button" class="photo-preview-close" @click="closePhotoPreview">关闭</button>
        </div>
      </div>

      <!-- 列表视图 -->
      <template v-if="!showDetailView">
        <div class="summary-bar">
          <div class="summary-stats">
            <span class="summary-item">
              <i class="dot"></i>
              <span class="label">今日进场:</span>
              <span class="value">{{ summary.todayEntries }}</span>
            </span>
            <span class="summary-item">
              <i class="dot"></i>
              <span class="label">总牦牛数:</span>
              <span class="value">{{ summary.totalYaks }}</span>
            </span>
            <span class="summary-item">
              <i class="dot"></i>
              <span class="label">在交易:</span>
              <span class="value">{{ summary.tradingCount }}</span>
            </span>
          </div>
          <button
            class="expand-btn"
            type="button"
            :title="isExpanded ? '收起' : '详细视图'"
            @click="toggleExpand"
          >
            <span class="expand-icon" :class="{ shrink: isExpanded }"></span>
          </button>
        </div>

        <div class="table-wrap">
          <div class="table-head">
            <span>姓名</span>
            <span>车牌号</span>
            <span>牦牛数量</span>
            <span>联系方式</span>
            <span>源头</span>
            <span>检疫号码</span>
            <span>进场时间</span>
            <span>交易进度</span>
            <span>操作</span>
          </div>

          <div v-if="loading" class="state-box">加载中...</div>
          <div v-else-if="error" class="state-box error">
            {{ error }}
            <button type="button" class="retry-btn" @click="loadList">重试</button>
          </div>
          <div v-else-if="list.length === 0" class="state-box">暂无数据</div>
          <div v-else class="table-body">
            <div v-for="row in list" :key="row.id" class="table-row">
              <span class="cell name" :title="row.name">{{ row.name }}</span>
              <span class="cell plate">{{ row.licensePlate }}</span>
              <span class="cell count">{{ row.yakCount }}头</span>
              <span class="cell contact">{{ maskPhone(row.contact) }}</span>
              <span class="cell origin" :title="row.origin">{{ row.origin || '--' }}</span>
              <span class="cell quarantine">{{ row.quarantineNo || '--' }}</span>
              <span class="cell time">{{ row.entryTime }}</span>
              <span class="cell progress">
                <CircleProgress :value="row.progress" />
              </span>
              <span class="cell action">
                <button
                  class="detail-action"
                  type="button"
                  title="详情"
                  @click="openDetail(row)"
                >
                  <span class="detail-icon" aria-hidden="true"></span>
                  <span v-if="isExpanded" class="detail-text">详情</span>
                </button>
              </span>
            </div>
          </div>
        </div>

        <div v-if="isExpanded && totalRecords > pageSize" class="pagination">
          <button type="button" class="page-btn" :disabled="currentPage <= 1" @click="changePage(currentPage - 1)">‹</button>
          <span class="page-info">{{ currentPage }} / {{ totalPages }}</span>
          <button type="button" class="page-btn" :disabled="currentPage >= totalPages" @click="changePage(currentPage + 1)">›</button>
        </div>
      </template>
    </div>
  </BaseCard>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, defineComponent, h } from 'vue'
import BaseCard from './BaseCard.vue'

const LIST_API = '/api/dashboard/yak-supply-realtime-info'
const DETAIL_API = '/api/dashboard/yak-supply-detail'
const STAT_ICONS = {
  total: '/images/总数量.png',
  traded: '/images/已交易.png',
  pending: '/images/待交易.png',
  orders: '/images/成交订单.png'
}

const props = defineProps({
  forceExpanded: {
    type: Boolean,
    default: false
  },
  initialDetailId: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['expand-change', 'initial-detail-applied'])

const isExpanded = computed(() => props.forceExpanded)
const cardTitle = computed(() => {
  if (showDetailView.value) {
    return '牦牛供应实时信息-详细视图-供应商详情'
  }
  return isExpanded.value ? '牦牛供应实时信息-详细视图' : '牦牛供应实时信息'
})

const summary = ref({ todayEntries: 0, totalYaks: 0, tradingCount: 0 })
const list = ref([])
const totalRecords = ref(0)
const loading = ref(false)
const error = ref(null)
const currentPage = ref(1)
const pageSize = computed(() => (isExpanded.value ? 10 : 5))

const showDetailView = ref(false)
const detailEntrySource = ref('')
const detailLoading = ref(false)
const detailData = ref(null)
const photoLoadErrors = ref({})
const weightPhotoErrors = ref({})
const photoPreview = ref({
  visible: false,
  url: '',
  title: ''
})

const basicInfoLeft = computed(() => {
  if (!detailData.value) return []
  return [
    { label: '姓名', value: detailData.value.name || '--' },
    { label: '联系方式', value: maskPhone(detailData.value.contact) },
    { label: '检疫号码', value: detailData.value.quarantineNo || '--' }
  ]
})

const basicInfoRight = computed(() => {
  if (!detailData.value) return []
  return [
    { label: '车牌号', value: detailData.value.licensePlate || '--' },
    { label: '源头', value: detailData.value.origin || '--' },
    { label: '进场时间', value: detailData.value.entryTime || '--' }
  ]
})

const basicInfoRows = computed(() => {
  return basicInfoLeft.value.map((left, index) => ({
    left,
    right: basicInfoRight.value[index] || { label: '', value: '--' }
  }))
})

const detailPhotos = computed(() => {
  if (!detailData.value) return []
  return [
    {
      key: 'entry',
      label: '入场照片',
      url: resolvePhoto(detailData.value.entryPhoto)
    },
    {
      key: 'cert',
      label: '检疫证',
      url: resolvePhoto(detailData.value.quarantineCert)
    }
  ]
})

const statMetrics = computed(() => {
  if (!detailData.value) return []
  return [
    {
      key: 'total',
      label: '总数量',
      value: detailData.value.yakCount ?? 0,
      unit: '头',
      icon: STAT_ICONS.total,
      theme: 'stat-blue'
    },
    {
      key: 'traded',
      label: '已交易',
      value: detailData.value.tradedCount ?? 0,
      unit: '头',
      icon: STAT_ICONS.traded,
      theme: 'stat-green'
    },
    {
      key: 'pending',
      label: '待交易',
      value: detailData.value.pendingCount ?? 0,
      unit: '头',
      icon: STAT_ICONS.pending,
      theme: 'stat-orange'
    },
    {
      key: 'orders',
      label: '成交订单',
      value: detailData.value.orderCount ?? detailData.value.orders?.length ?? 0,
      unit: '单',
      icon: STAT_ICONS.orders,
      theme: 'stat-teal'
    }
  ]
})

const totalPages = computed(() => Math.max(1, Math.ceil(totalRecords.value / pageSize.value)))

const getProgressColor = (value) => {
  if (value >= 100) return '#1AFC7A'
  if (value >= 75) return '#B8E986'
  if (value >= 50) return '#FFD700'
  return '#FF8C00'
}

const CircleProgress = defineComponent({
  props: {
    value: { type: Number, default: 0 }
  },
  setup(props) {
    return () => {
      const pct = Math.max(0, Math.min(100, Number(props.value) || 0))
      const color = getProgressColor(pct)
      const radius = 14
      const circumference = 2 * Math.PI * radius
      const offset = circumference * (1 - pct / 100)

      return h('div', { class: 'circle-progress' }, [
        h('svg', { viewBox: '0 0 36 36', class: 'circle-svg' }, [
          h('circle', {
            cx: 18,
            cy: 18,
            r: radius,
            fill: 'none',
            stroke: 'rgba(255,255,255,0.12)',
            'stroke-width': 3
          }),
          h('circle', {
            cx: 18,
            cy: 18,
            r: radius,
            fill: 'none',
            stroke: color,
            'stroke-width': 3,
            'stroke-linecap': 'round',
            'stroke-dasharray': `${circumference}`,
            'stroke-dashoffset': `${offset}`,
            transform: 'rotate(-90 18 18)'
          })
        ]),
        h('span', { class: 'circle-text', style: { color } }, `${pct}%`)
      ])
    }
  }
})

const maskPhone = (phone) => {
  if (!phone) return '--'
  const text = String(phone)
  if (text.length < 7) return text
  return `${text.slice(0, 3)}****${text.slice(-4)}`
}

const resolvePhoto = (value) => {
  if (!value) return ''
  const text = String(value).trim()
  if (!text) return ''
  if (text.startsWith('data:')) return text
  if (text.startsWith('http://localhost:8080')) {
    return text.replace('http://localhost:8080', '')
  }
  if (text.startsWith('http://127.0.0.1:8080')) {
    return text.replace('http://127.0.0.1:8080', '')
  }
  if (text.startsWith('http') || text.startsWith('/')) {
    return text
  }
  if (text.startsWith('profile/')) {
    return `/${text}`
  }
  if (/^\d{4}\/\d{2}\/\d{2}\//.test(text)) {
    return `/profile/${text}`
  }
  return ''
}

const orderWeightPhoto = (order) => resolvePhoto(order?.weightPhoto)

const markPhotoError = (key) => {
  photoLoadErrors.value = { ...photoLoadErrors.value, [key]: true }
}

const markWeightPhotoError = (orderId) => {
  weightPhotoErrors.value = { ...weightPhotoErrors.value, [orderId]: true }
}

const openPhotoPreview = (url, title = '照片预览') => {
  const resolved = resolvePhoto(url)
  if (!resolved) return
  photoPreview.value = {
    visible: true,
    url: resolved,
    title
  }
}

const closePhotoPreview = () => {
  photoPreview.value = {
    visible: false,
    url: '',
    title: ''
  }
}

const loadList = async () => {
  loading.value = true
  error.value = null
  try {
    const params = new URLSearchParams({
      pageNo: String(currentPage.value),
      pageSize: String(pageSize.value)
    })
    const response = await fetch(`${LIST_API}?${params}`)
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }
    const result = await response.json()
    if (result.code !== undefined && result.code !== 1) {
      throw new Error(result.message || '接口返回异常')
    }
    const payload = result.data ?? result
    summary.value = payload.summary || { todayEntries: 0, totalYaks: 0, tradingCount: 0 }
    list.value = payload.list || []
    totalRecords.value = Number(payload.total) || list.value.length
  } catch (err) {
    error.value = err.message || '加载失败'
    list.value = []
  } finally {
    loading.value = false
  }
}

const loadDetail = async (id) => {
  detailLoading.value = true
  detailData.value = null
  photoLoadErrors.value = {}
  weightPhotoErrors.value = {}
  closePhotoPreview()
  try {
    const response = await fetch(`${DETAIL_API}?id=${encodeURIComponent(id)}`)
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }
    const result = await response.json()
    if (result.code !== undefined && result.code !== 1) {
      throw new Error(result.message || '接口返回异常')
    }
    detailData.value = result.data ?? result
  } catch (err) {
    console.error('加载供应详情失败:', err)
  } finally {
    detailLoading.value = false
  }
}

const openDetail = (row) => {
  if (!isExpanded.value) {
    emit('expand-change', { expanded: true, detailId: row.id })
    return
  }
  detailEntrySource.value = 'expanded'
  showDetailView.value = true
  loadDetail(row.id)
}

const closeDetail = () => {
  if (detailEntrySource.value === 'compact') {
    emit('expand-change', false)
  }
  showDetailView.value = false
  detailData.value = null
  detailEntrySource.value = ''
}

const toggleExpand = () => {
  emit('expand-change', !isExpanded.value)
}

const changePage = (page) => {
  currentPage.value = page
  loadList()
}

watch(isExpanded, () => {
  currentPage.value = 1
  if (!showDetailView.value) {
    loadList()
  }
})

watch(
  () => props.initialDetailId,
  (id) => {
    if (!id || !isExpanded.value) return
    detailEntrySource.value = 'compact'
    showDetailView.value = true
    loadDetail(id)
    emit('initial-detail-applied')
  },
  { immediate: true }
)

onMounted(() => {
  loadList()
  window.addEventListener('dataReloaded', loadList)
})

onUnmounted(() => {
  window.removeEventListener('dataReloaded', loadList)
})
</script>

<style scoped>
.supply-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
  min-height: 0;
}

.summary-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 4px 6px;
  flex-shrink: 0;
}

.summary-stats {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.summary-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Microsoft YaHei', sans-serif;
}

.summary-item .label,
.summary-item .value {
  font-size: 13px;
  color: #D9F1FF;
}

.summary-item .value {
  font-weight: 700;
}

.dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
  background: rgba(217, 241, 255, 0.55);
}

.expand-btn {
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid rgba(217, 241, 255, 0.35);
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.expand-icon {
  width: 10px;
  height: 10px;
  border: 1px solid rgba(217, 241, 255, 0.75);
  position: relative;
}

.expand-icon::before,
.expand-icon::after {
  content: '';
  position: absolute;
  background: rgba(217, 241, 255, 0.75);
}

.expand-icon::before {
  width: 1px;
  height: 6px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.expand-icon::after {
  width: 6px;
  height: 1px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.expand-icon.shrink::before {
  display: none;
}

.table-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(65, 166, 252, 0.22);
  background: rgba(6, 24, 48, 0.35);
  overflow: hidden;
}

.table-head,
.table-row {
  display: grid;
  grid-template-columns: 0.9fr 0.85fr 0.7fr 0.95fr 1fr 0.85fr 1.05fr 0.85fr 0.65fr;
  align-items: center;
}

.table-head {
  background: rgba(3, 60, 110, 0.55);
  border-bottom: 1px solid rgba(65, 166, 252, 0.25);
  flex-shrink: 0;
}

.table-head span {
  padding: 8px 4px;
  font-size: 12px;
  font-weight: 700;
  color: #D9F1FF;
  text-align: center;
  font-family: 'Microsoft YaHei', sans-serif;
}

.table-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.table-row {
  border-bottom: 1px solid rgba(65, 166, 252, 0.08);
  min-height: 36px;
}

.table-row:hover {
  background: rgba(65, 166, 252, 0.06);
}

.cell {
  padding: 6px 4px;
  font-size: 12px;
  color: #D9F1FF;
  font-weight: 400;
  text-align: center;
  font-family: 'Microsoft YaHei', sans-serif;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell.action {
  display: flex;
  align-items: center;
  justify-content: center;
}

.detail-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  color: #41A6FC;
  transition: color 0.2s ease;
}

.detail-action:hover {
  color: #6bb8ff;
}

.detail-action:hover .detail-icon {
  border-color: #6bb8ff;
  background: rgba(65, 166, 252, 0.2);
}

.detail-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: 1px solid rgba(65, 166, 252, 0.55);
  background: rgba(65, 166, 252, 0.1);
  position: relative;
  box-sizing: border-box;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.detail-icon::before {
  content: '';
  position: absolute;
  left: 3px;
  top: 2px;
  width: 5px;
  height: 6px;
  border: 1px solid currentColor;
  border-radius: 1px;
}

.detail-icon::after {
  content: '';
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 5px;
  height: 5px;
  border: 1px solid currentColor;
  border-radius: 50%;
  box-sizing: border-box;
}

.detail-text {
  font-size: 12px;
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
}

.supply-panel.expanded .detail-action {
  gap: 8px;
}

.supply-panel.expanded .detail-text {
  font-size: 13px;
}

:deep(.circle-progress) {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  justify-content: center;
}

:deep(.circle-svg) {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}

:deep(.circle-text) {
  font-size: 11px;
  font-weight: 700;
  min-width: 30px;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding-top: 4px;
  flex-shrink: 0;
}

.page-btn {
  width: 24px;
  height: 24px;
  border: 1px solid rgba(65, 166, 252, 0.35);
  background: rgba(255, 255, 255, 0.05);
  color: #D9F1FF;
  cursor: pointer;
}

.page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.page-info {
  font-size: 12px;
  color: rgba(217, 241, 255, 0.75);
}

.state-box {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 80px;
  color: rgba(217, 241, 255, 0.7);
  font-size: 13px;
}

.state-box.error {
  color: #FE4A46;
  flex-direction: column;
}

.retry-btn {
  border: 1px solid rgba(254, 74, 70, 0.45);
  background: transparent;
  color: #FE4A46;
  padding: 4px 10px;
  cursor: pointer;
}

.detail-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.back-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid rgba(65, 166, 252, 0.55);
  background: rgba(3, 40, 78, 0.65);
  color: #41A6FC;
  padding: 2px 10px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'Microsoft YaHei', sans-serif;
  line-height: 22px;
  white-space: nowrap;
}

.back-chevron {
  font-size: 11px;
  line-height: 1;
}

.detail-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 18px 4px 12px 0;
  box-sizing: border-box;
}

.detail-subtitle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 32px;
  font-family: 'Microsoft YaHei', sans-serif;
  font-size: 18px;
  color: #0CE3FC;
  flex-shrink: 0;
}

.subtitle-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #0CE3FC;
  flex-shrink: 0;
}

.subtitle-name,
.subtitle-dash,
.subtitle-highlight {
  font-size: 18px;
  color: #0CE3FC;
  font-weight: 600;
}

.detail-section {
  position: relative;
  margin-bottom: 0;
  padding: 18px 12px 14px;
  border: 0.5px solid #1096A1;
  background: rgba(6, 24, 48, 0.35);
  overflow: visible;
  flex-shrink: 0;
}

.detail-section + .detail-section {
  /* 26px 梯形标题向上 + 约 22px 与上一模块底边的留白 */
  margin-top: 48px;
}

.section-tab {
  --tab-slant: 16px;
  --tab-border: 0.5px;
  position: absolute;
  top: 0;
  left: calc(-1 * var(--tab-border));
  transform: translateY(calc(-100% + var(--tab-border)));
  height: 26px;
  padding: 0 calc(14px + var(--tab-slant)) 0 12px;
  display: inline-flex;
  align-items: center;
  z-index: 2;
  pointer-events: none;
}

.section-tab::before {
  content: '';
  position: absolute;
  inset: calc(-1 * var(--tab-border)) calc(-1 * var(--tab-border)) 0 calc(-1 * var(--tab-border));
  background: #1096A1;
  clip-path: polygon(0 0, calc(100% - var(--tab-slant)) 0, 100% 100%, 0 100%);
  z-index: -2;
}

.section-tab::after {
  content: '';
  position: absolute;
  inset: var(--tab-border) var(--tab-border) 0 var(--tab-border);
  background: linear-gradient(180deg, rgba(10, 36, 66, 0.98) 0%, rgba(6, 24, 48, 0.98) 100%);
  clip-path: polygon(0 0, calc(100% - var(--tab-slant)) 0, 100% 100%, 0 100%);
  z-index: -1;
}

.section-tab-text {
  position: relative;
  z-index: 1;
  font-size: 14px;
  font-weight: 700;
  color: #0CE3FC;
  line-height: 1;
  font-family: 'Microsoft YaHei', sans-serif;
  letter-spacing: 0.5px;
  white-space: nowrap;
}

.info-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-row-bar {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
  height: 36px;
  min-height: 36px;
  padding: 0 12px;
  box-sizing: border-box;
  background: #15a2d01a;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.info-label {
  flex-shrink: 0;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.88);
  line-height: 1;
  font-family: 'Microsoft YaHei', sans-serif;
}

.info-value {
  min-width: 0;
  font-size: 13px;
  color: #ffffff;
  font-weight: 500;
  line-height: 1;
  word-break: break-all;
}

.stat-section {
  padding-top: 18px;
  padding-bottom: 14px;
}

.stat-cards {
  display: grid;
  grid-template-columns: repeat(4, 284px);
  justify-content: space-evenly;
  align-items: center;
  width: 100%;
}

.stat-card {
  flex: 0 0 284px;
  width: 284px;
  max-width: 284px;
  height: 64px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: center;
  justify-items: center;
  padding: 0;
  box-sizing: border-box;
  position: relative;
  border: none;
  border-bottom: 2px solid transparent;
}

.stat-icon-img {
  width: 36px;
  height: 36px;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
}

.stat-label {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.88);
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
  font-family: 'Microsoft YaHei', sans-serif;
}

.stat-number {
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  font-family: 'Arial Black', 'Microsoft YaHei', sans-serif;
  letter-spacing: 0;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
  background-image: linear-gradient(180deg, #ffffff 0%, #c8f0ff 35%, #0385F2 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.stat-unit {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
  font-family: 'Microsoft YaHei', sans-serif;
}

.stat-blue {
  background: linear-gradient(180deg, rgba(3, 133, 242, 0.04) 0%, rgba(3, 133, 242, 0.2) 55%, rgba(3, 133, 242, 0.36) 100%);
  border-bottom-color: rgba(3, 133, 242, 0.88);
  box-shadow: inset 0 -8px 16px rgba(3, 133, 242, 0.2);
}

.stat-blue .stat-number {
  background-image: linear-gradient(180deg, #ffffff 0%, #7ec8ff 45%, #0385F2 100%);
  filter: drop-shadow(0 1px 2px rgba(3, 133, 242, 0.35));
}

.stat-green {
  background: linear-gradient(180deg, rgba(26, 252, 122, 0.04) 0%, rgba(26, 252, 122, 0.16) 55%, rgba(26, 252, 122, 0.3) 100%);
  border-bottom-color: rgba(26, 252, 122, 0.85);
  box-shadow: inset 0 -8px 16px rgba(26, 252, 122, 0.18);
}

.stat-green .stat-number {
  background-image: linear-gradient(180deg, #ffffff 0%, #8affc8 45%, #1AFC7A 100%);
  filter: drop-shadow(0 1px 2px rgba(26, 252, 122, 0.35));
}

.stat-orange {
  background: linear-gradient(180deg, rgba(240, 165, 23, 0.04) 0%, rgba(240, 165, 23, 0.16) 55%, rgba(240, 165, 23, 0.32) 100%);
  border-bottom-color: rgba(240, 165, 23, 0.88);
  box-shadow: inset 0 -8px 16px rgba(240, 165, 23, 0.18);
}

.stat-orange .stat-number {
  background-image: linear-gradient(180deg, #ffffff 0%, #ffe08a 45%, #F0A517 100%);
  filter: drop-shadow(0 1px 2px rgba(240, 165, 23, 0.35));
}

.stat-teal {
  background: linear-gradient(180deg, rgba(11, 253, 242, 0.04) 0%, rgba(11, 253, 242, 0.14) 55%, rgba(11, 253, 242, 0.28) 100%);
  border-bottom-color: rgba(11, 253, 242, 0.85);
  box-shadow: inset 0 -8px 16px rgba(11, 253, 242, 0.18);
}

.stat-teal .stat-number {
  background-image: linear-gradient(180deg, #ffffff 0%, #8afffa 45%, #0BFDF2 100%);
  filter: drop-shadow(0 1px 2px rgba(11, 253, 242, 0.35));
}

.photo-row {
  display: flex;
  gap: 24px;
}

.photo-box {
  flex-shrink: 0;
}

.photo-frame {
  position: relative;
  width: 96px;
  height: 96px;
  border: 1px solid rgba(65, 166, 252, 0.28);
  background: rgba(12, 28, 48, 0.85);
  overflow: hidden;
}

.photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 18px 4px 8px;
  font-size: 11px;
  color: rgba(217, 241, 255, 0.72);
  text-align: center;
  background: linear-gradient(180deg, transparent 0%, rgba(6, 20, 40, 0.92) 100%);
}

.orders-table {
  border: 1px solid rgba(65, 166, 252, 0.22);
  background: rgba(4, 18, 36, 0.45);
  overflow: hidden;
}

.orders-head,
.orders-row {
  display: grid;
  grid-template-columns: 1.15fr 1fr 1.15fr 0.8fr 0.8fr 0.9fr;
  gap: 4px;
  padding: 9px 8px;
  font-size: 12px;
  text-align: center;
  align-items: center;
  font-family: 'Microsoft YaHei', sans-serif;
}

.orders-head {
  background: rgba(3, 60, 110, 0.55);
  color: #D9F1FF;
  font-weight: 700;
}

.orders-row {
  border-top: 1px solid rgba(65, 166, 252, 0.1);
  color: #D9F1FF;
}

.empty-orders {
  padding: 16px;
  text-align: center;
  color: rgba(217, 241, 255, 0.55);
  font-size: 12px;
}

.weight-thumb {
  width: 36px;
  height: 36px;
  object-fit: cover;
  border: 1px solid rgba(65, 166, 252, 0.25);
  background: rgba(255, 255, 255, 0.04);
}

.photo-frame.clickable {
  cursor: pointer;
}

.photo-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 18px;
  font-size: 11px;
  color: rgba(217, 241, 255, 0.45);
  font-family: 'Microsoft YaHei', sans-serif;
}

.photo-preview-mask {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.72);
}

.photo-preview-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: min(90vw, 720px);
  max-height: 90vh;
  padding: 16px;
  border: 1px solid rgba(65, 166, 252, 0.45);
  background: rgba(6, 24, 48, 0.96);
  box-sizing: border-box;
}

.photo-preview-title {
  font-size: 14px;
  color: #0CE3FC;
  font-family: 'Microsoft YaHei', sans-serif;
}

.photo-preview-img {
  max-width: 100%;
  max-height: calc(90vh - 100px);
  object-fit: contain;
  border: 1px solid rgba(65, 166, 252, 0.25);
  background: rgba(255, 255, 255, 0.04);
}

.photo-preview-close {
  border: 1px solid rgba(65, 166, 252, 0.45);
  background: rgba(3, 40, 78, 0.65);
  color: #41A6FC;
  padding: 4px 16px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'Microsoft YaHei', sans-serif;
}

.clickable {
  cursor: pointer;
}

.weight-placeholder {
  display: inline-block;
  min-width: 36px;
  color: rgba(217, 241, 255, 0.45);
  font-size: 12px;
}

.supply-panel.detail-open.expanded .info-value {
  font-size: 14px;
}

.supply-panel.detail-open.expanded .orders-head,
.supply-panel.detail-open.expanded .orders-row {
  font-size: 13px;
  padding: 10px 8px;
}

.supply-panel.expanded .table-head span,
.supply-panel.expanded .cell {
  font-size: 13px;
  padding-top: 10px;
  padding-bottom: 10px;
}

.supply-panel.expanded .summary-item .label,
.supply-panel.expanded .summary-item .value {
  font-size: 14px;
}

.table-body::-webkit-scrollbar,
.detail-content::-webkit-scrollbar {
  width: 4px;
}

.table-body::-webkit-scrollbar-thumb,
.detail-content::-webkit-scrollbar-thumb {
  background: rgba(65, 166, 252, 0.45);
  border-radius: 2px;
}
</style>
