<!--实时监测一张图-->
<template>
  <div class="gas-safety-gis">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <el-icon><MapLocation /></el-icon>
        <span class="title">燃气安全实时监测一张图</span>
        <div class="stats-badge">
          <span class="stat-item"><i class="dot pipeline-dot"></i>管线 {{ pipelineCount }}km</span>
          <span class="stat-item"><i class="dot monitor-dot"></i>监测点 {{ monitorCount }}</span>
          <span class="stat-item"><i class="dot station-dot"></i>场站 {{ stationCount }}</span>
          <span class="stat-item critical"><i class="dot alert-dot"></i>告警 {{ alertCount }}</span>
        </div>
      </div>
      <div class="header-right">
        <el-input v-model="searchKeyword" placeholder="搜索设施/地址" clearable :prefix-icon="Search" style="width:220px" @input="onSearch" />
        <el-button type="primary" :icon="Refresh" @click="refreshData">刷新</el-button>
        <el-button :icon="FullScreen" @click="fitBounds">全图</el-button>
      </div>
    </div>

    <!-- 主内容区 -->
    <div class="main-layout">
      <!-- 左侧图层控制面板 -->
      <div class="layer-panel">
        <div class="layer-header">分类图层</div>
        <div class="layer-tree">
          <div class="layer-group">
            <div class="group-title">燃气管网</div>
            <el-checkbox v-model="layers.highPressure" @change="onLayerChange">高压管线</el-checkbox>
            <el-checkbox v-model="layers.mediumPressure" @change="onLayerChange">中压管线</el-checkbox>
            <el-checkbox v-model="layers.lowPressure" @change="onLayerChange">低压管线</el-checkbox>
          </div>
          <div class="layer-group">
            <div class="group-title">相邻地下空间监测</div>
            <el-checkbox v-model="layers.methane" @change="onLayerChange">甲烷监测点</el-checkbox>
            <el-checkbox v-model="layers.temperature" @change="onLayerChange">温湿度监测</el-checkbox>
          </div>
          <div class="layer-group">
            <div class="group-title">管线压力/流量监测</div>
            <el-checkbox v-model="layers.pressure" @change="onLayerChange">压力监测点</el-checkbox>
            <el-checkbox v-model="layers.flow" @change="onLayerChange">流量监测点</el-checkbox>
          </div>
          <div class="layer-group">
            <div class="group-title">燃气场站</div>
            <el-checkbox v-model="layers.gateStation" @change="onLayerChange">门站</el-checkbox>
            <el-checkbox v-model="layers.regulatorStation" @change="onLayerChange">调压站</el-checkbox>
            <el-checkbox v-model="layers.lngStation" @change="onLayerChange">LNG储配站</el-checkbox>
          </div>
          <div class="layer-group">
            <div class="group-title">告警图层</div>
            <el-checkbox v-model="layers.alert" @change="onLayerChange">实时告警点</el-checkbox>
          </div>
        </div>

        <div class="legend-panel">
          <div class="legend-title">图例说明</div>
          <div><span class="legend-line high"></span> 高压管线 (0.4MPa)</div>
          <div><span class="legend-line medium"></span> 中压管线 (0.2MPa)</div>
          <div><span class="legend-line low"></span> 低压管线 (0.1MPa)</div>
          <div><span class="legend-point methane"></span> 甲烷监测点</div>
          <div><span class="legend-point temp"></span> 温湿度监测</div>
          <div><span class="legend-point pressure"></span> 压力监测点</div>
          <div><span class="legend-point flow"></span> 流量监测点</div>
          <div><span class="legend-point station"></span> 燃气场站</div>
          <div><span class="legend-point alert-l"></span> 告警设备</div>
        </div>

        <div class="stats-panel">
          <div class="stats-title">实时统计</div>
          <div class="stats-row"><span>平均压力:</span><span class="value">{{ avgPressure }} kPa</span></div>
          <div class="stats-row"><span>平均流量:</span><span class="value">{{ avgFlow }} Nm³/h</span></div>
          <div class="stats-row"><span>最高甲烷浓度:</span><span class="value alert-value">{{ maxMethane }} ppm</span></div>
          <div class="stats-row"><span>设备在线率:</span><span class="value">{{ onlineRate }}%</span></div>
        </div>
      </div>

      <!-- 右侧GIS地图 -->
      <div class="gis-container">
        <div class="map-toolbar">
          <el-button-group>
            <el-button size="small" :icon="ZoomIn" @click="zoomIn">放大</el-button>
            <el-button size="small" :icon="ZoomOut" @click="zoomOut">缩小</el-button>
            <el-button size="small" :icon="Location" @click="fitBounds">重置视图</el-button>
          </el-button-group>
          <div class="coordinate-info">坐标: {{ currentLng.toFixed(4) }}, {{ currentLat.toFixed(4) }}</div>
        </div>
        <div class="map-wrapper">
          <div id="gasSafetyBaiduMap" class="map-div"></div>
          <div v-if="mapError" class="map-error">{{ mapError }}</div>
        </div>

        <!-- 设施详情抽屉 -->
        <el-drawer v-model="detailDrawerVisible" :title="`设施详情 - ${currentFeature?.name || ''}`" size="450px" direction="rtl">
          <div v-if="currentFeature" class="feature-detail">
            <el-descriptions :column="1" border>
              <el-descriptions-item label="设施名称">{{ currentFeature.name }}</el-descriptions-item>
              <el-descriptions-item label="设施编号">{{ currentFeature.code || '—' }}</el-descriptions-item>
              <el-descriptions-item label="设施类型">{{ currentFeature.typeName }}</el-descriptions-item>
              <el-descriptions-item label="详细地址">{{ currentFeature.address }}</el-descriptions-item>
              <el-descriptions-item label="经纬度">{{ currentFeature.lng }}, {{ currentFeature.lat }}</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.pressure" label="当前压力">{{ currentFeature.pressure }} kPa</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.flow" label="当前流量">{{ currentFeature.flow }} Nm³/h</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.methane" label="甲烷浓度">{{ currentFeature.methane }} ppm</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.temperature" label="温度">{{ currentFeature.temperature }} °C</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.humidity" label="湿度">{{ currentFeature.humidity }} %RH</el-descriptions-item>
              <el-descriptions-item label="运行状态">
                <el-tag :type="statusTagType(currentFeature.status)">{{ statusLabel(currentFeature.status) }}</el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="最后通讯">{{ currentFeature.updateTime }}</el-descriptions-item>
            </el-descriptions>
          </div>
        </el-drawer>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { MapLocation, Search, Refresh, FullScreen, ZoomIn, ZoomOut, Location } from '@element-plus/icons-vue'
