<template>
  <div class="overview-container">
    <a-spin :loading="loading" style="width: 100%">
      <div v-if="!loading">
        <!-- 统计卡片 -->
        <a-row :gutter="[20, 20]" class="stat-cards-row">
          <a-col v-for="(card, index) in statCards" :key="index" :xs="12" :sm="12" :md="8" :lg="4.8">
            <div class="stat-card" :style="{ background: getCardBackground(card) }" @click="handleCardClick(card.title)">
              <div class="stat-card-header">
                <div class="stat-title">
                  <span class="stat-name">{{ card.title }}</span>
                  <a-tag v-if="card.title === '警告' || card.title === '工单' || card.title === '审核'" size="small" class="stat-tag">
                    {{ card.title === '警告' ? '告警中/总数' : '待处理/总数' }}
                  </a-tag>
                  <a-tag v-else size="small" class="stat-tag">启用/总数</a-tag>
                </div>
                <div class="stat-icon" :style="{ background: getIconBackground(card) }">
                  <component :is="getIconComponent(card.title)" :style="{ fontSize: '24px', color: getIconColor(card) }" />
                </div>
              </div>
              <div class="stat-value">
                <span class="stat-number" :class="{ 'animate-number': numberAnimated[index] }">
                  {{ animatedNumbers[index] || card.pending }}
                </span>
                <span class="stat-divider">/</span>
                <span class="stat-total">{{ card.total || '-' }}</span>
              </div>
            </div>
          </a-col>
        </a-row>

        <!-- 图表和列表区域 -->
        <a-row :gutter="[20, 20]" class="content-row">
          <!-- 告警趋势 -->
          <a-col :xs="24" :lg="16">
            <div class="chart-card">
              <div class="card-header">
                <div class="header-title">
                  <div class="title-icon">
                    <icon-bar-chart :style="{ fontSize: '20px', color: 'rgb(var(--primary-6))' }" />
                  </div>
                  <span class="title-text">告警趋势</span>
                </div>
                <a-select style="width: 160px" v-model="month" size="small" class="month-select" @change="handleChange">
                  <a-option v-for="item in monthOptions" :key="item.value" :value="item.value">
                    {{ item.label }}
                  </a-option>
                </a-select>
              </div>
              <div class="chart-container">
                <div v-if="!chartLoading && isTrendEmpty" class="chart-empty">
                  <a-empty>
                    <template #description>
                      <span>当前月份暂无告警趋势数据</span>
                    </template>
                  </a-empty>
                </div>
                <v-chart v-else-if="!chartLoading" :option="alertChartOption" class="chart" autoresize />
                <div v-else class="chart-loading">
                  <a-spin size="large" />
                  <div class="loading-text">加载图表数据...</div>
                </div>
              </div>
            </div>
          </a-col>

          <!-- 待处理警告 -->
          <a-col :xs="24" :lg="8">
            <div class="alert-card">
              <div class="card-header">
                <div class="header-title">
                  <div class="title-icon warning">
                    <icon-info-circle :style="{ fontSize: '20px' }" />
                  </div>
                  <span class="title-text">待处理警告</span>
                </div>
                <a-badge :count="pendingAlerts.length" :max-count="99" class="alert-badge" />
              </div>
              <div class="alert-content">
                <a-empty v-if="pendingAlerts.length === 0" class="empty-state">
                  <template #description>
                    <div class="empty-text">暂无待处理告警</div>
                  </template>
                </a-empty>
                <div v-else class="alert-list">
                  <div v-for="alert in pendingAlerts" :key="alert.id" class="alert-item" @click="handleViewDetail(alert.id)">
                    <div class="alert-avatar">
                      <a-avatar :style="{ backgroundColor: getStatusColor(alert.status) }">
                        {{ getAlertTitle(alert.title)?.charAt(0)?.toUpperCase() || 'A' }}
                      </a-avatar>
                    </div>
                    <div class="alert-info">
                      <div class="alert-title">{{ getAlertTitle(alert.alert_name) || '告警信息' }}</div>
                      <div class="alert-description">{{ getAlertDescription(alert.description) || '-' }}</div>
                      <div class="alert-meta">
                        <a-tag :color="getStatusTagColor(alert.status)" size="small">
                          {{ getStatusText(alert.status) }}
                        </a-tag>
                        <span class="alert-time">{{ alert.created_at ? formatDate(alert.created_at) : '-' }}</span>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="card-footer">
                <a-button type="primary" long @click="handleViewMore">
                  查看更多警告
                  <template #icon>
                    <icon-right />
                  </template>
                </a-button>
              </div>
            </div>
          </a-col>
        </a-row>
      </div>
    </a-spin>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { Message } from '@arco-design/web-vue'
