<template>
  <div class="equipment-abnormal">
    <!-- 左侧面板 -->
    <div class="left-panel">
      <!-- 搜索 -->
      <div class="panel-card search-card">
        <div class="panel-title"><el-icon><Search /></el-icon> 快速查询</div>
        <el-input v-model="searchKey" placeholder="设备名称/编号/地址" clearable prefix-icon="Search" size="default" />
        <el-select v-model="levelFilter" placeholder="异常等级" clearable style="width:100%;margin-top:10px">
          <el-option label="严重" value="严重" />
          <el-option label="一般" value="一般" />
          <el-option label="轻微" value="轻微" />
        </el-select>
        <el-select v-model="typeFilter" placeholder="设备类型" clearable style="width:100%;margin-top:10px">
          <el-option label="阀门" value="阀门" />
          <el-option label="调压器" value="调压器" />
          <el-option label="流量计" value="流量计" />
          <el-option label="窨井盖" value="窨井盖" />
          <el-option label="终端节点" value="终端节点" />
          <el-option label="检查井" value="检查井" />
        </el-select>
        <el-select v-model="statusFilter" placeholder="处理状态" clearable style="width:100%;margin-top:10px">
          <el-option label="待处理" value="待处理" />
          <el-option label="处理中" value="处理中" />
          <el-option label="已修复" value="已修复" />
        </el-select>
        <div style="display:flex;gap:8px;margin-top:10px">
          <el-button type="primary" size="small" @click="handleQuery" style="flex:1">查询</el-button>
          <el-button size="small" @click="handleReset" style="flex:1">重置</el-button>
        </div>
      </div>

      <!-- 异常等级分布 -->
      <div class="panel-card">
        <div class="panel-title"><el-icon><PieChart /></el-icon> 异常等级分布</div>
        <div class="level-list">
          <div class="level-item critical">
            <span class="level-dot"></span>
            <span class="level-label">严重</span>
            <span class="level-count">{{ stats.critical }}</span>
          </div>
          <div class="level-item warning">
            <span class="level-dot"></span>
            <span class="level-label">一般</span>
            <span class="level-count">{{ stats.normal }}</span>
          </div>
          <div class="level-item minor">
            <span class="level-dot"></span>
            <span class="level-label">轻微</span>
            <span class="level-count">{{ stats.minor }}</span>
          </div>
        </div>
      </div>

      <!-- 设备类型统计 -->
      <div class="panel-card">
        <div class="panel-title"><el-icon><Histogram /></el-icon> 设备类型统计</div>
        <div class="type-list">
          <div class="type-item" v-for="item in deviceTypeStats" :key="item.name">
            <span class="type-name">{{ item.name }}</span>
            <span class="type-bar-bg"><span class="type-bar" :style="{width: (stats.total > 0 ? item.count/stats.total*100 : 0)+'%', background: item.color}"></span></span>
            <span class="type-count">{{ item.count }}</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 右侧内容区 -->
    <div class="right-panel">
      <!-- 统计卡片 -->
      <div class="stats-row">
        <div class="stat-card stat-total">
          <div class="stat-icon"><el-icon size="22"><WarningFilled /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">异常设备总数</div>
            <div class="stat-value">{{ stats.total }} <small>台</small></div>
          </div>
        </div>
        <div class="stat-card stat-today">
          <div class="stat-icon"><el-icon size="22"><Clock /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">今日新增</div>
            <div class="stat-value">{{ stats.today }} <small>台</small></div>
          </div>
        </div>
        <div class="stat-card stat-rate">
          <div class="stat-icon"><el-icon size="22"><TrendCharts /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">异常占比</div>
            <div class="stat-value">{{ stats.rate }} <small>%</small></div>
          </div>
        </div>
        <div class="stat-card stat-processed">
          <div class="stat-icon"><el-icon size="22"><CircleCheckFilled /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">已修复</div>
            <div class="stat-value">{{ stats.processed }} <small>台</small></div>
          </div>
        </div>
        <div class="stat-card stat-pending">
          <div class="stat-icon"><el-icon size="22"><Warning /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">待处理</div>
            <div class="stat-value">{{ stats.pending }} <small>台</small></div>
          </div>
        </div>
        <div class="stat-card stat-process-rate">
          <div class="stat-icon"><el-icon size="22"><DataAnalysis /></el-icon></div>
          <div class="stat-info">
            <div class="stat-label">修复率</div>
            <div class="stat-value">{{ stats.processRate }} <small>%</small></div>
          </div>
        </div>
      </div>

      <!-- 图表区域 - 上方: 趋势图(全宽) -->
      <div class="chart-card chart-trend">
        <div class="chart-header">
          <span class="chart-title">设备异常趋势图</span>
          <span class="chart-subtitle">近15天运行数据</span>
          <div class="chart-legend-custom">
            <span class="legend-tag tag-total">异常总数</span>
            <span class="legend-tag tag-new">新增异常</span>
            <span class="legend-tag tag-fixed">已修复</span>
          </div>
        </div>
        <div id="trendChart" class="chart-body chart-body-large" style="height:340px"></div>
      </div>

      <!-- 图表区域 - 下方: 两个图表并排 -->
      <div class="charts-row">
        <div class="chart-card chart-half">
          <div class="chart-header">
            <span class="chart-title">异常类型分布</span>
          </div>
          <div id="typeChart" class="chart-body" style="height:290px"></div>
        </div>
        <div class="chart-card chart-half">
          <div class="chart-header">
            <span class="chart-title">设备异常等级与处理状态</span>
          </div>
          <div id="levelChart" class="chart-body" style="height:290px"></div>
        </div>
      </div>

      <!-- 异常设备列表 -->
      <div class="table-card">
        <div class="table-header">
          <span class="table-title">异常设备列表</span>
          <span class="table-count">共 {{ tableTotal }} 条记录</span>
        </div>
        <el-table :data="paginatedData" border stripe v-loading="loading" max-height="460" size="small"
          @sort-change="handleSortChange" :default-sort="{ prop: 'alarmTime', order: 'descending' }">
          <el-table-column prop="id" label="序号" width="56" align="center" sortable="custom" />
          <el-table-column prop="deviceCode" label="设备编号" min-width="140" show-overflow-tooltip />
          <el-table-column prop="deviceName" label="设备名称" min-width="150" show-overflow-tooltip />
          <el-table-column prop="deviceType" label="设备类型" width="100" />
          <el-table-column prop="level" label="异常等级" width="100" align="center" sortable="custom">
            <template #default="{ row }">
              <el-tag :type="levelTagType(row.level)" size="small">{{ row.level }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="alarmDesc" label="异常描述" min-width="220" show-overflow-tooltip />
          <el-table-column prop="address" label="安装地址" min-width="200" show-overflow-tooltip />
          <el-table-column prop="alarmTime" label="异常时间" width="168" sortable="custom" />
          <el-table-column prop="processStatus" label="处理状态" width="100" align="center" sortable="custom">
            <template #default="{ row }">
              <el-tag :type="row.processStatus === '已修复' ? 'success' : row.processStatus === '处理中' ? 'warning' : 'danger'" size="small">
                {{ row.processStatus }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150" fixed="right" align="center">
            <template #default="{ row }">
              <el-button type="primary" link size="small" @click="handleDetail(row)">详情</el-button>
              <el-button v-if="row.processStatus === '待处理'" type="warning" link size="small" @click="handleProcess(row)">处理</el-button>
              <el-button v-if="row.processStatus === '处理中'" type="success" link size="small" @click="handleComplete(row)">完成</el-button>
            </template>
          </el-table-column>
        </el-table>
        <div class="table-footer">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :total="tableTotal"
            layout="total, prev, pager, next"
            :page-sizes="[10, 20]"
            small
            background
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { Clock, CircleCheckFilled, DataAnalysis, Histogram, PieChart, Search, TrendCharts, Warning, WarningFilled } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getEquipmentAbnormalList, getEquipmentAbnormalStats } from '@/api/pipeNetwork/gasMonitor'

const loading = ref(false)
const searchKey = ref('')
const levelFilter = ref('')
const typeFilter = ref('')
const statusFilter = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const sortProp = ref('alarmTime')
const sortOrder = ref('descending')

let trendChart = null
let typeChart = null
let levelChart = null

// ==================== 统计数据（从API加载） ====================
const stats = ref({
  total: 0, today: 0, rate: 0, processed: 0, pending: 0,
  processRate: 0, critical: 0, normal: 0, minor: 0
})

const deviceTypeStats = ref([])

async function loadStats() {
  try {
    const res = await getEquipmentAbnormalStats()
    if (res.data) {
      const d = res.data
      stats.value = {
        total: d.total || 0, today: d.today || 0, rate: d.rate || 0,
        processed: d.processed || 0, pending: d.pending || 0,
        processRate: d.processRate || 0, critical: d.critical || 0,
        normal: d.normal || 0, minor: d.minor || 0
      }
      // 设备类型统计
      const colors = ['#e63946', '#f77f00', '#2d6a4f', '#7f4f24', '#6c757d', '#b08968']
      const typeMap = d.deviceTypeStats || {}
      let idx = 0
      deviceTypeStats.value = Object.entries(typeMap).map(([name, count]) => ({
        name, count, color: colors[idx++ % colors.length]
      }))
      // 图表数据
      chartData.value = {
        trend: d.trend || { dates: [], totalData: [], newData: [], fixedData: [] },
        typeDistribution: d.typeDistribution || { categories: [], values: [] },
        levelStatus: d.levelStatus || { levels: [], pending: [], processing: [], fixed: [] }
      }
    }
  } catch (e) { console.error(e) }
}

// ==================== 图表数据（从API动态加载） ====================
const chartData = ref({
  trend: { dates: [], totalData: [], newData: [], fixedData: [] },
  typeDistribution: { categories: [], values: [] },
  levelStatus: { levels: [], pending: [], processing: [], fixed: [] }
})

// ==================== 表格数据（从API加载） ====================
const tableData = ref([])
const tableTotal = ref(0)

async function loadList() {
  loading.value = true
  try {
    const res = await getEquipmentAbnormalList({
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      searchKey: searchKey.value || undefined,
      level: levelFilter.value || undefined,
      type: typeFilter.value || undefined,
      status: statusFilter.value || undefined
    })
    if (res.data) {
      tableData.value = (res.data.rows || []).map((r, i) => ({
        ...r,
        id: String((currentPage.value - 1) * pageSize.value + i + 1),
        level: r.levelText || r.faultLevel,
        processStatus: r.processStatus || '待处理',
        alarmTime: r.alarmTime || '',
        alarmDesc: r.alarmDesc || '',
        deviceCode: r.deviceCode || '',
        deviceName: r.deviceName || '',
        deviceType: r.deviceType || '',
        address: r.address || ''
      }))
      tableTotal.value = res.data.total || 0
    }
  } catch (e) { console.error(e) } finally { loading.value = false }
}

const paginatedData = computed(() => {
  const list = [...tableData.value]
  if (sortProp.value) {
    list.sort((a, b) => {
      const va = a[sortProp.value] || ''
      const vb = b[sortProp.value] || ''
      const cmp = typeof va === 'string' ? va.localeCompare(vb) : va - vb
      return sortOrder.value === 'descending' ? -cmp : cmp
    })
  }
  return list
})

// 排序切换
function handleSortChange({ prop, order }) {
  sortProp.value = prop
  sortOrder.value = order || 'descending'
}

// 分页切换时重载
watch(currentPage, () => loadList())
watch(pageSize, () => { currentPage.value = 1; loadList() })

// ==================== 工具函数 ====================
function levelTagType(level) {
  if (level === '严重') return 'danger'
  if (level === '一般') return 'warning'
  return 'info'
}

function handleQuery() {
  currentPage.value = 1
  loadList()
}

function handleReset() {
  searchKey.value = ''
  levelFilter.value = ''
  typeFilter.value = ''
  statusFilter.value = ''
  currentPage.value = 1
  loadList()
}

function handleDetail(row) {
  ElMessageBox.alert(
    `<div style="line-height:2.2;font-size:14px;">
      <p><b>设备编号：</b>${row.deviceCode}</p>
      <p><b>设备名称：</b>${row.deviceName}</p>
      <p><b>设备类型：</b>${row.deviceType}</p>
      <p><b>异常等级：</b><span style="color:${row.level==='严重'?'#e63946':row.level==='一般'?'#f77f00':'#909399'}">${row.level}</span></p>
      <p><b>异常描述：</b>${row.alarmDesc}</p>
      <p><b>安装地址：</b>${row.address}</p>
      <p><b>异常时间：</b>${row.alarmTime}</p>
      <p><b>处理状态：</b>${row.processStatus}</p>
    </div>`,
    '设备异常详情',
    { dangerouslyUseHTMLString: true, confirmButtonText: '关闭', customClass: 'detail-dialog' }
  )
}

function handleProcess(row) {
  ElMessageBox.confirm(`确认开始处理设备「${row.deviceName}」的异常？系统将自动派发工单至运维班组。`, '处理确认', {
    confirmButtonText: '确认处理',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    row.processStatus = '处理中'
    ElMessage.success(`已派发工单，设备「${row.deviceName}」处理中`)
  }).catch(() => {})
}

function handleComplete(row) {
  ElMessageBox.confirm(`确认设备「${row.deviceName}」的异常已修复完成？`, '修复确认', {
    confirmButtonText: '确认修复',
    cancelButtonText: '取消',
    type: 'success'
  }).then(() => {
    row.processStatus = '已修复'
    ElMessage.success(`设备「${row.deviceName}」异常已修复`)
  }).catch(() => {})
}

// ==================== ECharts ====================
function initTrendChart() {
  const dom = document.getElementById('trendChart')
  if (!dom) return
  if (trendChart) trendChart.dispose()
  trendChart = echarts.init(dom)
  const t = chartData.value.trend
  trendChart.setOption({
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(255,255,255,0.96)',
      borderColor: '#e0e4ea',
      textStyle: { color: '#2c3e50', fontSize: 13 }
    },
    legend: {
      data: ['异常总数', '新增异常', '已修复'],
      top: 0,
      textStyle: { color: '#606a78', fontSize: 12 }
    },
    grid: { left: 52, right: 44, top: 44, bottom: 32 },
    xAxis: {
      type: 'category',
      data: t.dates || [],
      boundaryGap: false,
      axisLabel: { color: '#9098a6', fontSize: 12 },
      axisLine: { lineStyle: { color: '#d0d5dd' } }
    },
    yAxis: {
      type: 'value',
      name: '数量(台)',
      nameTextStyle: { color: '#9098a6', fontSize: 12 },
      axisLabel: { color: '#9098a6', fontSize: 12 },
      splitLine: { lineStyle: { color: '#f0f2f6', type: 'dashed' } }
    },
    series: [
      {
        name: '异常总数', type: 'line',
        data: t.totalData || [], smooth: true, symbol: 'circle', symbolSize: 6,
        lineStyle: { width: 3, color: '#e63946' },
        itemStyle: { color: '#e63946', borderColor: '#fff', borderWidth: 2 },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(230,57,70,0.15)' },
            { offset: 1, color: 'rgba(230,57,70,0.0)' }
          ])
        }
      },
      {
        name: '新增异常', type: 'line',
        data: t.newData || [], smooth: true, symbol: 'emptyCircle', symbolSize: 6,
        lineStyle: { width: 2.5, color: '#f77f00' },
        itemStyle: { color: '#f77f00', borderColor: '#f77f00', borderWidth: 2 }
      },
      {
        name: '已修复', type: 'line',
        data: t.fixedData || [], smooth: true, symbol: 'diamond', symbolSize: 7,
        lineStyle: { width: 2.5, color: '#2a9d8f', type: 'dashed' },
        itemStyle: { color: '#2a9d8f', borderColor: '#fff', borderWidth: 2 }
      }
    ]
  })
}