import { convertPipeline, convertPoints, convertCoord } from '@/utils/coordTransform'

// ==================== 图层状态 ====================
const layers = reactive({
  highPressure: true, mediumPressure: true, lowPressure: true,
  methane: true, temperature: true,
  pressure: true, flow: true,
  gateStation: true, regulatorStation: true, lngStation: true,
  alert: true
})

const searchKeyword = ref('')
const mapError = ref('')
let mapInstance = null
let activeInfoWindow = null

// 存储所有覆盖物以便按图层显隐
const overlayStore = {
  highPressure: [], mediumPressure: [], lowPressure: [],
  methane: [], temperature: [],
  pressure: [], flow: [],
  gateStation: [], regulatorStation: [], lngStation: [],
  alert: []
}

// ==================== 沅陵县太常片区静态数据 ====================
const MAP_CENTER = { lng: 110.386, lat: 28.445 }
const MAP_DEFAULT_ZOOM = 14

// --- 管线数据 (polyline paths) ---
const pipelines = [
  { id: 'P1', name: '燃气1', type: 'highPressure', pressure: '高压 0.4MPa', color: '#f56c6c', width: 5,
    path: [[110.404947, 28.433419], [110.404836, 28.433429], [110.403275, 28.433571], [110.401084, 28.433876], [110.399601, 28.433876], [110.398112, 28.433979], [110.396717, 28.434314], [110.394299, 28.434538], [110.394352, 28.434887], [110.391969, 28.434985], [110.384374, 28.435695], [110.381418, 28.43559], [110.377993, 28.436193], [110.376062, 28.436385], [110.374231, 28.43655], [110.372584, 28.437107], [110.371292, 28.4377], [110.370581, 28.438198], [110.369831, 28.438821]] },
  { id: 'P2', name: '燃气2', type: 'mediumPressure', pressure: '中压 0.2MPa', color: '#e6a23c', width: 4,
    path: [[110.361433, 28.454979], [110.362363, 28.453169], [110.362851, 28.452213], [110.364377, 28.452443], [110.365138, 28.45246], [110.366462, 28.452157], [110.369549, 28.451441], [110.37219, 28.450897], [110.372753, 28.450901], [110.373875, 28.451194], [110.373913, 28.451107], [110.374597, 28.451476]] },
]