import {
  IconDesktop,
  IconCloud,
  IconWifi,
  IconExclamationCircle,
  IconFile,
  IconCheckCircle,
  IconBarChart,
  IconInfoCircle,
  IconRight,
} from '@arco-design/web-vue/es/icon'
import VChart from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent, GridComponent } from 'echarts/components'
import dayjs from 'dayjs'
import { fetchAlertCount, fetchAlertTrend, fetchHistories } from '@/api/ops/alertHistory'
import { fetchCollectorStatistics } from '@/api/ops/dcControl'
import { fetchFeedbackTicketStatistics } from '@/api/ops/feedbackTicket'
import { fetchNetworkDeviceList } from '@/api/ops/network-device'
import { fetchReviewStats } from '@/api/kb/review'

// 注册必要的 ECharts 组件
use([CanvasRenderer, BarChart, TitleComponent, TooltipComponent, GridComponent])

const router = useRouter()
const getCurrentMonthValue = () => dayjs().format('YYYY-MM')

const formatMonthLabel = (value: string) => dayjs(`${value}-01`).format('YYYY年M月')

const monthOptions = computed(() => {
  return Array.from({ length: 6 }, (_, index) => {
    const value = dayjs().subtract(index, 'month').format('YYYY-MM')
    return {
      label: formatMonthLabel(value),
      value,
    }
  })
})

const getMonthRange = (value: string) => {
  const start = dayjs(`${value}-01`).startOf('month')
  const end = start.endOf('month')
  return {
    start,
    end,
    startTime: start.toISOString(),
    endTime: end.toISOString(),
  }
}

const buildMonthDays = (value: string) => {
  const { start, end } = getMonthRange(value)
  const days: string[] = []
  let cursor = start
  while (cursor.isBefore(end) || cursor.isSame(end, 'day')) {
    days.push(cursor.format('YYYY-MM-DD'))
    cursor = cursor.add(1, 'day')
  }
  return days
}

const month = ref(getCurrentMonthValue())
const loading = ref(true)
const chartLoading = ref(false)
const numberAnimated = ref([false, false, false, false, false, false])
const animatedNumbers = ref([0, 0, 0, 0, 0, 0])

// 统计数据
const statistics = reactive({
  serverPc: { pending: 0, total: 0 },
  database: { pending: 0, total: 0 },
  network: { pending: 0, total: 0 },
  alert: { pending: 0, total: 0 },
  ticket: { pending: 0, total: 0 },
  review: { pending: 0, total: 0 },
})

const pendingAlerts = ref<any[]>([])
const trendDates = ref<string[]>([])
const trendCounts = ref<number[]>([])
const isTrendEmpty = computed(() => trendCounts.value.length > 0 && trendCounts.value.every((count) => count === 0))

const unwrapDetails = (payload: any) => payload?.details ?? payload?.data ?? payload ?? {}

const normalizeCountPair = (source: any) => ({
  pending: Number(source?.collect_enabled ?? source?.enabled ?? 0) || 0,
  total: Number(source?.total ?? 0) || 0,
})

const getPageTotal = (payload: any) => {
  const body = unwrapDetails(payload)
  return Number(body?.total ?? payload?.total ?? 0) || 0
}

const isFailedRequest = (value: unknown): value is { error: unknown; success: false } =>
  Boolean(value && typeof value === 'object' && 'success' in value && value.success === false)

// 统计卡片数据
const statCards = computed(() => [
  {
    title: '服务器及PC',
    pending: statistics.serverPc.pending,
    total: statistics.serverPc.total,
    lightColor: 'rgba(64, 169, 255, 0.1)',
    darkColor: 'rgba(64, 169, 255, 0.15)',
    iconColor: '#409EFF',
  },
  {
    title: '数据库服务',
    pending: statistics.database.pending,
    total: statistics.database.total,
    lightColor: 'rgba(255, 153, 0, 0.1)',
    darkColor: 'rgba(255, 153, 0, 0.15)',
    iconColor: '#FF9900',
  },
  {
    title: '网络设备',
    pending: statistics.network.pending,
    total: statistics.network.total,
    lightColor: 'rgba(82, 196, 26, 0.1)',
    darkColor: 'rgba(82, 196, 26, 0.15)',
    iconColor: '#52C41A',
  },
  {
    title: '警告',
    pending: statistics.alert.pending,
    total: statistics.alert.total,
    lightColor: 'rgba(255, 77, 79, 0.1)',
    darkColor: 'rgba(255, 77, 79, 0.15)',
    iconColor: '#FF4D4F',
  },
  {
    title: '工单',
    pending: statistics.ticket.pending,
    total: statistics.ticket.total,
    lightColor: 'rgba(114, 46, 209, 0.1)',
    darkColor: 'rgba(114, 46, 209, 0.15)',
    iconColor: '#722ED1',
  },
  {
    title: '审核',
    pending: statistics.review.pending,
    total: statistics.review.total,
    lightColor: 'rgba(19, 194, 194, 0.1)',
    darkColor: 'rgba(19, 194, 194, 0.15)',
    iconColor: '#13C2C2',
  },
])

