<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { statisticsApi, targetApi, notificationApi } from '@/api/service-monitor'
import * as echarts from 'echarts'
import type { Target, OverviewStats, ItemKeysModule, HealthTrendData } from '@/types/service-monitor'

// Filters
const targets = ref<Target[]>([])
const filterTargetId = ref('')
const filterStartDate = ref('')
const filterEndDate = ref('')
const loading = ref(false)

// Missing report alert
const missingTargets = ref<Array<{ target_name: string; target_id: string; last_report_at: string | null; missing_days: number }>>([])

// Overview data
const overview = ref<OverviewStats | null>(null)
const healthTrendData = ref<HealthTrendData | null>(null)

// Item selector
const cachedModulesData = ref<ItemKeysModule[]>([])
const selectedModuleId = ref('')
const selectedModuleItems = ref<{ key: string; name: string; has_numeric: boolean }[]>([])
const selectedItemKey = ref('')

// Charts
let chartModules: echarts.ECharts | null = null
let chartHealthTrend: echarts.ECharts | null = null
let chartTrendLine: echarts.ECharts | null = null
let chartTrendPie: echarts.ECharts | null = null
let chartAbnormal: echarts.ECharts | null = null

// Colors
const COLORS = {
  normal: '#16a34a',
  warning: '#d97706',
  critical: '#dc2626',
  primary: '#2563eb'
}

// Init dates (last 30 days)
function initDates() {
  const today = new Date()
  const start = new Date(today)
  start.setDate(start.getDate() - 30)
  filterEndDate.value = today.toISOString().slice(0, 10)
  filterStartDate.value = start.toISOString().slice(0, 10)
}

// Init charts
function initCharts() {
  const chartModulesEl = document.getElementById('chartModules')
  const chartHealthTrendEl = document.getElementById('chartHealthTrend')
  const chartTrendLineEl = document.getElementById('chartTrendLine')
  const chartTrendPieEl = document.getElementById('chartTrendPie')
  const chartAbnormalEl = document.getElementById('chartAbnormal')

  if (chartModulesEl) chartModules = echarts.init(chartModulesEl)
  if (chartHealthTrendEl) chartHealthTrend = echarts.init(chartHealthTrendEl)
  if (chartTrendLineEl) chartTrendLine = echarts.init(chartTrendLineEl)
  if (chartTrendPieEl) chartTrendPie = echarts.init(chartTrendPieEl)
  if (chartAbnormalEl) chartAbnormal = echarts.init(chartAbnormalEl)

  window.addEventListener('resize', handleResize)
}

function handleResize() {
  chartModules?.resize()
  chartHealthTrend?.resize()
  chartTrendLine?.resize()
  chartTrendPie?.resize()
  chartAbnormal?.resize()
}

function getParams() {
  const params: Record<string, string> = {}
  if (filterTargetId.value) params.target_id = filterTargetId.value
  if (filterStartDate.value) params.start_date = filterStartDate.value
  if (filterEndDate.value) params.end_date = filterEndDate.value
  return params
}

// Fetch functions
async function fetchOverview() {
  try {
    const res = await statisticsApi.getOverviewStats(getParams())
    if (res.success && res.data) {
      overview.value = res.data
    }
  } catch {
    // silent
  }
}

async function fetchModules() {
  if (!chartModules) return
  try {
    const res = await statisticsApi.getModuleStats(getParams())
    if (res.success && res.data) {
      const modules = res.data.modules || []
      if (modules.length === 0) {
        chartModules.setOption({
          title: { text: '暂无数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
        })
        return
      }

      const names = modules.map(m => m.name)
      chartModules.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
          formatter: (params: any) => {
            let s = params[0].name + '<br/>'
            let total = 0, normal = 0
            params.forEach((p: any) => { total += p.value; if (p.seriesName === '正常') normal += p.value })
            params.forEach((p: any) => { s += p.marker + p.seriesName + ': ' + p.value + '<br/>' })
            s += '通过率: ' + (total > 0 ? (normal / total * 100).toFixed(1) : 0) + '%'
            return s
          }
        },
        legend: { data: ['正常', '警告', '严重'], bottom: 0 },
        grid: { left: 10, right: 20, bottom: 50, top: 20, containLabel: true },
        xAxis: { type: 'category', data: names, axisLabel: { rotate: 30, fontSize: 11 } },
        yAxis: { type: 'value' },
        series: [
          { name: '正常', type: 'bar', stack: 'total', data: modules.map(m => m.normal), itemStyle: { color: COLORS.normal } },
          { name: '警告', type: 'bar', stack: 'total', data: modules.map(m => m.warning), itemStyle: { color: COLORS.warning } },
          { name: '严重', type: 'bar', stack: 'total', data: modules.map(m => m.critical), itemStyle: { color: COLORS.critical } },
        ],
      })
    }
  } catch {
    // silent
  }
}