// --- 甲烷监测点（相邻地下空间）---
const methanePoints = [
  { id: 'M1', name: '太常路CH4监测', type: 'methane', typeName: '甲烷监测点', lng: 110.362851, lat: 28.452213, address: '太常路北段地下管沟', methane: 28, status: 'alert', updateTime: '2026-06-13 15:23:45', code: 'CH4-001' },
  { id: 'M3', name: '滨江路CH4监测', type: 'methane', typeName: '甲烷监测点', lng: 110.381, lat: 28.443, address: '滨江路西段地下空间', methane: 35, status: 'alert', updateTime: '2026-06-13 15:21:15', code: 'CH4-003' },
]

// --- 温湿度监测点 ---
const tempHumidityPoints = [
  { id: 'TH1', name: '城东温湿度', type: 'temperature', typeName: '温湿度监测点', lng: 110.407, lat: 28.445, address: '城东大道管沟监测点', temperature: 25.8, humidity: 62, status: 'online', updateTime: '2026-06-13 15:25:00', code: 'TH-001' },
  { id: 'TH2', name: '古城路温湿度', type: 'temperature', typeName: '温湿度监测点', lng: 110.372, lat: 28.441, address: '古城路中段管沟', temperature: 27.2, humidity: 58, status: 'online', updateTime: '2026-06-13 15:23:30', code: 'TH-002' },
]

// --- 压力监测点 ---
const pressurePoints = [
  { id: 'PR1', name: '太常路压力', type: 'pressure', typeName: '压力监测点', lng: 110.402, lat: 28.454, address: '太常路与迎宾路交叉口', pressure: 385, status: 'online', updateTime: '2026-06-13 15:32:18', code: 'PR-001' },
  { id: 'PR2', name: '建设路压力', type: 'pressure', typeName: '压力监测点', lng: 110.385, lat: 28.436, address: '建设路中段阀门井', pressure: 432, status: 'danger', updateTime: '2026-06-13 15:31:45', code: 'PR-002' },
  { id: 'PR3', name: '酉水大桥压力', type: 'pressure', typeName: '压力监测点', lng: 110.37219, lat: 28.450897, address: '学府路北段调压柜', pressure: 142, status: 'warning', updateTime: '2026-06-13 15:29:58', code: 'PR-003' },
]

// --- 流量监测点 ---
const flowPoints = [
  { id: 'F2', name: '城东流量', type: 'flow', typeName: '流量监测点', lng: 110.409, lat: 28.452, address: '城东大道计量站', flow: 2620, status: 'danger', updateTime: '2026-06-13 15:31:45', code: 'FL-002' },
]