// 告警图表配置
const alertChartOption = computed(() => ({
  tooltip: {
    trigger: 'axis',
    backgroundColor: 'rgba(17, 24, 39, 0.9)',
    borderColor: 'rgba(99, 102, 241, 0.3)',
    borderWidth: 1,
    borderRadius: 8,
    padding: [12, 16],
    textStyle: {
      color: '#fff',
      fontSize: 14,
      fontWeight: 500,
    },
    axisPointer: {
      type: 'shadow',
      shadowStyle: {
        color: 'rgba(99, 102, 241, 0.15)',
        shadowBlur: 20,
      },
    },
    formatter: (params: any) => {
      if (!params || !params.length) return ''
      const data = params[0]
      const date = data.axisValue
      const value = data.value
      const maxValue = Math.max(...trendCounts.value, 0)
      const percent = maxValue > 0 ? ((value / maxValue) * 100).toFixed(1) : '0.0'
      return `
        <div style="margin-bottom: 4px; font-size: 12px; color: rgba(255, 255, 255, 0.7);">${date}</div>
        <div style="display: flex; align-items: center; gap: 8px;">
          <span style="display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: linear-gradient(180deg, #6366F1 0%, #8B5CF6 100%);"></span>
          <span style="font-weight: 600;">${data.seriesName}：</span>
          <span style="color: #6366F1; font-weight: 700;">${value}</span>
          <span style="font-size: 12px; color: rgba(255, 255, 255, 0.6); margin-left: 4px;">(${percent}%)</span>
        </div>
      `
    },
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '10%',
    top: '12%',
    containLabel: true,
  },
  xAxis: {
    type: 'category',
    data: trendDates.value,
    axisLine: {
      show: false,
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      color: 'rgba(0, 0, 0, 0.65)',
      fontSize: 13,
      fontWeight: 500,
      fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
    },
    axisPointer: {
      type: 'shadow',
      shadowStyle: {
        color: 'rgba(99, 102, 241, 0.1)',
        shadowBlur: 10,
      },
    },
  },
  yAxis: {
    type: 'value',
    min: 0,
    max: (value: { max: number }) => Math.max(5, Math.ceil(value.max * 1.2)),
    splitNumber: 5,
    splitLine: {
      lineStyle: {
        type: 'dashed',
        color: 'rgba(0, 0, 0, 0.06)',
        width: 1,
        cap: 'round',
      },
    },
    axisLabel: {
      color: 'rgba(0, 0, 0, 0.65)',
      fontSize: 13,
      fontWeight: 500,
      fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
      formatter: (value: number) => {
        return value
      },
    },
    axisLine: {
      show: false,
    },
    axisTick: {
      show: false,
    },
  },
  series: [
    {
      name: '告警数量',
      type: 'bar',
      data: trendCounts.value,
      barWidth: '50%',
      itemStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [
            { offset: 0, color: '#818CF8' },
            { offset: 0.3, color: '#6366F1' },
            { offset: 1, color: '#8B5CF6' },
          ],
        },
        borderRadius: [12, 12, 0, 0],
        shadowBlur: 20,
        shadowColor: 'rgba(99, 102, 241, 0.4)',
        shadowOffsetY: 8,
      },
      emphasis: {
        itemStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: '#A5B4FC' },
              { offset: 0.3, color: '#7C3AED' },
              { offset: 1, color: '#9333EA' },
            ],
          },
          shadowBlur: 30,
          shadowColor: 'rgba(124, 58, 237, 0.5)',
          shadowOffsetY: 12,
        },
        scale: true,
        scaleSize: 5,
      },
      label: {
        show: true,
        position: 'top',
        fontSize: 13,
        fontWeight: 600,
        color: '#6366F1',
        offset: 2,
        formatter: (params: any) => {
          return params.value
        },
      },
      animationDuration: 1200,
      animationEasing: 'cubicOut',
      animationDelay: (idx: number) => idx * 50,
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(99, 102, 241, 0.05)',
        borderRadius: [12, 12, 0, 0],
      },
    },
  ],
}))

// 获取卡片背景
const getCardBackground = (card: any) => {
  return document.documentElement.getAttribute('arco-theme') === 'dark' ? card.darkColor : card.lightColor
}

