<template>
  <div>
    <!-- 仪表盘 -->
    <div v-show="activeMenu === 'dashboard'" class="section-content">

      <!-- Row 1: 6 个统计卡 — 文字在上，数字在下 -->
      <div class="dash-row dash-row-stats">
        <el-card
          v-for="item in statItems" :key="item.key"
          class="stat-card"
          shadow="never"
        >
          <div class="stat-label">{{ item.label }}</div>
          <div class="stat-value">{{ (stats as any)[item.key] ?? 0 }}</div>
        </el-card>
      </div>

      <!-- Row 2: 网盘使用空间 -->
      <div class="dash-row">
        <el-card class="storage-card" shadow="never">
          <template #header>
            <span>💾 网盘存储空间</span>
          </template>
          <div class="storage-grid">
            <div
              v-for="item in stats.cloudUsage" :key="item.cloudType + '-' + (item.nickname || '')"
              class="storage-drive-card"
            >
              <div class="drive-header">
                <img :src="driveIcon(item.cloudType)" class="drive-icon" />
                <span class="drive-name">{{ item.nickname || item.cloudType }}</span>
                <span :class="['drive-status', item.isActive ? 'active' : 'inactive']">
                  {{ item.isActive ? '正常' : '停用' }}
                </span>
              </div>
              <div class="drive-space">
                <span class="drive-used">{{ item.storageUsed || '--' }}</span>
                <span class="drive-sep">/</span>
                <span class="drive-total">{{ item.storageTotal || '--' }}</span>
              </div>
              <el-progress
                :percentage="cloudStoragePercent(item)"
                :stroke-width="10"
                :color="cloudStoragePercent(item) > 80 ? '#f56c6c' : cloudStoragePercent(item) > 60 ? '#e6a23c' : '#67c23a'"
              />
            </div>
            <el-empty v-if="stats.cloudUsage.length === 0" description="暂无网盘数据" :image-size="72" />
          </div>
        </el-card>
      </div>

      <!-- Row 3: 近 7 天趋势 + 热门搜索关键词 Top 20 + 操作来源 IP Top 10 -->
      <div class="dash-row dash-row-cols-3">
        <el-card class="insight-card trend-card" shadow="never">
          <template #header>
            <div class="insight-header">
              <span>📈 使用趋势</span>
              <div class="trend-day-btns">
                <button
                  v-for="d in trendDayOptions" :key="d"
                  :class="['trend-day-btn', { active: trendDays === d }]"
                  @click="switchTrendDays(d)"
                >{{ d }}天</button>
              </div>
            </div>
          </template>
          <div v-if="trendSummary" class="trend-summary-row">
            <div class="trend-summary-item">
              <span class="trend-summary-num">{{ trendSummary.totalSearches }}</span>
              <span class="trend-summary-desc">总搜索</span>
            </div>
            <div class="trend-summary-item">
              <span class="trend-summary-num">{{ trendSummary.totalSaves }}</span>
              <span class="trend-summary-desc">总保存</span>
            </div>
            <div class="trend-summary-item">
              <span class="trend-summary-num">{{ trendSummary.avgSearches }}/{{ trendSummary.avgSaves }}</span>
              <span class="trend-summary-desc">日均搜索/保存</span>
            </div>
            <div class="trend-summary-item">
              <span class="trend-summary-num">{{ trendSummary.peakDay }}</span>
              <span class="trend-summary-desc">峰值日 {{ trendSummary.peakSearches }}+{{ trendSummary.peakSaves }}</span>
            </div>
          </div>
          <div ref="chartRef" class="trend-chart-echarts"></div>
        </el-card>

        <el-card class="insight-card" shadow="never">
          <template #header><span>🔍 热门搜索 Top 20</span></template>
          <div class="keyword-list">
            <el-tag
              v-for="(kw, i) in stats.hotKeywords" :key="kw.keyword"
              :type="keywordTagType(i)"
              size="small"
              class="keyword-tag"
            >{{ kw.keyword }}<sup class="kw-count">{{ kw.count }}</sup></el-tag>
            <el-empty v-if="stats.hotKeywords.length === 0" description="暂无搜索数据" :image-size="56" />
          </div>
        </el-card>

        <el-card class="insight-card" shadow="never">
          <template #header>
            <el-tabs v-model="rightTab" class="card-tabs" @tab-click="handleTabClick">
              <el-tab-pane label="🌐 IP Top 10" name="ip" />
              <el-tab-pane label="🗺️ 地域 Top 10" name="province" />
            </el-tabs>
          </template>
          <div class="ip-list" v-show="rightTab === 'ip'">
            <div v-for="(ip, i) in stats.topIps" :key="ip.ip" class="ip-row">
              <span class="ip-rank">{{ i + 1 }}</span>
              <span class="ip-addr">{{ ip.ip }}</span>
              <span class="ip-loc" v-if="ip.ip_location">{{ formatLocation(ip.ip_location) }}</span>
              <span class="ip-count">{{ ip.count }} 次</span>
            </div>
            <el-empty v-if="stats.topIps.length === 0" description="暂无数据" :image-size="56" />
          </div>
          <div class="province-list" v-show="rightTab === 'province'">
            <div
              v-for="(item, i) in stats.provinceRankings.slice(0, 10)"
              :key="item.province"
              class="province-row"
            >
              <span class="province-rank">{{ i + 1 }}</span>
              <span class="province-bar-wrap">
                <span
                  class="province-bar"
                  :style="{
                    width: (item.count / maxProvinceCount) * 100 + '%',
                    background: provinceBarColor(i),
                  }"
                ></span>
              </span>
              <span class="province-name">{{ item.province }}</span>
              <span class="province-count">{{ item.count }} 次</span>
            </div>
            <el-empty v-if="!stats.provinceRankings?.length" description="暂无数据" :image-size="56" />
          </div>
        </el-card>
      </div>
    </div>

    <!-- 网盘设置及授权 -->
    <div v-if="showCloudToggle" class="section-content">
      <el-card class="config-card" shadow="never">
        <template #header>
          <span>📂 网盘类型开关</span>
        </template>
        <div class="cloud-toggle-grid">
          <div
            v-for="ct in cloudTypes"
            :key="ct.type"
            class="cloud-toggle-chip"
          >
            <img :src="ct.icon" class="cloud-icon-img" />
            <span class="cloud-label">{{ ct.label }}</span>
            <el-tag v-if="ct.type === 'others'" size="small" type="info">关</el-tag>
            <el-switch
              :model-value="ct.enabled"
              size="small"
              @change="(val: boolean) => handleCloudToggle(ct.type, val)"
            />
          </div>
        </div>
        <div class="form-tip" style="margin-top: 12px;">
          关闭的网盘类型在搜索结果中不会展示。修改后立即生效，无需点击保存。
        </div>
      </el-card>
      <CloudConfig />
    </div>

    <!-- 系统配置 -->
    <div v-if="showSystemConfig" class="section-content">
      <SystemConfig :section="activeSystemSection" />
    </div>

    <!-- 转存日志 -->
    <div v-if="activeMenu === 'save-records'" class="section-content">
      <SaveRecords />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, reactive, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useTrendChart, type TrendSummary } from '../../composables/useTrendChart'