function initTypeChart() {
  const dom = document.getElementById('typeChart')
  if (!dom) return
  if (typeChart) typeChart.dispose()
  typeChart = echarts.init(dom)
  const d = chartData.value.typeDistribution
  const colors = ['#457b9d', '#e76f51', '#e63946']
  typeChart.setOption({
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    grid: { left: 46, right: 20, top: 16, bottom: 32 },
    xAxis: {
      type: 'category',
      data: d.categories || [],
      axisLabel: { color: '#9098a6', fontSize: 11, rotate: 15 },
      axisLine: { lineStyle: { color: '#d0d5dd' } }
    },
    yAxis: {
      type: 'value', name: '数量(台)',
      axisLabel: { color: '#9098a6', fontSize: 11 },
      splitLine: { lineStyle: { color: '#f0f2f6', type: 'dashed' } }
    },
    series: [{
      type: 'bar',
      data: (d.values || []).map((v, i) => ({ value: v, itemStyle: { color: colors[i] || '#6c757d', borderRadius: [4, 4, 0, 0] } })),
      barWidth: 28,
      label: { show: true, position: 'top', color: '#4e5969', fontSize: 12, fontWeight: 600 }
    }]
  })
}

function initLevelChart() {
  const dom = document.getElementById('levelChart')
  if (!dom) return
  if (levelChart) levelChart.dispose()
  levelChart = echarts.init(dom)
  const d = chartData.value.levelStatus
  levelChart.setOption({
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    legend: {
      data: ['待处理', '处理中', '已修复'],
      top: 0,
      textStyle: { color: '#606a78', fontSize: 12 }
    },
    grid: { left: 46, right: 20, top: 44, bottom: 28 },
    xAxis: {
      type: 'category',
      data: d.levels || [],
      axisLabel: { color: '#9098a6', fontSize: 12 },
      axisLine: { lineStyle: { color: '#d0d5dd' } }
    },
    yAxis: {
      type: 'value', name: '数量(台)',
      axisLabel: { color: '#9098a6', fontSize: 11 },
      splitLine: { lineStyle: { color: '#f0f2f6', type: 'dashed' } },
      nameTextStyle: { color: '#9098a6', fontSize: 11 }
    },
    series: [
      {
        name: '待处理', type: 'bar',
        data: d.pending || [], barWidth: 30, barGap: '20%',
        itemStyle: { color: '#e63946', borderRadius: [4, 4, 0, 0] }
      },
      {
        name: '处理中', type: 'bar',
        data: d.processing || [], barWidth: 30,
        itemStyle: { color: '#f77f00', borderRadius: [4, 4, 0, 0] }
      },
      {
        name: '已修复', type: 'bar',
        data: d.fixed || [], barWidth: 30,
        itemStyle: { color: '#2a9d8f', borderRadius: [4, 4, 0, 0] }
      }
    ]
  })
}