async function fetchHealthTrend() {
  if (!chartHealthTrend) return
  try {
    const res = await statisticsApi.getHealthTrend(getParams())
    if (res.success && res.data) {
      const data = res.data
      healthTrendData.value = data
      const points = data.data_points || []
      if (points.length === 0) {
        chartHealthTrend.setOption({
          title: { text: '暂无数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
        })
        return
      }

      const dates = points.map(p => p.date)
      const scores = points.map(p => p.score)

      chartHealthTrend.setOption({
        tooltip: {
          trigger: 'axis',
          formatter: (params: any) => {
            const idx = params[0].dataIndex
            const p = points[idx]
            if (!p) return ''
            let s = p.date + '<br/>'
            s += '健康度: ' + p.score + ' 分<br/>'
            s += '检测项: ' + p.total_items + ' 项<br/>'
            s += '🟢 正常: ' + p.normal_count + '<br/>'
            s += '🟡 警告: ' + p.warning_count + '<br/>'
            s += '🔴 严重: ' + p.critical_count
            return s
          },
          axisPointer: { type: 'cross' }
        },
        legend: { data: ['健康度'], bottom: 0 },
        grid: { left: 10, right: 20, bottom: 40, top: 30, containLabel: true },
        xAxis: { type: 'category', data: dates, axisLabel: { rotate: 30, fontSize: 10 } },
        yAxis: { type: 'value', min: 0, max: 100, name: '健康度' },
        series: [{
          name: '健康度',
          type: 'line',
          data: scores,
          smooth: true,
          symbol: 'circle',
          symbolSize: 7,
          lineStyle: { color: COLORS.primary, width: 2 },
          itemStyle: { color: COLORS.primary },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(37, 99, 235, 0.25)' },
              { offset: 1, color: 'rgba(37, 99, 235, 0.02)' }
            ])
          },
          markLine: {
            silent: true,
            symbol: 'none',
            data: [
              { yAxis: 80, lineStyle: { color: '#16a34a', type: 'dashed', width: 1 }, label: { formatter: '优良线 80', fontSize: 10 } },
              { yAxis: 60, lineStyle: { color: '#d97706', type: 'dashed', width: 1 }, label: { formatter: '及格线 60', fontSize: 10 } }
            ]
          }
        }],
      })
    }
  } catch {
    // silent
  }
}

async function fetchItemKeys() {
  try {
    const res = await statisticsApi.getItemKeys(getParams())
    if (res.success && res.data) {
      cachedModulesData.value = res.data
    }
  } catch {
    // silent
  }
}