// --- 燃气场站 ---
const stations = [
  { id: 'S1', name: '龙兴路门站', type: 'gateStation', typeName: '门站', lng: 110.401084, lat: 28.433876, address: '龙兴路', status: 'online', updateTime: '2026-06-13 15:35:00', code: 'GS-001' },
  { id: 'S2', name: '龙兴路调压站', type: 'regulatorStation', typeName: '调压站', lng: 110.394299, lat: 28.434538, address: '龙兴路中段', status: 'online', updateTime: '2026-06-13 15:30:00', code: 'RS-001' },
]

// ==================== 统计数据 ====================
const pipelineCount = computed(() => 48.6)
const monitorCount = computed(() => methanePoints.length + tempHumidityPoints.length + pressurePoints.length + flowPoints.length)
const stationCount = computed(() => stations.length)
const alertCount = computed(() => {
  const all = [...methanePoints, ...tempHumidityPoints, ...pressurePoints, ...flowPoints, ...stations]
  return all.filter(f => f.status === 'alert' || f.status === 'danger').length
})
const avgPressure = computed(() => {
  const online = pressurePoints.filter(p => p.status !== 'offline' && p.pressure > 0)
  return online.length ? Math.round(online.reduce((a, b) => a + b.pressure, 0) / online.length) : '--'
})
const avgFlow = computed(() => {
  const online = flowPoints.filter(f => f.status !== 'offline' && f.flow > 0)
  return online.length ? Math.round(online.reduce((a, b) => a + b.flow, 0) / online.length) : '--'
})
const maxMethane = computed(() => Math.max(...methanePoints.map(m => m.methane)))
const onlineRate = computed(() => {
  const allDevices = [...methanePoints, ...tempHumidityPoints, ...pressurePoints, ...flowPoints, ...stations]
  const online = allDevices.filter(d => d.status === 'online').length
  return Math.round((online / allDevices.length) * 100)
})

// 搜索过滤
const filteredFeatures = computed(() => {
  const all = [
    ...methanePoints.map(p => ({ ...p, category: 'methane' })),
    ...tempHumidityPoints.map(p => ({ ...p, category: 'temperature' })),
    ...pressurePoints.map(p => ({ ...p, category: 'pressure' })),
    ...flowPoints.map(p => ({ ...p, category: 'flow' })),
    ...stations.map(p => ({ ...p, category: 'station' }))
  ]
  if (!searchKeyword.value) return all
  const kw = searchKeyword.value.toLowerCase()
  return all.filter(f => f.name.toLowerCase().includes(kw) || f.address.toLowerCase().includes(kw))
})

function onSearch() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  const found = filteredFeatures.value[0]
  if (found) {
    const [sfLng, sfLat] = convertCoord(found.lng, found.lat)
    const pt = new BMapGL.Point(sfLng, sfLat)
    mapInstance.panTo(pt)
    openFeatureInfo(found)
  }
}

// ==================== 状态映射 ====================
function statusTagType(status) {
  const map = { online: 'success', warning: 'warning', danger: 'danger', alert: 'danger', offline: 'info' }
  return map[status] || 'info'
}
function statusLabel(status) {
  const map = { online: '在线', warning: '预警', danger: '告警', alert: '告警', offline: '离线' }
  return map[status] || status
}

// ==================== 地图交互 ====================
const currentLng = ref(MAP_CENTER.lng)
const currentLat = ref(MAP_CENTER.lat)
const currentFeature = ref(null)
const detailDrawerVisible = ref(false)

function zoomIn() {
  if (!mapInstance) return
  mapInstance.zoomIn()
}
function zoomOut() {
  if (!mapInstance) return
  mapInstance.zoomOut()
}
function fitBounds() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  const [fLng, fLat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
  mapInstance.centerAndZoom(new BMapGL.Point(fLng, fLat), MAP_DEFAULT_ZOOM)
  closeInfoWindow()
}
function refreshData() {
  // 重新渲染所有覆盖物
  clearAllOverlays()
  renderAllOverlays()
}