// 获取图标背景
const getIconBackground = (card: any) => {
  return document.documentElement.getAttribute('arco-theme') === 'dark' ? 'rgba(255, 255, 255, 0.1)' : card.iconColor + '1A'
}

// 获取图标颜色
const getIconColor = (card: any) => {
  return card.iconColor
}

// 获取图标组件
const getIconComponent = (title: string) => {
  const iconMap: any = {
    服务器及PC: IconDesktop,
    数据库服务: IconCloud,
    网络设备: IconWifi,
    警告: IconExclamationCircle,
    工单: IconFile,
    审核: IconCheckCircle,
  }
  return iconMap[title] || IconDesktop
}

const normalizeTrendItems = (payload: any) => {
  const body = unwrapDetails(payload)
  return Array.isArray(body?.data) ? body.data : []
}

const loadAlertTrend = async (monthValue: string) => {
  chartLoading.value = true
  const days = buildMonthDays(monthValue)
  try {
    const { startTime, endTime } = getMonthRange(monthValue)
    const response = await fetchAlertTrend({
      granularity: 'day',
      start_time: startTime,
      end_time: endTime,
    })
    const countMap = new Map<string, number>()
    normalizeTrendItems(response).forEach((item: any) => {
      countMap.set(String(item.date), Number(item.count) || 0)
    })
    trendDates.value = days.map((day) => dayjs(day).format('MM/DD'))
    trendCounts.value = days.map((day) => countMap.get(day) || 0)
  } catch (error) {
    console.warn('告警趋势数据加载失败:', error)
    trendDates.value = days.map((day) => dayjs(day).format('MM/DD'))
    trendCounts.value = days.map(() => 0)
  } finally {
    chartLoading.value = false
  }
}

// 处理月份选择变更
const handleChange = (value: string) => {
  month.value = value
  loadAlertTrend(value)
}

// 处理统计卡片点击
const handleCardClick = (cardTitle: string) => {
  const routeMap: any = {
    服务器及PC: '/dc/server',
    数据库服务: '/dc/database',
    网络设备: '/monitor/network',
    警告: '/alert/tackle',
    工单: '/feedback/all',
    审核: '/kb/review',
  }
  const route = routeMap[cardTitle]
  if (route) {
    router.push(route)
  } else {
    Message.info('该功能正在开发中')
  }
}

// 数字动画效果
const animateNumber = (index: number, targetValue: number) => {
  const duration = 1000 // 动画持续时间（毫秒）
  const startValue = 0
  const startTime = performance.now()

  const animate = (currentTime: number) => {
    const elapsed = currentTime - startTime
    const progress = Math.min(elapsed / duration, 1)

    // 使用缓动函数 easeOutQuart
    const easeOut = 1 - Math.pow(1 - progress, 4)
    const currentValue = Math.floor(startValue + (targetValue - startValue) * easeOut)

    animatedNumbers.value[index] = currentValue

    if (progress < 1) {
      requestAnimationFrame(animate)
    } else {
      animatedNumbers.value[index] = targetValue
      numberAnimated.value[index] = true
    }
  }

  requestAnimationFrame(animate)
}