async function fetchAbnormalItems() {
  if (!chartAbnormal) return
  try {
    const res = await statisticsApi.getAbnormalItems(getParams())
    if (res.success && res.data) {
      const items = res.data.items || []
      if (items.length === 0) {
        chartAbnormal.setOption({
          title: { text: '暂无异常数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
        })
        return
      }

      const names = items.map(i => i.name).reverse()
      const warns = items.map(i => i.warning_count).reverse()
      const crits = items.map(i => i.critical_count).reverse()

      chartAbnormal.setOption({
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
          formatter: (params: any) => {
            const idx = params[0].dataIndex
            const item = items.slice().reverse()[idx]
            let s = item.name + '<br/>'
            s += '模块: ' + item.module_name + '<br/>'
            s += '总出现: ' + item.total_appearances + ' 次<br/>'
            s += '异常率: ' + item.abnormal_rate + '%<br/>'
            params.forEach((p: any) => { s += p.marker + p.seriesName + ': ' + p.value + '<br/>' })
            return s
          }
        },
        legend: { data: ['警告', '严重'], bottom: 0 },
        grid: { left: 10, right: 20, bottom: 40, top: 20, containLabel: true },
        xAxis: { type: 'value' },
        yAxis: { type: 'category', data: names, axisLabel: { fontSize: 11, width: 120, overflow: 'truncate' } },
        series: [
          { name: '警告', type: 'bar', stack: 'total', data: warns, itemStyle: { color: COLORS.warning } },
          { name: '严重', type: 'bar', stack: 'total', data: crits, itemStyle: { color: COLORS.critical } },
        ],
      })
    }
  } catch {
    // silent
  }
}

async function fetchMissingReports() {
  try {
    const res = await notificationApi.checkMissingReports()
    if (res.success && res.data) {
      missingTargets.value = res.data.missing_targets || []
    }
  } catch {
    // silent
  }
}