// ==================== 百度地图初始化 ====================
function waitForBMapGL() {
  if (typeof BMapGL !== 'undefined') { initMap(); return }
  let attempts = 0
  const timer = setInterval(() => {
    attempts++
    if (typeof BMapGL !== 'undefined') { clearInterval(timer); initMap(); return }
    if (attempts >= 50) { clearInterval(timer); mapError.value = '百度地图脚本加载超时，请刷新页面重试。' }
  }, 200)
}

function closeInfoWindow() {
  if (activeInfoWindow) {
    try { activeInfoWindow.close(); mapInstance.removeOverlay(activeInfoWindow) } catch (_) {}
    activeInfoWindow = null
  }
}

function initMap() {
  const el = document.getElementById('gasSafetyBaiduMap')
  if (!el) { mapError.value = '地图容器未找到。'; return }

  try {
    mapInstance = new BMapGL.Map('gasSafetyBaiduMap', { enableMapClick: true })
  } catch (e) {
    mapError.value = '百度地图初始化失败，请检查AK和网络连接。'
    return
  }

  const [mcLng, mcLat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
  mapInstance.centerAndZoom(new BMapGL.Point(mcLng, mcLat), MAP_DEFAULT_ZOOM)
  mapInstance.enableScrollWheelZoom(true)
  mapInstance.setMinZoom(12)
  mapInstance.setMaxZoom(18)

  // 鼠标移动更新坐标
  mapInstance.addEventListener('mousemove', (e) => {
    if (e && e.latlng) {
      currentLng.value = e.latlng.lng
      currentLat.value = e.latlng.lat
    }
  })

  // 点击空白关闭信息窗
  mapInstance.addEventListener('click', () => {
    closeInfoWindow()
  })

  renderAllOverlays()
}

// ==================== 覆盖物渲染 ====================
function clearAllOverlays() {
  closeInfoWindow()
  Object.values(overlayStore).forEach(arr => {
    arr.forEach(ov => { try { mapInstance.removeOverlay(ov) } catch (_) {} })
    arr.length = 0
  })
}

function getLayerKey(category) {
  const map = { methane: 'methane', temperature: 'temperature', pressure: 'pressure', flow: 'flow', gateStation: 'gateStation', regulatorStation: 'regulatorStation', lngStation: 'lngStation' }
  return map[category] || category
}

// 绘制管线
function renderPipelines() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  pipelines.forEach(pipe => {
    const pts = pipe.path.map(([lng, lat]) => {
      const [bdLng, bdLat] = convertCoord(lng, lat)
      return new BMapGL.Point(bdLng, bdLat)
    })
    const polyline = new BMapGL.Polyline(pts, {
      strokeColor: pipe.color,
      strokeWeight: pipe.width,
      strokeOpacity: 0.85
    })
    polyline.addEventListener('click', () => {
      closeInfoWindow()
      const html = `<div style="font-size:13px;line-height:1.8;"><b>${pipe.name}</b><br/>压力等级：${pipe.pressure}</div>`
      activeInfoWindow = new BMapGL.InfoWindow(html, { width: 200, height: 60 })
      const mid = Math.floor(pts.length / 2)
      mapInstance.openInfoWindow(activeInfoWindow, pts[mid])
    })
    mapInstance.addOverlay(polyline)
    overlayStore[pipe.type].push(polyline)
  })
}