// 加载统计数据和待处理告警列表
const loadStatistics = async () => {
  try {
    loading.value = true

    // 并行请求所有统计接口和待处理告警
    const [alertData, collectorData, ticketData, alertListData, reviewStatsData, networkTotalData, networkEnabledData] =
      await Promise.allSettled([
        fetchAlertCount().catch((e) => ({ error: e, success: false })),
        fetchCollectorStatistics().catch((e) => ({ error: e, success: false })),
        fetchFeedbackTicketStatistics().catch((e) => ({ error: e, success: false })),
        fetchHistories({ page: 1, page_size: 5, status: 'firing' }).catch((e) => ({ error: e, success: false })),
        fetchReviewStats({ resource_type: 'all' }).catch((e: unknown) => ({ error: e, success: false as const })),
        fetchNetworkDeviceList({ page: 1, size: 1 }).catch((e) => ({ error: e, success: false })),
        fetchNetworkDeviceList({ page: 1, size: 1, enabled: true }).catch((e) => ({ error: e, success: false })),
      ])

    // 处理服务器及PC统计数据
    if (collectorData.status === 'fulfilled' && !isFailedRequest(collectorData.value)) {
      const resourceStats = unwrapDetails(collectorData.value)
      statistics.serverPc = normalizeCountPair(resourceStats.servers)
      statistics.database = normalizeCountPair(resourceStats.database_services)
    } else {
      console.warn('资源统计数据加载失败:', collectorData.status === 'rejected' ? collectorData.reason : collectorData.value?.error)
    }

    if (
      networkTotalData.status === 'fulfilled' &&
      !isFailedRequest(networkTotalData.value) &&
      networkEnabledData.status === 'fulfilled' &&
      !isFailedRequest(networkEnabledData.value)
    ) {
      statistics.network = {
        pending: getPageTotal(networkEnabledData.value),
        total: getPageTotal(networkTotalData.value),
      }
    } else {
      console.warn('网络设备统计数据加载失败')
    }

    // 处理告警统计数据
    if (alertData.status === 'fulfilled' && !isFailedRequest(alertData.value)) {
      statistics.alert = {
        pending: alertData.value?.details?.status_counts?.firing || 0,
        total: alertData.value?.details?.total || 0,
      }
    } else {
      console.warn('告警统计数据加载失败:', alertData.status === 'rejected' ? alertData.reason : alertData.value?.error)
    }

    // 处理工单统计数据
    if (ticketData.status === 'fulfilled' && !isFailedRequest(ticketData.value)) {
      statistics.ticket = {
        pending: ticketData.value?.details?.pending || ticketData.value?.pending || 0,
        total: ticketData.value?.details?.total || ticketData.value?.total || 0,
      }
    } else {
      console.warn('工单统计数据加载失败:', ticketData.status === 'rejected' ? ticketData.reason : ticketData.value?.error)
    }

    // 审核统计数据（待处理=尚未审核，总数=需本人审核）
    if (reviewStatsData.status === 'fulfilled' && !isFailedRequest(reviewStatsData.value)) {
      const reviewPayload = reviewStatsData.value.details
      statistics.review = {
        pending: Number(reviewPayload.need_my_review_unreviewed_total) || 0,
        total: Number(reviewPayload.need_my_review_total) || 0,
      }
    } else {
      const reason =
        reviewStatsData.status === 'rejected'
          ? reviewStatsData.reason
          : isFailedRequest(reviewStatsData.value)
            ? reviewStatsData.value.error
            : undefined
      console.warn('审核统计数据加载失败:', reason)
    }

    // 设置待处理告警列表
    if (alertListData.status === 'fulfilled' && !isFailedRequest(alertListData.value)) {
      pendingAlerts.value = alertListData.value?.details?.data || []
    } else {
      console.warn('待处理告警列表加载失败:', alertListData.status === 'rejected' ? alertListData.reason : alertListData.value?.error)
      pendingAlerts.value = []
    }

    // 启动数字动画
    const values = [
      statistics.serverPc.pending,
      statistics.database.pending,
      statistics.network.pending,
      statistics.alert.pending,
      statistics.ticket.pending,
      statistics.review.pending,
    ]
    values.forEach((value, index) => {
      animateNumber(index, value)
    })
  } catch (error: any) {
    console.error('加载统计数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 处理查看详情 - 打开新窗口
const handleViewDetail = (alertId: number) => {
  window.open(`/#/alert/detail?id=${alertId}`, '_blank')
}

// 查看更多警告
const handleViewMore = () => {
  router.push('/alert/tackle')
}

// 获取告警状态对应的颜色
const getStatusColor = (status: any) => {
  const statusStr = typeof status === 'object' ? status?.code || status?.name : status
  const colorMap: any = {
    pending: '#FF4D4F',
    firing: '#FF4D4F',
    processing: '#1890FF',
    resolved: '#52C41A',
    closed: '#8C8C8C',
  }
  return colorMap[statusStr] || '#FF4D4F'
}

// 获取告警状态对应的标签颜色
const getStatusTagColor = (status: any) => {
  const statusStr = typeof status === 'object' ? status?.code || status?.name : status
  const colorMap: any = {
    pending: 'red',
    firing: 'red',
    processing: 'blue',
    resolved: 'green',
    closed: 'gray',
  }
  return colorMap[statusStr] || 'red'
}

// 获取状态文本
const getStatusText = (status: any) => {
  if (typeof status === 'object') {
    return status?.name || status?.code || '-'
  }
  const statusMap: any = {
    pending: '待处理',
    firing: '告警中',
    processing: '处理中',
    resolved: '已解决',
    closed: '已关闭',
  }
  return statusMap[status] || status || '-'
}

// 获取告警标题
const getAlertTitle = (title: any) => {
  if (typeof title === 'object') {
    return title?.name || '-'
  }
  return title || '-'
}

// 获取告警描述
const getAlertDescription = (description: any) => {
  if (typeof description === 'object') {
    return JSON.stringify(description)
  }
  return description || '-'
}

// 格式化日期
const formatDate = (date: string) => {
  return dayjs(date).format('MM/DD HH:mm')
}

onMounted(() => {
  loadStatistics()
  loadAlertTrend(month.value)
})
</script>

<style scoped lang="less">
.overview-container {
  padding: 20px;
  min-height: 100%;
  background: var(--color-bg-2);
}

// 统计卡片样式
.stat-cards-row {
  margin-bottom: 20px;
}

.stat-card {
  border-radius: 16px;
  padding: 24px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  position: relative;
  overflow: hidden;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
    opacity: 0;
    transition: opacity 0.3s ease;
  }

  &:hover {
    transform: translateY(-6px);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);

    &::before {
      opacity: 1;
    }

    .stat-icon {
      transform: scale(1.1) rotate(5deg);
    }
  }

  &:active {
    transform: translateY(-2px);
  }
}

.stat-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
}