function initCharts() {
  try { initTrendChart() } catch (e) { console.warn('趋势图初始化失败：', e) }
  try { initTypeChart() } catch (e) { console.warn('类型分布图初始化失败：', e) }
  try { initLevelChart() } catch (e) { console.warn('等级统计图初始化失败：', e) }
}

function resizeCharts() {
  trendChart?.resize()
  typeChart?.resize()
  levelChart?.resize()
}

onMounted(async () => {
  await nextTick()
  // 先加载数据，再初始化图表
  await Promise.all([loadStats(), loadList()])
  await nextTick()
  initCharts()
  window.addEventListener('resize', resizeCharts)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeCharts)
  trendChart?.dispose()
  typeChart?.dispose()
  levelChart?.dispose()
})
</script>

<style scoped>
.equipment-abnormal {
  display: flex;
  gap: 16px;
  padding: 16px;
  background: #f0f2f6;
  min-height: calc(100vh - 84px);
}

/* ========== 左侧面板 ========== */
.left-panel {
  width: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.panel-card {
  background: #fff;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 2px 12px rgba(15, 35, 95, 0.04);
}

.panel-title {
  font-size: 14px;
  font-weight: 700;
  color: #1f2d3d;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 10px;
  border-bottom: 1px solid #f0f2f6;
}

.panel-title .el-icon { color: #1890ff; }

/* 等级列表 */
.level-list { display: flex; flex-direction: column; gap: 8px; }
.level-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  background: #f8fafc;
  cursor: pointer;
  transition: all 0.2s;
}
.level-item:hover { background: #eef2f8; transform: translateX(4px); }
.level-dot { width: 10px; height: 10px; border-radius: 50%; }
.level-item.critical .level-dot { background: #e63946; box-shadow: 0 0 6px rgba(230,57,70,0.4); }
.level-item.warning .level-dot { background: #f77f00; box-shadow: 0 0 6px rgba(247,127,0,0.4); }
.level-item.minor .level-dot { background: #457b9d; box-shadow: 0 0 6px rgba(69,123,157,0.4); }
.level-label { flex: 1; font-size: 13px; color: #4e5969; }
.level-count { font-size: 18px; font-weight: 700; color: #1f2d3d; }

/* 设备类型列表 */
.type-list { display: flex; flex-direction: column; gap: 10px; }
.type-item { display: flex; align-items: center; gap: 10px; }
.type-name { width: 56px; font-size: 12px; color: #606a78; text-align: right; flex-shrink: 0; }
.type-bar-bg { flex: 1; height: 8px; background: #f0f2f6; border-radius: 4px; overflow: hidden; }
.type-bar { height: 100%; border-radius: 4px; transition: width 0.6s ease; }
.type-count { width: 24px; font-size: 12px; font-weight: 600; color: #1f2d3d; text-align: right; flex-shrink: 0; }

/* ========== 右侧内容区 ========== */
.right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

/* 统计卡片 */
.stats-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
}

.stat-card {
  background: #fff;
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: 0 2px 12px rgba(15, 35, 95, 0.04);
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  transition: all 0.25s;
}
.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(15, 35, 95, 0.1);
}

.stat-icon {
  width: 44px; height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.stat-total .stat-icon { background: #fef0f0; color: #e63946; }
.stat-today .stat-icon { background: #fff3e6; color: #f77f00; }
.stat-rate .stat-icon { background: #fef5e7; color: #e76f51; }
.stat-processed .stat-icon { background: #e8f8f5; color: #2a9d8f; }
.stat-pending .stat-icon { background: #eaf2f8; color: #457b9d; }
.stat-process-rate .stat-icon { background: #e8f5e9; color: #2d6a4f; }

.stat-label { font-size: 12px; color: #9098a6; margin-bottom: 4px; }
.stat-value { font-size: 24px; font-weight: 700; color: #1f2d3d; line-height: 1.1; }
.stat-value small { font-size: 12px; color: #9098a6; font-weight: 400; }

/* 图表卡片 */
.chart-card {
  background: #fff;
  border-radius: 12px;
  padding: 16px 20px;
  box-shadow: 0 2px 12px rgba(15, 35, 95, 0.04);
  display: flex;
  flex-direction: column;
}

.chart-trend { /* 全宽 */ }

.charts-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.chart-half { flex: 1; }

.chart-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.chart-title {
  font-size: 15px;
  font-weight: 700;
  color: #1f2d3d;
}

.chart-subtitle {
  font-size: 12px;
  color: #a0a9b6;
}

.chart-legend-custom {
  margin-left: auto;
  display: flex;
  gap: 8px;
}

.legend-tag {
  font-size: 11px;
  padding: 2px 10px;
  border-radius: 10px;
  color: #fff;
}
.tag-total { background: #e63946; }
.tag-new { background: #f77f00; }
.tag-fixed { background: #2a9d8f; }

.chart-body {
  flex: 1;
  min-height: 280px;
}
.chart-body-large {
  min-height: 330px;
}

/* 表格卡片 */
.table-card {
  background: #fff;
  border-radius: 12px;
  padding: 16px 20px;
  box-shadow: 0 2px 12px rgba(15, 35, 95, 0.04);
}

.table-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.table-title {
  font-size: 15px;
  font-weight: 700;
  color: #1f2d3d;
}

.table-count {
  font-size: 12px;
  color: #9098a6;
}

.table-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}

/* ========== 响应式 ========== */
@media (max-width: 1600px) {
  .stats-row { grid-template-columns: repeat(3, 1fr); }
  .left-panel { width: 260px; }
}

@media (max-width: 1400px) {
  .equipment-abnormal { flex-direction: column; }
  .left-panel { width: 100%; flex-direction: row; flex-wrap: wrap; }
  .left-panel .panel-card { flex: 1; min-width: 240px; }
  .charts-row { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .stats-row { grid-template-columns: repeat(2, 1fr); }
}
</style>