// 绘制点位标记
function drawPointMarkers(points, category, color, size = 10, shape = 'circle', iconText = '') {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  const layerKey = getLayerKey(category)
  points.forEach(p => {
    const [bdLng, bdLat] = convertCoord(p.lng, p.lat)
    const pt = new BMapGL.Point(bdLng, bdLat)
    let displayColor = color
    if (p.status === 'alert' || p.status === 'danger') displayColor = '#f56c6c'
    if (p.status === 'warning') displayColor = '#e6a23c'
    if (p.status === 'offline') displayColor = '#909399'

    const r = size
    const html = `<div style="width:${r*2}px;height:${r*2}px;border-radius:${shape === 'circle' ? '50%' : shape === 'rect' ? '3px' : '0'};background:${displayColor};border:2px solid #fff;box-shadow:0 2px 6px rgba(0,0,0,0.3);cursor:pointer;display:flex;align-items:center;justify-content:center;color:#fff;font-size:10px;font-weight:bold;">${iconText}</div>`

    const label = new BMapGL.Label(html, {
      position: pt,
      offset: new BMapGL.Size(-r, -r)
    })
    label.setStyle({ border: 'none', background: 'transparent', padding: '0' })

    label.addEventListener('click', (e) => {
      if (e && e.domEvent) e.domEvent.stopPropagation()
      openFeatureInfo(p)
    })

    mapInstance.addOverlay(label)
    overlayStore[layerKey].push(label)

  /*  // 告警点额外显示脉冲圈
    if ((p.status === 'alert' || p.status === 'danger') && layers.alert) {
      const pulseHtml = `<div style="width:${r*3}px;height:${r*3}px;border-radius:50%;background:rgba(245,108,108,0.3);border:2px solid rgba(245,108,108,0.6);animation:pulse 1.5s infinite;"></div>`
      const pulseLabel = new BMapGL.Label(pulseHtml, {
        position: pt,
        offset: new BMapGL.Size(-r * 1.5, -r * 1.5)
      })
      pulseLabel.setStyle({ border: 'none', background: 'transparent', padding: '0' })
      mapInstance.addOverlay(pulseLabel)
      overlayStore.alert.push(pulseLabel)
    }*/
  })
}

function renderAllOverlays() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  clearAllOverlays()

  // 管线
  if (layers.highPressure || layers.mediumPressure || layers.lowPressure) {
    renderPipelines()
  }

  // 点位
  drawPointMarkers(methanePoints, 'methane', '#9b59b6', 10, 'circle', 'CH4')
  drawPointMarkers(tempHumidityPoints, 'temperature', '#2db7f5', 9, 'circle', '温')
  drawPointMarkers(pressurePoints, 'pressure', '#409eff', 9, 'rect', 'P')
  drawPointMarkers(flowPoints, 'flow', '#67c23a', 9, 'rect', 'F')
  drawPointMarkers(stations.filter(s => s.type === 'gateStation'), 'gateStation', '#e6a23c', 13, 'circle', '门')
  drawPointMarkers(stations.filter(s => s.type === 'regulatorStation'), 'regulatorStation', '#e6a23c', 12, 'circle', '调')
  drawPointMarkers(stations.filter(s => s.type === 'lngStation'), 'lngStation', '#e6a23c', 14, 'circle', 'LNG')

  applyLayerVisibility()
}

// ==================== 图层显隐 ====================
function applyLayerVisibility() {
  Object.entries(overlayStore).forEach(([key, overlays]) => {
    const visible = layers[key]
    overlays.forEach(ov => {
      try {
        if (visible) { ov.show() } else { ov.hide() }
      } catch (_) {}
    })
  })

  // 告警脉冲圈只在告警图层开启时显示
  overlayStore.alert.forEach(ov => {
    try {
      if (layers.alert) { ov.show() } else { ov.hide() }
    } catch (_) {}
  })
}

function onLayerChange() {
  if (!mapInstance) return
  applyLayerVisibility()
}