.stat-title {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text-1);
  letter-spacing: 0.3px;
}

.stat-tag {
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.06);
  color: var(--color-text-2);
  width: fit-content;
  font-weight: 500;
  letter-spacing: 0.2px;
}

.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.stat-value {
  display: flex;
  align-items: baseline;
  gap: 4px;
}

.stat-number {
  font-size: 32px;
  font-weight: 700;
  color: var(--color-text-1);
  line-height: 1;
  transition: all 0.3s ease;

  &.animate-number {
    animation: numberPop 0.3s ease-out;
  }
}

@keyframes numberPop {
  0% {
    transform: scale(1.2);
    opacity: 0.8;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

.stat-divider {
  font-size: 20px;
  color: var(--color-text-3);
  margin: 0 4px;
  font-weight: 300;
}

.stat-total {
  font-size: 18px;
  color: var(--color-text-3);
  font-weight: 500;
}

// 内容区域样式
.content-row {
  margin-top: 20px;
}

.chart-card,
.alert-card {
  background: var(--color-bg-1);
  border-radius: 16px;
  border: 1px solid var(--color-border);
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

  &:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    transform: translateY(-2px);
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  border-bottom: 1px solid var(--color-border);
  background: linear-gradient(180deg, var(--color-bg-1) 0%, rgba(var(--primary-1), 0.05) 100%);
}

.header-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(64, 169, 255, 0.12);
  box-shadow: 0 2px 8px rgba(64, 169, 255, 0.2);

  &.warning {
    background: rgba(255, 77, 79, 0.12);
    color: rgb(var(--danger-6));
    box-shadow: 0 2px 8px rgba(255, 77, 79, 0.2);
  }
}

.title-text {
  font-size: 17px;
  font-weight: 600;
  color: var(--color-text-1);
  letter-spacing: 0.3px;
}

.month-select {
  width: 130px;
  border-radius: 8px;
}

.alert-badge {
  :deep(.arco-badge-count) {
    background: rgb(var(--danger-6));
    box-shadow: 0 2px 8px rgba(var(--danger-6), 0.3);
  }
}

// 图表容器
.chart-container {
  padding: 24px;
  height: 400px;
  position: relative;
}

.chart {
  width: 100%;
  height: 100%;
}

.chart-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 16px;
}

.chart-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.loading-text {
  color: var(--color-text-3);
  font-size: 14px;
}

// 告警内容区域
.alert-content {
  height: 370px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.empty-text {
  color: var(--color-text-3);
  font-size: 15px;
  font-weight: 500;
}

.alert-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 24px;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: var(--color-fill-3);
    border-radius: 3px;
    transition: background 0.2s ease;

    &:hover {
      background: var(--color-fill-4);
    }
  }

  &::-webkit-scrollbar-track {
    background: transparent;
  }
}

.alert-item {
  display: flex;
  gap: 14px;
  padding: 18px 0;
  border-bottom: 1px solid var(--color-border-2);
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  border-radius: 8px;

  &:hover {
    background: linear-gradient(90deg, var(--color-fill-1), rgba(var(--primary-1), 0.1));
    margin: 0 -24px;
    padding: 18px 24px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  }

  &:last-child {
    border-bottom: none;
  }
}

.alert-avatar {
  flex-shrink: 0;
}

.alert-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.alert-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: 0.2px;
}

.alert-description {
  font-size: 13px;
  color: var(--color-text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
}

.alert-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
}

.alert-time {
  color: var(--color-text-3);
  margin-left: auto;
  font-weight: 500;
}

// 卡片底部
.card-footer {
  padding: 18px 24px;
  border-top: 1px solid var(--color-border);
  background: linear-gradient(180deg, transparent, rgba(var(--primary-1), 0.05));
}