async function fetchItemTrend() {
  if (!chartTrendLine || !chartTrendPie) return
  if (!selectedItemKey.value) {
    chartTrendLine.clear()
    chartTrendPie.clear()
    return
  }

  try {
    const res = await statisticsApi.getItemTrend(selectedItemKey.value, getParams())
    if (res.success && res.data) {
      const data = res.data
      const points = data.data_points || []
      const numericCount = points.filter(p => p.value_num !== null).length

      if (points.length === 0) {
        chartTrendLine.setOption({
          title: { text: '该检测项暂无数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
        }, true)
        chartTrendPie.setOption({
          title: { text: '暂无数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
        }, true)
        return
      }

      // Status/text type (no numeric values)
      if (numericCount === 0) {
        chartTrendLine.setOption({
          title: {
            text: '该检测项为状态/文本类型',
            subtext: '无法绘制数值趋势图，请查看右侧状态分布',
            left: 'center', top: 'center',
            textStyle: { color: '#6b7280', fontSize: 14 },
            subtextStyle: { color: '#9ca3af', fontSize: 12 }
          }
        }, true)

        const dist = data.status_distribution
        const pieData = [
          { value: dist['正常'] || 0, name: '正常', itemStyle: { color: COLORS.normal } },
          { value: dist['警告'] || 0, name: '警告', itemStyle: { color: COLORS.warning } },
          { value: dist['严重'] || 0, name: '严重', itemStyle: { color: COLORS.critical } },
        ].filter(d => d.value > 0)

        if (pieData.length > 0) {
          chartTrendPie.setOption({
            tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
            legend: { bottom: 0 },
            series: [{
              type: 'pie', radius: ['40%', '70%'],
              label: { formatter: '{b}\n{d}%' },
              data: pieData,
            }],
          }, true)
        } else {
          chartTrendPie.setOption({
            title: { text: '暂无状态数据', left: 'center', top: 'center', textStyle: { color: '#9ca3af', fontSize: 14 } }
          }, true)
        }
        return
      }

      // Numeric type - render line chart
      const times = points.map(p => p.time ? p.time.replace('T', ' ').slice(0, 16) : '')
      const values = points.map(p => p.value_num)

      // Scatter points by status
      const normalPts: [number, number][] = []
      const warnPts: [number, number][] = []
      const critPts: [number, number][] = []
      points.forEach((p, i) => {
        if (p.value_num == null) return
        if (p.status === '严重') critPts.push([i, p.value_num])
        else if (p.status === '警告') warnPts.push([i, p.value_num])
        else normalPts.push([i, p.value_num])
      })

      const series: any[] = [
        { name: data.item_name, type: 'line', data: values, lineStyle: { color: COLORS.primary, width: 2 }, itemStyle: { color: COLORS.primary }, symbol: 'circle', symbolSize: 6 },
        { name: '正常', type: 'scatter', data: normalPts, symbolSize: 8, itemStyle: { color: COLORS.normal } },
        { name: '警告', type: 'scatter', data: warnPts, symbolSize: 10, itemStyle: { color: COLORS.warning }, symbol: 'triangle' },
        { name: '严重', type: 'scatter', data: critPts, symbolSize: 10, itemStyle: { color: COLORS.critical }, symbol: 'diamond' },
      ]

      // Threshold line
      if (data.threshold) {
        const match = data.threshold.match(/([<>]=?)\s*([\d.]+)/)
        if (match) {
          const tv = parseFloat(match[2])
          series.push({
            name: '阈值', type: 'line', data: new Array(times.length).fill(tv),
            lineStyle: { color: COLORS.critical, type: 'dashed', width: 1 }, symbol: 'none',
          })
        }
      }

      chartTrendLine.setOption({
        tooltip: {
          trigger: 'axis',
          formatter: (params: any) => {
            const idx = params[0].dataIndex
            const p = points[idx]
            if (!p) return ''
            let s = p.time ? p.time.replace('T', ' ').slice(0, 16) : '' + '<br/>'
            s += '值: ' + p.value_raw + '<br/>'
            s += '状态: ' + p.status
            return s
          }
        },
        legend: { data: series.map(s => s.name), bottom: 0 },
        grid: { left: 10, right: 20, bottom: 40, top: 20, containLabel: true },
        xAxis: { type: 'category', data: times, axisLabel: { rotate: 30, fontSize: 10 } },
        yAxis: { type: 'value', name: data.unit || '' },
        series: series,
      }, true)

      // Pie chart for status distribution
      const dist = data.status_distribution
      chartTrendPie.setOption({
        tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
        legend: { bottom: 0 },
        series: [{
          type: 'pie', radius: ['40%', '70%'],
          label: { formatter: '{b}\n{d}%' },
          data: [
            { value: dist['正常'] || 0, name: '正常', itemStyle: { color: COLORS.normal } },
            { value: dist['警告'] || 0, name: '警告', itemStyle: { color: COLORS.warning } },
            { value: dist['严重'] || 0, name: '严重', itemStyle: { color: COLORS.critical } },
          ].filter(d => d.value > 0),
        }],
      }, true)
    }
  } catch {
    // silent
  }
}

// Module selector change
function onModuleChange() {
  const mod = cachedModulesData.value.find(m => m.module_id === selectedModuleId.value)
  selectedModuleItems.value = mod?.items || []
  selectedItemKey.value = ''
  if (selectedModuleItems.value.length > 0) {
    selectedItemKey.value = selectedModuleItems.value[0].key
    fetchItemTrend()
  } else {
    chartTrendLine?.clear()
    chartTrendPie?.clear()
  }
}

// Fetch all
async function fetchAllData() {
  loading.value = true
  try {
    await Promise.all([
      fetchOverview(),
      fetchModules(),
      fetchHealthTrend(),
      fetchItemKeys(),
      fetchAbnormalItems(),
      fetchMissingReports(),
    ])
    // If item selector has value, refresh trend
    if (selectedItemKey.value) {
      await fetchItemTrend()
    }
  } finally {
    loading.value = false
  }
}

// Format
function formatAbnormalItem(overview: OverviewStats | null): string {
  if (!overview?.most_abnormal_item) return '-'
  return `${overview.most_abnormal_item.name} (${overview.most_abnormal_item.abnormal_count}次)`
}

function avgItemsPerReport(overview: OverviewStats | null): string {
  if (!overview || overview.total_reports === 0) return '-'
  return Math.round(overview.total_items / overview.total_reports).toString()
}

onMounted(async () => {
  initDates()
  // Load targets for filter
  try {
    const res = await targetApi.getTargets()
    targets.value = res.targets || []
  } catch {
    // silent
  }
  initCharts()
  await fetchAllData()
})

onUnmounted(() => {
  chartModules?.dispose()
  chartHealthTrend?.dispose()
  chartTrendLine?.dispose()
  chartTrendPie?.dispose()
  chartAbnormal?.dispose()
  window.removeEventListener('resize', handleResize)
})
</script>

<template>
  <div class="page-statistics" v-loading="loading">
    <!-- Filter bar -->
    <el-card class="filter-card">
      <div class="filter-bar">
        <div class="filter-group">
          <span class="filter-label">目标服务器</span>
          <el-select v-model="filterTargetId" placeholder="全部目标" clearable style="width: 200px;">
            <el-option v-for="t in targets" :key="t.id" :label="t.name" :value="t.id" />
          </el-select>
        </div>
        <div class="filter-group">
          <span class="filter-label">开始日期</span>
          <el-date-picker v-model="filterStartDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 150px;" />
        </div>
        <div class="filter-group">
          <span class="filter-label">结束日期</span>
          <el-date-picker v-model="filterEndDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 150px;" />
        </div>
        <el-button type="primary" @click="fetchAllData">🔍 查询</el-button>
      </div>
    </el-card>

    <!-- Overview cards -->
    <div class="overview-cards">
      <el-card class="ov-card">
        <div class="value">{{ overview?.total_reports || '-' }}</div>
        <div class="label">总报告数</div>
      </el-card>
      <el-card class="ov-card warn">
        <div class="value">{{ overview?.abnormal_rate != null ? overview.abnormal_rate + '%' : '-' }}</div>
        <div class="label">异常率</div>
      </el-card>
      <el-card class="ov-card crit">
        <div class="value">{{ formatAbnormalItem(overview) }}</div>
        <div class="label">最常异常项</div>
      </el-card>
      <el-card class="ov-card highlight">
        <div class="value">{{ avgItemsPerReport(overview) }}</div>
        <div class="label">平均检测项/报告</div>
      </el-card>
    </div>

    <!-- Missing report alert banner -->
    <el-card v-if="missingTargets.length > 0" class="missing-alert">
      <div class="missing-alert-head">
        <span class="missing-alert-title">📭 报告缺失告警</span>
        <span class="missing-alert-count">{{ missingTargets.length }} 个目标超过阈值未生成报告</span>
      </div>
      <div class="missing-alert-list">
        <div v-for="mt in missingTargets" :key="mt.target_id" class="missing-target">
          <span class="target-name">{{ mt.target_name }}</span>
          <span class="target-detail">已缺 {{ mt.missing_days }} 天</span>
          <span class="target-detail" v-if="mt.last_report_at">上次报告: {{ mt.last_report_at.replace('T', ' ').slice(0, 16) }}</span>
          <span class="target-detail" v-else>从未生成报告</span>
        </div>
      </div>
    </el-card>

    <!-- Module health -->
    <el-card class="chart-card">
      <template #header>
        <span class="chart-title">🧩 模块健康概览</span>
      </template>
      <div id="chartModules" class="chart-container"></div>
    </el-card>

    <!-- Health trend -->
    <el-card class="chart-card">
      <template #header>
        <span class="chart-title">📈 健康度趋势</span>
      </template>
      <div class="trend-summary" v-if="healthTrendData">
        <span class="trend-summary-item">
          整体评分: <strong>{{ healthTrendData.overall_score }}</strong> 分
        </span>
        <span class="trend-summary-item">
          报告数: <strong>{{ healthTrendData.data_points.length }}</strong> 份
        </span>
      </div>
      <div id="chartHealthTrend" class="chart-container"></div>
    </el-card>

    <!-- Item trend -->
    <el-card class="chart-card">
      <template #header>
        <div class="chart-header">
          <span class="chart-title">📉 检测项趋势分析</span>
          <div class="trend-filters">
            <el-select v-model="selectedModuleId" placeholder="-- 选择模块 --" @change="onModuleChange" style="width: 160px;">
              <el-option-group v-for="group in cachedModulesData" :key="group.module_id" :label="group.category === 'system' ? '系统检测' : '服务检测'">
                <el-option :label="group.module_name" :value="group.module_id" />
              </el-option-group>
            </el-select>
            <el-select
              v-model="selectedItemKey"
              placeholder="-- 选择检测项 --"
              :disabled="selectedModuleItems.length === 0"
              @change="fetchItemTrend"
              style="width: 200px;"
            >
              <el-option
                v-for="item in selectedModuleItems"
                :key="item.key"
                :label="item.name + (item.has_numeric ? '' : ' (状态)')"
                :value="item.key"
              />
            </el-select>
          </div>
        </div>
      </template>
      <div class="trend-layout">
        <div class="trend-left">
          <div id="chartTrendLine" class="chart-container" style="min-height: 300px;"></div>
        </div>
        <div class="trend-right">
          <div id="chartTrendPie" class="chart-container" style="min-height: 300px;"></div>
        </div>
      </div>
    </el-card>

    <!-- Abnormal items -->
    <el-card class="chart-card">
      <template #header>
        <span class="chart-title">🚨 高频异常检测项 TOP 10</span>
      </template>
      <div id="chartAbnormal" class="chart-container"></div>
    </el-card>
  </div>
</template>

<style scoped lang="scss">
.page-statistics {
  padding: 0 0 40px;
}

.filter-card {
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  margin-bottom: 20px;
}

.filter-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.filter-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.filter-label {
  font-size: 14px;
  color: $gray-700;
  font-weight: 500;
}

.overview-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}

.ov-card {
  border-radius: 12px;
  text-align: center;

  :deep(.el-card__body) {
    padding: 18px;
  }

  .value {
    font-size: 28px;
    font-weight: 700;
    color: $gray-900;
  }

  .label {
    font-size: 13px;
    color: $gray-500;
    margin-top: 4px;
  }

  &.warn .value { color: $yellow; }
  &.crit .value { color: $red; }
  &.highlight .value { color: $primary; }
}

.chart-card {
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  margin-bottom: 20px;

  :deep(.el-card__header) {
    padding: 16px 20px;
    border-bottom: 1px solid $gray-200;
  }

  :deep(.el-card__body) {
    padding: 20px;
  }
}

.missing-alert {
  border-radius: 12px;
  border: 1px solid #fecaca;
  background: #fef2f2;
  margin-bottom: 20px;

  :deep(.el-card__body) {
    padding: 16px 20px;
  }
}

.missing-alert-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.missing-alert-title {
  font-size: 15px;
  font-weight: 700;
  color: #b91c1c;
}

.missing-alert-count {
  font-size: 13px;
  color: #dc2626;
}

.missing-alert-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.missing-target {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 14px;
  color: #7f1d1d;
}

.missing-target .target-name {
  font-weight: 600;
}

.missing-target .target-detail {
  color: #b91c1c;
  font-size: 13px;
}

.chart-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

.chart-title {
  font-size: 16px;
  font-weight: 700;
  color: $gray-900;
}

.trend-filters {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.chart-container {
  width: 100%;
  min-height: 350px;
}

.trend-summary {
  display: flex;
  gap: 24px;
  margin-bottom: 16px;
  padding: 8px 12px;
  background: #f8fafc;
  border-radius: 8px;
  font-size: 14px;
  color: #475569;
}

.trend-summary-item strong {
  color: #2563eb;
  font-size: 16px;
}

.trend-layout {
  display: flex;
  gap: 20px;
}

.trend-left {
  flex: 2;
  min-width: 0;
}

.trend-right {
  flex: 1;
  min-width: 0;
}

@media screen and (max-width: 1024px) {
  .overview-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media screen and (max-width: 768px) {
  .filter-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .filter-group {
    width: 100%;
  }

  .filter-label {
    font-size: 13px;
  }

  .overview-cards {
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }

  .ov-card {
    :deep(.el-card__body) {
      padding: 12px;
    }
    .value { font-size: 22px; }
    .label { font-size: 12px; }
  }

  .trend-layout {
    flex-direction: column;
    gap: 16px;
  }

  .chart-container {
    min-height: 250px;
  }

  .chart-header {
    flex-direction: column;
    align-items: flex-start;
  }

  .trend-filters {
    flex-direction: column;
    width: 100%;
  }
}

@media screen and (max-width: 480px) {
  .overview-cards {
    gap: 6px;
  }

  .ov-card {
    :deep(.el-card__body) {
      padding: 10px;
    }
    .value { font-size: 18px; }
    .label { font-size: 11px; }
  }

  .chart-container {
    min-height: 200px;
  }
}
</style>