// ==================== 详情交互 ====================
function openFeatureInfo(feature) {
  closeInfoWindow()
  currentFeature.value = feature
  detailDrawerVisible.value = true

  const [bfLng, bfLat] = convertCoord(feature.lng, feature.lat)
  const pt = new BMapGL.Point(bfLng, bfLat)
  let infoHtml = `<div style="font-size:13px;line-height:1.8;max-width:240px;"><b>${feature.name}</b><br/>类型：${feature.typeName}<br/>`
  if (feature.pressure) infoHtml += `压力：${feature.pressure} kPa<br/>`
  if (feature.flow) infoHtml += `流量：${feature.flow} Nm³/h<br/>`
  if (feature.methane) infoHtml += `甲烷浓度：${feature.methane} ppm<br/>`
  if (feature.temperature) infoHtml += `温度：${feature.temperature} °C<br/>`
  if (feature.humidity) infoHtml += `湿度：${feature.humidity} %RH<br/>`
  infoHtml += `状态：${statusLabel(feature.status)}<br/>地址：${feature.address}</div>`

  activeInfoWindow = new BMapGL.InfoWindow(infoHtml, { width: 240, height: 150 })
  mapInstance.openInfoWindow(activeInfoWindow, pt)
  mapInstance.panTo(pt)
}

onMounted(() => {
  nextTick(() => {
    waitForBMapGL()
  })
})

onBeforeUnmount(() => {
  try { mapInstance?.destroy() } catch (_) {}
  mapInstance = null
})
</script>

<style scoped>
.gas-safety-gis {
  background: #f0f2f6;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.page-header {
  background: #fff;
  padding: 12px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e9ecef;
  flex-shrink: 0;
}
.header-left { display: flex; align-items: center; gap: 20px; }
.header-left .title { font-size: 1.25rem; font-weight: 600; color: #1f2d3d; }
.stats-badge { display: flex; gap: 20px; }
.stat-item { font-size: 13px; display: flex; align-items: center; gap: 6px; }
.stat-item.critical { color: #f56c6c; }
.dot { width: 8px; height: 8px; border-radius: 50%; }
.pipeline-dot { background: #f56c6c; }
.monitor-dot { background: #9b59b6; }
.station-dot { background: #e6a23c; }
.alert-dot { background: #f56c6c; }
.header-right { display: flex; gap: 12px; }

.main-layout {
  display: flex;
  flex: 1;
  overflow: hidden;
  padding: 12px;
  gap: 12px;
}

/* 左侧面板 */
.layer-panel {
  width: 260px;
  background: #fff;
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  flex-shrink: 0;
}
.layer-header { font-weight: 600; font-size: 16px; }
.layer-group { margin-bottom: 12px; }
.group-title { font-weight: 500; margin-bottom: 8px; font-size: 13px; color: #606266; }
.layer-group :deep(.el-checkbox) { display: block; margin-left: 8px; margin-bottom: 6px; }
.legend-panel { border-top: 1px solid #e9ecef; padding-top: 12px; }
.legend-title { font-weight: 600; margin-bottom: 8px; }
.legend-line { display: inline-block; width: 30px; height: 3px; margin-right: 8px; vertical-align: middle; }
.legend-line.high { background: #f56c6c; }
.legend-line.medium { background: #e6a23c; }
.legend-line.low { background: #67c23a; }
.legend-point { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; vertical-align: middle; }
.legend-point.temp { background: #2db7f5; }
.legend-point.methane { background: #9b59b6; }
.legend-point.pressure { background: #409eff; border-radius: 2px; }
.legend-point.flow { background: #67c23a; border-radius: 2px; }
.legend-point.station { background: #e6a23c; }
.legend-point.alert-l { background: #f56c6c; }
.stats-panel { background: #f5f7fa; border-radius: 8px; padding: 12px; }
.stats-title { font-weight: 600; margin-bottom: 8px; }
.stats-row { display: flex; justify-content: space-between; font-size: 13px; margin: 6px 0; }
.stats-row .value { font-weight: 600; }
.alert-value { color: #f56c6c; }

/* 右侧GIS */
.gis-container {
  flex: 1;
  background: #fff;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.map-toolbar {
  padding: 10px 16px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.coordinate-info { font-size: 12px; color: #909399; }
.map-wrapper { flex: 1; position: relative; overflow: hidden; }
.map-div { width: 100%; height: 100%; }
.map-error {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  color: #f56c6c; font-size: 14px; background: #fff; padding: 16px 24px;
  border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1);
}
.feature-detail { padding: 8px; }
</style>