// 暗色主题适配
.arco-theme-dark {
  .stat-card {
    &:hover {
      box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
    }
  }

  .stat-name {
    color: rgb(255, 255, 255);
  }

  .stat-number {
    color: rgb(255, 255, 255);
  }

  .stat-tag {
    background: rgba(255, 255, 255, 0.1);
    color: rgba(255, 255, 255, 0.75);
  }

  .stat-icon {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  }

  .chart-card,
  .alert-card {
    &:hover {
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    }
  }

  .title-text {
    color: rgb(255, 255, 255);
  }

  .alert-item {
    &:hover {
      background: linear-gradient(90deg, rgba(255, 255, 255, 0.05), rgba(var(--primary-1), 0.15));
    }
  }
}

// 响应式优化
@media (max-width: 1440px) {
  .stat-cards-row {
    :deep(.arco-col) {
      margin-bottom: 16px;
    }
  }

  .stat-card {
    padding: 20px;
  }

  .stat-number {
    font-size: 30px;
  }
}

@media (max-width: 1200px) {
  .overview-container {
    padding: 18px;
  }

  .stat-card {
    padding: 20px;
  }

  .stat-number {
    font-size: 28px;
  }

  .chart-container {
    height: 380px;
  }

  .alert-content {
    height: 340px;
  }
}

@media (max-width: 992px) {
  .overview-container {
    padding: 16px;
  }

  .stat-card {
    padding: 18px;
  }

  .stat-icon {
    width: 42px;
    height: 42px;
  }

  .stat-number {
    font-size: 26px;
  }

  .stat-name {
    font-size: 14px;
  }

  .stat-tag {
    font-size: 10px;
    padding: 2px 8px;
  }

  .chart-container {
    height: 360px;
    padding: 20px;
  }

  .alert-content {
    height: 320px;
  }

  .card-header {
    padding: 16px 20px;
  }

  .title-text {
    font-size: 16px;
  }

  .month-select {
    width: 120px;
  }
}

@media (max-width: 768px) {
  .overview-container {
    padding: 14px;
  }

  .stat-cards-row {
    margin-bottom: 16px;
  }

  .stat-card {
    padding: 16px;
    border-radius: 12px;

    &:hover {
      transform: translateY(-4px);
    }
  }

  .stat-card-header {
    margin-bottom: 12px;
  }

  .stat-icon {
    width: 40px;
    height: 40px;
  }

  .stat-name {
    font-size: 13px;
  }

  .stat-tag {
    font-size: 10px;
    padding: 2px 6px;
  }

  .stat-number {
    font-size: 24px;
  }

  .stat-total {
    font-size: 16px;
  }

  .stat-divider {
    font-size: 18px;
    margin: 0 3px;
  }

  .content-row {
    margin-top: 16px;
  }

  .chart-card,
  .alert-card {
    border-radius: 12px;
  }

  .chart-container {
    height: 320px;
    padding: 16px;
  }

  .alert-content {
    height: 300px;
  }

  .card-header {
    padding: 14px 16px;
  }

  .title-icon {
    width: 32px;
    height: 32px;
  }

  .title-text {
    font-size: 15px;
  }

  .month-select {
    width: 110px;
    font-size: 12px;
  }

  .alert-list {
    padding: 0 16px;
  }

  .alert-item {
    padding: 14px 0;

    &:hover {
      margin: 0 -16px;
      padding: 14px 16px;
    }
  }

  .alert-avatar {
    :deep(.arco-avatar) {
      width: 32px !important;
      height: 32px !important;
      font-size: 12px !important;
    }
  }

  .alert-title {
    font-size: 14px;
  }

  .alert-description {
    font-size: 12px;
  }

  .alert-time {
    font-size: 11px;
  }

  .card-footer {
    padding: 14px 16px;
  }

  .card-footer {
    :deep(.arco-btn) {
      font-size: 13px;
      padding: 0 16px;
      height: 32px;
    }
  }
}

@media (max-width: 576px) {
  .overview-container {
    padding: 12px;
  }

  .stat-card {
    padding: 14px;
    border-radius: 10px;
  }

  .stat-card-header {
    margin-bottom: 10px;
  }

  .stat-icon {
    width: 36px;
    height: 36px;
  }

  .stat-name {
    font-size: 12px;
  }

  .stat-tag {
    font-size: 9px;
    padding: 1px 5px;
    border-radius: 4px;
  }

  .stat-number {
    font-size: 22px;
  }

  .stat-total {
    font-size: 15px;
  }

  .stat-divider {
    font-size: 16px;
  }

  .chart-card,
  .alert-card {
    border-radius: 10px;
  }

  .chart-container {
    height: 280px;
    padding: 12px;
  }

  .alert-content {
    height: 260px;
  }

  .card-header {
    padding: 12px 14px;
  }

  .title-icon {
    width: 30px;
    height: 30px;
  }

  .title-text {
    font-size: 14px;
  }

  .month-select {
    width: 100px;
    font-size: 11px;
  }

  .alert-list {
    padding: 0 14px;
  }

  .alert-item {
    padding: 12px 0;

    &:hover {
      margin: 0 -14px;
      padding: 12px 14px;
    }
  }

  .alert-avatar {
    :deep(.arco-avatar) {
      width: 30px !important;
      height: 30px !important;
      font-size: 11px !important;
    }
  }

  .alert-title {
    font-size: 13px;
  }

  .alert-description {
    font-size: 11px;
  }

  .alert-meta {
    font-size: 11px;
  }

  .alert-time {
    font-size: 10px;
  }

  .card-footer {
    padding: 12px 14px;
  }

  .card-footer {
    :deep(.arco-btn) {
      font-size: 12px;
      padding: 0 14px;
      height: 30px;
    }
  }
}