import {
  DataBoard,
  Connection,
  Setting,
  SwitchButton,
  DocumentCopy,
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { getStats, getCloudConfigs, getSiteConfig, getCloudTypes, toggleCloudType } from '../../api'
import type { StatsData } from '../../types'
import CloudConfig from './CloudConfig.vue'
import SystemConfig from './SystemConfig.vue'
import SaveRecords from './SaveRecords.vue'

interface CloudTypeInfo {
  type: string
  label: string
  icon: string
  enabled: boolean
}

const router = useRouter()

const appVersion = ref("")
const stats = ref<StatsData>({
  todaySearches: 0,
  todaySaves: 0,
  monthSearches: 0,
  monthSaves: 0,
  totalSearches: 0,
  totalSaves: 0,
  hotKeywords: [],
  trendTrend: [],
  cloudUsage: [],
  topIps: [],
  provinceRankings: [],
})
const siteName = ref('')
const cloudTypes = ref<CloudTypeInfo[]>([])

// ── ECharts trend chart (via composable) ──
/** ── Trend summary (MUST be declared before useTrendChart callback) ── */

const { chartRef: _chartRef, render: renderTrendChart, initResize: initTrendChart } = useTrendChart(computed(() => stats.value.trendTrend), (s: any) => { trendSummary.value = s })
const chartRef = _chartRef as any

// Force render after mount (data may already be loaded)
watch(() => stats.value.trendTrend, () => {
  renderTrendChart()
}, { deep: true })

// Reload chart when switching back to dashboard
watch(() => activeMenu.value, (val, oldVal) => {
  if (val === 'dashboard' && oldVal !== 'dashboard') {
    nextTick(() => {
      const el = document.querySelector('.trend-chart-echarts') as HTMLElement | null
      if (el && el.childElementCount === 0) {
        renderTrendChart()
        initTrendChart()
      } else if (el) {
        initTrendChart()
      }
    })
  }
})

// ── Dashboard stat items: label top, value bottom ──
const statItems = [
  { key: 'todaySearches', label: '今日搜索' },
  { key: 'todaySaves', label: '今日保存' },
  { key: 'monthSearches', label: '本月搜索' },
  { key: 'monthSaves', label: '本月保存' },
  { key: 'totalSearches', label: '总搜索量' },
  { key: 'totalSaves', label: '总保存量' },
]

function keywordTagType(i: number): string {
  if (i === 0) return 'danger'
  if (i < 3) return 'warning'
  if (i < 8) return ''
  return 'info'
}

/** Strip "中国/China" prefix from location string for consistent display */
function formatLocation(loc: string): string {
  if (!loc) return ''
  return loc.replace(/^(中国|China)\s*/i, '').trim()
}

// ── Province ranking helpers ──
const maxProvinceCount = computed(() => {
  const items = stats.value.provinceRankings
  return items.length > 0 ? Math.max(...items.map(i => i.count)) : 1
})
const PROVINCE_COLORS = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399', '#b37feb', '#36cfc9', '#ff85c0']
function provinceBarColor(i: number): string {
  return PROVINCE_COLORS[i % PROVINCE_COLORS.length]
}

// ── Right card tabs ──
const rightTab = ref('ip')
function handleTabClick() {
  // no-op for now, tabs handle switching via v-show
}

// ── Drive icon lookup from API data ──
const FALLBACK_ICON = 'data:image/svg+xml,' + encodeURIComponent('<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><rect rx="4" width="24" height="24" fill="#909399"/><text x="12" y="16" text-anchor="middle" fill="white" font-size="14" font-weight="bold" font-family="Arial">☁</text></svg>')
function driveIcon(type: string): string {
  return cloudTypes.value.find(c => c.type === type)?.icon || FALLBACK_ICON
}

// ── Trend day range ──
const trendDayOptions = [7, 15, 30, 60]
const trendDays = ref(7)
const trendSummary = ref<TrendSummary | null>(null)
async function switchTrendDays(d: number) {
  trendDays.value = d
  await loadStats()
}

// Menu selection
const activeMenu = ref('dashboard')
const activeSystemSection = ref('')

// ── Recent saves ──
const recentSaves = ref<any[]>([])
const systemInfo = reactive({
  uptime: '--',
  memory: '--',
  version: '--',
  dbOk: false,
  redisOk: false,
  pansouOk: false,
})

async function loadRecentSaves() {
  try {
    const res = await fetch('/api/admin/save-records?pageSize=5&page=1')
    const data = await res.json()
    recentSaves.value = data.records || data.data || []
  } catch { recentSaves.value = [] }
}

async function loadSystemInfo() {
  try {
    const res = await fetch('/health')
    const h = await res.json()
    systemInfo.uptime = formatUptime(h.uptime || 0)
    systemInfo.memory = formatBytes(h.memory || 0)
    systemInfo.version = h.version || '--'
    systemInfo.dbOk = h.components?.db === 'connected'
    systemInfo.redisOk = h.components?.redis === 'connected'
    systemInfo.pansouOk = h.components?.pansou === 'ok'
  } catch {}
}

function formatUptime(s: number): string {
  const d = Math.floor(s / 86400)
  const h = Math.floor((s % 86400) / 3600)
  const m = Math.floor((s % 3600) / 60)
  const parts = []
  if (d > 0) parts.push(d + '天')
  if (h > 0) parts.push(h + '时')
  parts.push(m + '分')
  return parts.join(' ')
}

function formatBytes(b: number): string {
  if (b >= 1073741824) return (b / 1073741824).toFixed(1) + ' GB'
  if (b >= 1048576) return (b / 1048576).toFixed(0) + ' MB'
  return (b / 1024).toFixed(0) + ' KB'
}

function formatSaveTime(t: string): string {
  if (!t) return ''
  const d = new Date(t)
  if (isNaN(d.getTime())) return t.slice(0, 10)
  const diff = Date.now() - d.getTime()
  const mins = Math.floor(diff / 60000)
  if (mins < 60) return mins <= 1 ? '刚刚' : mins + '分钟前'
  const hours = Math.floor(mins / 60)
  if (hours < 24) return hours + '小时前'
  return t.slice(0, 10)
}

const pageTitles: Record<string, string> = {
  dashboard: '仪表盘',
  'save-records': '转存日志',
}
const sysSectionTitles: Record<string, string> = {
  'sys-site': '网站设置',
  'sys-services': '外部服务 & 缓存',
  'sys-strategy': '搜索结果展示策略',
  'sys-validation': '链接验证配置',
  'sys-filter': '搜索标题过滤规则',
  'sys-password': '修改管理员密码',
}

const pageTitle = computed(() => {
  if (activeMenu.value.startsWith('sys-')) {
    return '系统配置 — ' + (sysSectionTitles[activeMenu.value] || '')
  }
  if (activeMenu.value === 'cloud-configs-toggle' || activeMenu.value === 'cloud-configs-cleanup') {
    return '网盘管理'
  }
  return pageTitles[activeMenu.value] || '管理后台'
})

const showCloudToggle = computed(() => {
  return activeMenu.value === 'cloud-configs-toggle'
})

const showSystemConfig = computed(() => {
  return activeMenu.value.startsWith('sys-')
})

onMounted(async () => {
  try {
    const cfg = await getSiteConfig()
    if (cfg.site_name) {
      siteName.value = cfg.site_name
      document.title = cfg.site_name + ' - 管理后台'
    }
  } catch {}
  try {
    const [configs, ctResult] = await Promise.all([
      getCloudConfigs(),
      getCloudTypes(),
    ])
    cloudTypes.value = ctResult.types
    await loadStats()
    await loadRecentSaves()
    await loadSystemInfo()
    initTrendChart()
  } catch (e) {
    console.error('加载数据失败', e)
  }
})

async function loadStats() {
  try {
    stats.value = await getStats(trendDays.value)
    try { const h = await fetch("/health"); const hv = await h.json(); appVersion.value = hv.version; } catch {}
  } catch (e) {
    console.error('加载统计数据失败', e)
  }
}

function cloudStoragePercent(item: { storageUsed: string; storageTotal: string }): number {
  if (!item.storageUsed || !item.storageTotal) return 0
  const used = parseFloat(item.storageUsed)
  const total = parseFloat(item.storageTotal)
  if (total <= 0) return 0
  return Math.round((used / total) * 100)
}

function handleMenuSelect(index: string) {
  if (index === 'logout') {
    handleLogout()
    return
  }
  activeMenu.value = index

  // For system config sub-items, set which section to scroll to
  if (index.startsWith('sys-')) {
    activeSystemSection.value = index
  }

  // Refresh cloud types when switching to cloud configs
  if (index === 'cloud-configs-toggle') {
    getCloudTypes().then(r => { cloudTypes.value = r.types }).catch(() => {})
  }
}

function handleLogout() {
  localStorage.removeItem('admin_token')
  router.push('/admin/login')
}

function goBackHome() {
  window.location.href = '/'
}

// ── 网盘类型开关 ──

async function handleCloudToggle(type: string, enabled: boolean) {
  const ct = cloudTypes.value.find(c => c.type === type)
  if (!ct) return
  try {
    await toggleCloudType(type, enabled)
    ct.enabled = enabled
  } catch (e: any) {
    ElMessage.error(e.message || '切换失败')
    // Revert optimistic update
    ct.enabled = !enabled
  }
}
</script>

<style scoped>
.section-content { }

/* ── Row 1: 统计卡片 ── */
.dash-row { margin-bottom: 20px; }
.dash-row-stats {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 14px;
}
@media (max-width: 1200px) { .dash-row-stats { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px) { .dash-row-stats { grid-template-columns: repeat(2, 1fr); } }

.stat-card {
  text-align: center;
  background: var(--bg-card) !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-lg) !important;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  cursor: default;
  position: relative;
  overflow: hidden;
}
/* 统计卡片左侧装饰条 — 不同颜色区分 */
.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  border-radius: 14px 0 0 14px;
}
.stat-card:nth-child(1)::before { background: linear-gradient(180deg, #409eff, #79bbff); }
.stat-card:nth-child(2)::before { background: linear-gradient(180deg, #67c23a, #95d475); }
.stat-card:nth-child(3)::before { background: linear-gradient(180deg, #e6a23c, #f3d19e); }
.stat-card:nth-child(4)::before { background: linear-gradient(180deg, #7c3aed, #a78bfa); }
.stat-card:nth-child(5)::before { background: linear-gradient(180deg, #f56c6c, #f89898); }
.stat-card:nth-child(6)::before { background: linear-gradient(180deg, #36cfc9, #6fe0d9); }
.stat-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0,0,0,0.08) !important;
}
.stat-card :deep(.el-card__body) {
  padding: 22px 14px 18px !important;
}
.stat-label {
  font-size: 13px;
  color: var(--text-tertiary);
  font-weight: 500;
  margin-bottom: 8px;
  letter-spacing: 0.5px;
}
.stat-value {
  font-size: 30px;
  font-weight: 800;
  background: linear-gradient(135deg, #409eff, #7c3aed);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  letter-spacing: -1px;
  line-height: 1.2;
}

/* ── Row 2: 三列洞察卡片 ── */
.dash-row-cols-3 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 14px;
}
@media (max-width: 1100px) { .dash-row-cols-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 700px) { .dash-row-cols-3 { grid-template-columns: 1fr; } }

.insight-card {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border) !important;
  transition: box-shadow 0.2s;
}
.insight-card:hover {
  box-shadow: var(--shadow-md) !important;
}
.insight-card :deep(.el-card__body) {
  padding: 0 !important;
}
.insight-card.trend-card :deep(.el-card__body) {
  padding: 8px 6px 0 !important;
  height: 400px;
  overflow: hidden;
}
.insight-card:not(.trend-card) :deep(.el-card__body) {
  padding: 14px 18px !important;
  max-height: 400px;
  overflow-y: auto;
}
.insight-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.trend-day-btns {
  display: flex;
  gap: 4px;
}
.trend-day-btn {
  padding: 2px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg-card);
  font-size: 11px;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: all 0.2s;
  font-family: inherit;
}
.trend-day-btn:hover {
  border-color: var(--primary);
  color: var(--primary);
}
.trend-day-btn.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* ECharts */
.trend-chart-echarts {
  width: 100%;
  height: 100%;
  min-height: 320px;
}

/* Trend summary */
.trend-summary-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 12px 14px 6px;
  border-bottom: 1px solid var(--border-light);
}
.trend-summary-item { text-align: center; }
.trend-summary-num {
  display: block;
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
}
.trend-summary-desc {
  display: block;
  font-size: 11px;
  color: var(--text-tertiary);
  margin-top: 2px;
}

/* Keywords */
.keyword-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-content: flex-start;
}
.keyword-tag { cursor: default; }
.kw-count {
  font-size: 9px;
  margin-left: 2px;
  opacity: 0.7;
  font-weight: 400;
}

/* IP list */
.ip-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ip-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg);
  transition: background 0.2s;
}
.ip-row:hover {
  background: var(--border-light);
}
.ip-rank {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: linear-gradient(135deg, #409eff, #7c3aed);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ip-addr {
  font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ip-loc {
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--primary-soft);
  color: var(--primary);
  white-space: nowrap;
  flex-shrink: 0;
}
.ip-count {
  font-size: 12px;
  color: var(--text-tertiary);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Province */
.province-list {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.province-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.province-row:hover {
  background: var(--border-light);
}
.province-rank {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: linear-gradient(135deg, #409eff, #7c3aed);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.province-bar-wrap {
  flex: 1;
  height: 16px;
  background: var(--border-light);
  border-radius: 8px;
  overflow: hidden;
  min-width: 0;
}
.province-bar {
  display: block;
  height: 100%;
  border-radius: 8px;
  transition: width 0.4s ease;
  min-width: 4px;
}
.province-name {
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  white-space: nowrap;
  width: 90px;
  text-align: right;
  flex-shrink: 0;
}
.province-count {
  font-size: 12px;
  color: var(--text-tertiary);
  white-space: nowrap;
  width: 50px;
  text-align: right;
  flex-shrink: 0;
}

/* ── Storage section ── */
.storage-card {
  border-radius: var(--radius-lg);
  border: 1px solid var(--border) !important;
}
.storage-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
.storage-drive-card {
  flex: 1 1 280px;
  min-width: 260px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
  background: var(--bg-card);
  transition: box-shadow 0.2s, transform 0.2s;
  position: relative;
  overflow: hidden;
}
.storage-drive-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #409eff, #7c3aed);
}
.storage-drive-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.drive-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.drive-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  flex-shrink: 0;
  object-fit: contain;
}
.drive-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.drive-status {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}
.drive-status.active { background: #f0f9eb; color: #67c23a; }
.drive-status.inactive { background: var(--bg); color: var(--text-tertiary); }
.drive-space {
  font-size: 12px;
  margin-bottom: 8px;
  display: flex;
  align-items: baseline;
  gap: 3px;
}
.drive-used { color: var(--text); font-weight: 600; }
.drive-sep { color: var(--border); }
.drive-total { color: var(--text-secondary); font-weight: 500; }

/* ── Cloud toggle ── */
.config-card {
  margin-bottom: 20px;
}
.config-card :deep(.el-card__header) {
  background: var(--bg-card-header);
}
.cloud-toggle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}
.cloud-toggle-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg);
  border: 1px solid var(--border);
  transition: background 0.2s, box-shadow 0.15s;
}
.cloud-toggle-chip:hover {
  background: var(--border-light);
  box-shadow: var(--shadow-sm);
}
.cloud-icon-img {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  flex-shrink: 0;
  object-fit: contain;
}
.cloud-label {
  font-size: 13px;
  font-weight: 500;
  flex: 1;
}
</style>