@media (max-width: 480px) {
  .overview-container {
    padding: 10px;
  }

  .stat-cards-row {
    :deep(.arco-col) {
      margin-bottom: 12px;
    }
  }

  .stat-card {
    padding: 12px;
  }

  .stat-card-header {
    margin-bottom: 8px;
  }

  .stat-icon {
    width: 32px;
    height: 32px;

    :deep(.arco-icon) {
      font-size: 18px !important;
    }
  }

  .stat-name {
    font-size: 11px;
    letter-spacing: 0.2px;
  }

  .stat-tag {
    font-size: 8px;
    padding: 1px 4px;
  }

  .stat-number {
    font-size: 20px;
  }

  .stat-total {
    font-size: 14px;
  }

  .stat-divider {
    font-size: 15px;
  }

  .chart-container {
    height: 250px;
    padding: 10px;
  }

  .alert-content {
    height: 240px;
  }

  .card-header {
    padding: 10px 12px;
  }

  .title-icon {
    width: 28px;
    height: 28px;

    :deep(.arco-icon) {
      font-size: 16px !important;
    }
  }

  .title-text {
    font-size: 13px;
  }

  .month-select {
    width: 90px;
    font-size: 10px;
  }

  .alert-list {
    padding: 0 12px;
  }

  .alert-item {
    padding: 10px 0;
    gap: 10px;

    &:hover {
      margin: 0 -12px;
      padding: 10px 12px;
    }
  }

  .alert-avatar {
    :deep(.arco-avatar) {
      width: 28px !important;
      height: 28px !important;
      font-size: 10px !important;
    }
  }

  .alert-title {
    font-size: 12px;
  }

  .alert-description {
    font-size: 10px;
  }

  .alert-meta {
    font-size: 10px;
    gap: 6px;

    :deep(.arco-tag) {
      font-size: 9px;
      padding: 0 4px;
      height: 18px;
      line-height: 16px;
    }
  }

  .alert-time {
    font-size: 9px;
  }

  .card-footer {
    padding: 10px 12px;
  }

  .card-footer {
    :deep(.arco-btn) {
      font-size: 11px;
      padding: 0 12px;
      height: 28px;
    }
  }

  .empty-text {
    font-size: 13px;
  }
}

@media (max-width: 375px) {
  .stat-card {
    padding: 10px;
  }

  .stat-number {
    font-size: 18px;
  }

  .stat-name {
    font-size: 10px;
  }

  .chart-container {
    height: 220px;
    padding: 8px;
  }

  .alert-content {
    height: 220px;
  }

  .title-text {
    font-size: 12px;
  }

  .month-select {
    width: 80px;
  }
}

// 横屏模式优化
@media (max-height: 600px) and (orientation: landscape) {
  .chart-container {
    height: 280px;
  }

  .alert-content {
    height: 260px;
  }

  .stat-card {
    padding: 14px 20px;
  }
}

// 触摸设备优化
@media (hover: none) and (pointer: coarse) {
  .stat-card,
  .chart-card,
  .alert-card {
    &:active {
      transform: scale(0.98);
      opacity: 0.9;
    }
  }

  .stat-card {
    &:hover {
      transform: none;
    }
  }

  .alert-item {
    &:hover {
      background: none;
      margin: 0;
      padding: 18px 0;
    }

    &:active {
      background: linear-gradient(90deg, var(--color-fill-1), rgba(var(--primary-1), 0.1));
      margin: 0 -24px;
      padding: 18px 24px;
    }
  }
}

// 打印样式优化
@media print {
  .overview-container {
    padding: 0;
  }

  .stat-card,
  .chart-card,
  .alert-card {
    box-shadow: none;
    border: 1px solid #ddd;
    page-break-inside: avoid;
  }

  .chart-container {
    height: 300px;
  }

  .alert-content {
    height: auto;
    max-height: 400px;
  }
}
</style>
