<!-- 燃气管网风险评估 GIS 联动-->
<template>
  <div class="pipeline-risk-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 high"><i class="dot"></i>高风险 {{ highRiskCount }}</span>
          <span class="stat-item medium"><i class="dot"></i>中风险 {{ mediumRiskCount }}</span>
          <span class="stat-item low"><i class="dot"></i>低风险 {{ lowRiskCount }}</span>
        </div>
      </div>
      <div class="header-right">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索管段名称/编号"
          clearable
          :prefix-icon="Search"
          style="width: 220px"
        />
        <el-button type="primary" :icon="Location" @click="locateSearch">定位</el-button>
        <el-button :icon="Refresh" @click="refreshMap">刷新</el-button>
        <el-button :icon="FullScreen" @click="fitBounds">全图</el-button>
      </div>
    </div>

    <!-- 主内容区：左侧控制面板 + 右侧GIS地图 -->
    <div class="main-layout">
      <!-- 左侧控制面板 -->
      <div class="control-panel">
        <div class="panel-section">
          <div class="section-title">风险图层</div>
          <el-checkbox-group v-model="visibleLayers" @change="onLayerChange">
            <div class="layer-item">
              <el-checkbox value="high">高风险管段</el-checkbox>
              <span class="layer-badge high">●</span>
            </div>
            <div class="layer-item">
              <el-checkbox value="medium">中风险管段</el-checkbox>
              <span class="layer-badge medium">●</span>
            </div>
            <div class="layer-item">
              <el-checkbox value="low">低风险管段</el-checkbox>
              <span class="layer-badge low">●</span>
            </div>
            <div class="layer-item">
              <el-checkbox value="hazard">周边危险源</el-checkbox>
              <span class="layer-badge hazard">●</span>
            </div>
            <div class="layer-item">
              <el-checkbox value="target">防护目标</el-checkbox>
              <span class="layer-badge target">●</span>
            </div>
          </el-checkbox-group>
        </div>

        <div class="panel-section">
          <div class="section-title">风险筛选</div>
          <el-slider v-model="riskScoreRange" range :min="0" :max="100" :marks="riskMarks" @change="onScoreFilter" />
        </div>

        <div class="panel-section">
          <div class="section-title">快速定位</div>
          <el-select v-model="quickLocation" placeholder="选择区域" size="small" style="width: 100%" @change="locateArea">
            <el-option label="辰州路沿线" value="area1" />
            <el-option label="古城路沿线" value="area2" />
            <el-option label="建设路沿线" value="area3" />
            <el-option label="太常片区全貌" value="area4" />
          </el-select>
        </div>

        <div class="panel-section">
          <div class="section-title">风险统计</div>
          <div class="stats-list">
            <div class="stat-row"><span>高风险管段:</span><strong class="high-text">{{ highRiskCount }}</strong><span>段</span></div>
            <div class="stat-row"><span>中风险管段:</span><strong class="medium-text">{{ mediumRiskCount }}</strong><span>段</span></div>
            <div class="stat-row"><span>低风险管段:</span><strong class="low-text">{{ lowRiskCount }}</strong><span>段</span></div>
            <div class="stat-row"><span>平均风险评分:</span><strong>{{ avgRiskScore }}</strong><span>分</span></div>
            <div class="stat-row"><span>周边危险源:</span><strong class="high-text">{{ hazardCount }}</strong><span>处</span></div>
            <div class="stat-row"><span>防护目标:</span><strong class="medium-text">{{ targetCount }}</strong><span>处</span></div>
          </div>
        </div>

        <div class="panel-section">
          <div class="section-title">图例说明</div>
          <div class="legend-item"><span class="legend-line high-line"></span> 高风险管线 (≥70分)</div>
          <div class="legend-item"><span class="legend-line medium-line"></span> 中风险管线 (40-69分)</div>
          <div class="legend-item"><span class="legend-line low-line"></span> 低风险管线 (&lt;40分)</div>
          <div class="legend-item"><span class="legend-point hazard-point"></span> 周边危险源</div>
          <div class="legend-item"><span class="legend-point target-point"></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="riskAssessmentBaiduMap" class="map-div"></div>
          <div v-if="mapError" class="map-error">{{ mapError }}</div>
          <!-- 悬浮信息卡 -->
          <div v-if="hoverPipeline" class="hover-card" :style="{ top: hoverY + 'px', left: hoverX + 'px' }">
            <div class="hover-title">{{ hoverPipeline.name }}</div>
            <div>风险等级: {{ hoverPipeline.riskLevelName }}</div>
            <div>风险评分: {{ hoverPipeline.riskScore }}分</div>
            <div>管材: {{ hoverPipeline.material }}</div>
          </div>
        </div>

        <!-- 详情抽屉 -->
        <el-drawer v-model="detailDrawerVisible" :title="`管段详情 - ${currentPipeline?.name}`" size="520px" direction="rtl" @opened="onDrawerOpened">
          <div v-if="currentPipeline" class="pipeline-detail">
            <el-descriptions :column="1" border size="small">
              <el-descriptions-item label="管段名称">{{ currentPipeline.name }}</el-descriptions-item>
              <el-descriptions-item label="管段编号">{{ currentPipeline.code }}</el-descriptions-item>
              <el-descriptions-item label="风险等级">
                <el-tag :type="currentPipeline.riskLevel === 'high' ? 'danger' : currentPipeline.riskLevel === 'medium' ? 'warning' : 'success'" size="small">
                  {{ currentPipeline.riskLevelName }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="风险评分">{{ currentPipeline.riskScore }}分</el-descriptions-item>
              <el-descriptions-item label="管材材质">{{ currentPipeline.material }}</el-descriptions-item>
              <el-descriptions-item label="压力级别">{{ currentPipeline.pressureLevel }}</el-descriptions-item>
              <el-descriptions-item label="管径">{{ currentPipeline.diameter }}mm</el-descriptions-item>
              <el-descriptions-item label="长度">{{ currentPipeline.length }}km</el-descriptions-item>
              <el-descriptions-item label="埋设年代">{{ currentPipeline.buryYear }}</el-descriptions-item>
              <el-descriptions-item label="权属单位">{{ currentPipeline.owner }}</el-descriptions-item>
              <el-descriptions-item label="最近检测">{{ currentPipeline.lastInspection }}</el-descriptions-item>
            </el-descriptions>
            <div class="risk-causes">
              <div class="sub-title">主要风险因素</div>
              <ul>
                <li v-for="(cause, idx) in currentPipeline.riskCauses" :key="idx">{{ cause }}</li>
              </ul>
            </div>
            <div class="chart-section">
              <div class="sub-title">近6次风险评估趋势</div>
              <div ref="chartRef" class="trend-chart"></div>
            </div>
            <div class="action-buttons">
              <el-button type="primary" size="small" @click="viewDetailReport">查看详细报告</el-button>
              <el-button size="small" @click="locatePipeline">地图定位</el-button>
            </div>
          </div>
        </el-drawer>
      </div>
    </div>
  </div>
</template>

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

// ==================== 百度地图初始化 ====================
const MAP_CENTER = { lng: 110.386, lat: 28.445 }
const MAP_DEFAULT_ZOOM = 14

let mapInstance = null
const mapError = ref('')
const currentLng = ref(110.394)
const currentLat = ref(28.469)

const overlayStore = {
  high: [], medium: [], low: [], hazard: [], target: []
}

function waitForBMapGL() {
  return new Promise((resolve, reject) => {
    let attempts = 0
    const timer = setInterval(() => {
      attempts++
      if (window.BMapGL) { clearInterval(timer); resolve(window.BMapGL) }
      if (attempts > 150) { clearInterval(timer); reject(new Error('百度地图API加载超时')) }
    }, 200)
  })
}

function initMap() {
  const BMapGL = window.BMapGL
  const el = document.getElementById('riskAssessmentBaiduMap')
  if (!el) return
  mapInstance = new BMapGL.Map(el, { enableMapClick: true })
  const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
  mapInstance.centerAndZoom(new BMapGL.Point(clng, clat), MAP_DEFAULT_ZOOM)
  mapInstance.enableScrollWheelZoom(true)
  mapInstance.setMapStyleV2({ styleId: 'a0f4e6e6f9e7a6c5d8e7f7e7f7e7f7e5' })
  mapInstance.addEventListener('mousemove', (e) => {
    currentLng.value = e.latlng.lng
    currentLat.value = e.latlng.lat
  })
  renderAllOverlays()
}

// ==================== 沅陵县静态数据 ====================

function riskLevelName(level) {
  return level === 'high' ? '高风险' : level === 'medium' ? '中风险' : '低风险'
}

// 管线风险数据（8段）
const pipelines = ref([
  {
    id: 1, code: 'PL-YL-001', name: '燃气1', area: '燃气1管线',
    riskLevel: 'high', riskScore: 86.5, riskLevelName: '高风险',
    material: '钢管', pressureLevel: '高压 (1.6MPa)', diameter: 500, length: 3.8,
    buryYear: '2015年', owner: '燃气公司', lastInspection: '2026-03-15',
    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]],
    riskCauses: ['管道服役超过10年', '交通密集', '防腐层多处破损', '沿线施工活动'],
    trendData: [82.3, 83.1, 84.2, 85.0, 85.8, 86.5]
  },
  {
    id: 2, code: 'PL-YL-002', name: '燃气2', area: '燃气2管线',
    riskLevel: 'medium', riskScore: 64.3, riskLevelName: '中风险',
    material: 'PE管', pressureLevel: '中压 (0.4MPa)', diameter: 300, length: 3.2,
    buryYear: '2018年', owner: '燃气公司', lastInspection: '2026-02-10',
    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]],
    riskCauses: ['沿线有在建工程', '防腐层老化', '人流量大'],
    trendData: [60.1, 61.0, 62.1, 63.2, 63.8, 64.3]
  },
])

// 周边危险源
const hazardPoints = ref([
  { id: 'HZ1', name: '燃气1-D点危险源', type: '危险源', level: 'high', lng: 110.401084, lat: 28.433876, desc: '储配站', riskRadius: '500m' },
  { id: 'HZ2', name: '燃气2-B点危险源', type: '危险源', level: 'medium', lng: 110.372753, lat: 28.450901, desc: '计量调压站', riskRadius: '300m' },
])

const targetPoints = ref([
  { id: 'TG1', name: '燃气1-E点防护目标', type: '防护目标', level: 'high', lng: 110.394299, lat: 28.434538, desc: '学校，约2000人' },
  { id: 'TG2', name: '燃气2-A点防护目标', type: '防护目标', level: 'medium', lng: 110.362363, lat: 28.453169, desc: '医院' },
  { id: 'TG3', name: '燃气1-F点防护目标', type: '防护目标', level: 'low', lng: 110.374231, lat: 28.43655, desc: '公园' },
])

// 风险评分区间标记
const riskMarks = { 0: '0', 25: '25', 50: '50', 75: '75', 100: '100' }

// ==================== 图层 & 筛选 ====================
const visibleLayers = ref(['high', 'medium', 'low', 'hazard', 'target'])
const riskScoreRange = ref([0, 100])
const searchKeyword = ref('')
const quickLocation = ref('')

const filteredPipelines = computed(() => {
  let list = pipelines.value
  if (riskScoreRange.value) {
    list = list.filter(p => p.riskScore >= riskScoreRange.value[0] && p.riskScore <= riskScoreRange.value[1])
  }
  return list
})

// ==================== 统计 ====================
const highRiskCount = computed(() => pipelines.value.filter(p => p.riskLevel === 'high').length)
const mediumRiskCount = computed(() => pipelines.value.filter(p => p.riskLevel === 'medium').length)
const lowRiskCount = computed(() => pipelines.value.filter(p => p.riskLevel === 'low').length)
const avgRiskScore = computed(() => (pipelines.value.reduce((sum, p) => sum + p.riskScore, 0) / pipelines.value.length).toFixed(1))
const hazardCount = computed(() => hazardPoints.value.length)
const targetCount = computed(() => targetPoints.value.length)

// ==================== 交互状态 ====================
const hoverPipeline = ref(null)
const hoverX = ref(0)
const hoverY = ref(0)
const currentPipeline = ref(null)
const detailDrawerVisible = ref(false)

// ==================== 地图覆盖物渲染 ====================
function clearOverlays() {
  Object.values(overlayStore).forEach(arr => {
    arr.forEach(o => { try { mapInstance.removeOverlay(o) } catch {} })
    arr.length = 0
  })
}

function addToStore(layer, overlay) {
  if (overlayStore[layer]) overlayStore[layer].push(overlay)
}

function renderPipelines() {
  const BMapGL = window.BMapGL
  filteredPipelines.value.forEach(p => {
    const layerKey = p.riskLevel
    const points = p.path.map(c => { const [lng, lat] = convertCoord(c[0], c[1]); return new BMapGL.Point(lng, lat) })
    const color = p.riskLevel === 'high' ? '#f56c6c' : p.riskLevel === 'medium' ? '#e6a23c' : '#67c23a'
    const weight = p.riskLevel === 'high' ? 6 : p.riskLevel === 'medium' ? 5 : 4
    const polyline = new BMapGL.Polyline(points, {
      strokeColor: color, strokeWeight: weight, strokeOpacity: 0.8
    })
    mapInstance.addOverlay(polyline)
    addToStore(layerKey, polyline)

    // 点击事件
    polyline.addEventListener('click', () => {
      currentPipeline.value = p
      detailDrawerVisible.value = true
    })

    // hover 事件
    polyline.addEventListener('mouseover', () => {
      hoverPipeline.value = p
    })
    polyline.addEventListener('mouseout', () => {
      hoverPipeline.value = null
    })

    // 管线名称标签
    const mid = Math.floor(points.length / 2)
    const scoreLabel = new BMapGL.Label(p.riskScore + '分', {
      position: points[mid],
      offset: new BMapGL.Size(0, -16)
    })
    scoreLabel.setStyle({
      color: '#fff', fontSize: '11px', fontWeight: 'bold', padding: '2px 8px',
      backgroundColor: color, borderRadius: '10px', border: 'none', whiteSpace: 'nowrap'
    })
    mapInstance.addOverlay(scoreLabel)
    addToStore(layerKey, scoreLabel)

    const nameLabel = new BMapGL.Label(p.name, {
      position: points[mid],
      offset: new BMapGL.Size(0, 4)
    })
    nameLabel.setStyle({
      color: '#333', fontSize: '10px', padding: '1px 4px',
      backgroundColor: 'rgba(255,255,255,0.85)', borderRadius: '2px', border: 'none', whiteSpace: 'nowrap'
    })
    mapInstance.addOverlay(nameLabel)
    addToStore(layerKey, nameLabel)
  })
}

function renderHazardPoints() {
  const BMapGL = window.BMapGL
  hazardPoints.value.forEach(h => {
    const [hlng, hlat] = convertCoord(h.lng, h.lat)
    const pt = new BMapGL.Point(hlng, hlat)
    const label = new BMapGL.Label(h.name, {
      position: pt,
      offset: new BMapGL.Size(0, -18)
    })
    label.setStyle({
      color: '#fff', fontSize: '10px', padding: '3px 8px',
      backgroundColor: '#9b59b6', borderRadius: '3px', border: 'none', whiteSpace: 'nowrap'
    })
    mapInstance.addOverlay(label)
    addToStore('hazard', label)

    const marker = new BMapGL.Marker(pt)
    mapInstance.addOverlay(marker)
    addToStore('hazard', marker)

    marker.addEventListener('click', () => {
      currentPipeline.value = {
        name: h.name, code: h.id, riskLevelName: h.type,
        riskLevel: h.level, riskScore: '—', material: '—',
        pressureLevel: '—', diameter: '—', length: '—',
        buryYear: '—', owner: '—', lastInspection: '—',
        riskCauses: [h.desc, `影响半径: ${h.riskRadius}`],
        trendData: null
      }
      detailDrawerVisible.value = true
    })
  })
}

function renderTargetPoints() {
  const BMapGL = window.BMapGL
  targetPoints.value.forEach(t => {
    const [tlng, tlat] = convertCoord(t.lng, t.lat)
    const pt = new BMapGL.Point(tlng, tlat)
    const label = new BMapGL.Label(t.name, {
      position: pt,
      offset: new BMapGL.Size(0, -18)
    })
    label.setStyle({
      color: '#fff', fontSize: '10px', padding: '3px 8px',
      backgroundColor: '#409eff', borderRadius: '3px', border: 'none', whiteSpace: 'nowrap'
    })
    mapInstance.addOverlay(label)
    addToStore('target', label)

    const marker = new BMapGL.Marker(pt)
    mapInstance.addOverlay(marker)
    addToStore('target', marker)

    marker.addEventListener('click', () => {
      currentPipeline.value = {
        name: t.name, code: t.id, riskLevelName: t.type,
        riskLevel: t.level, riskScore: '—', material: '—',
        pressureLevel: '—', diameter: '—', length: '—',
        buryYear: '—', owner: '—', lastInspection: '—',
        riskCauses: [t.desc],
        trendData: null
      }
      detailDrawerVisible.value = true
    })
  })
}

function renderAllOverlays() {
  clearOverlays()
  renderPipelines()
  renderHazardPoints()
  renderTargetPoints()
  onLayerChange()
}

// ==================== 图层显隐 ====================
function onLayerChange() {
  const set = new Set(visibleLayers.value)
  Object.entries(overlayStore).forEach(([layer, overlays]) => {
    overlays.forEach(o => {
      try {
        set.has(layer) ? o.show() : o.hide()
      } catch {}
    })
  })
}

function onScoreFilter() {
  renderAllOverlays()
}

// ==================== 工具栏操作 ====================
function zoomIn() {
  if (mapInstance) mapInstance.zoomIn()
}

function zoomOut() {
  if (mapInstance) mapInstance.zoomOut()
}

function fitBounds() {
  if (mapInstance) {
    const BMapGL = window.BMapGL
    const [clng, clat] = convertCoord(MAP_CENTER.lng, MAP_CENTER.lat)
    mapInstance.centerAndZoom(new BMapGL.Point(clng, clat), MAP_DEFAULT_ZOOM)
  }
}

function refreshMap() {
  ElMessage.success('地图已刷新')
}

function locateArea() {
  const areas = {
    area1: { lng: 110.386, lat: 28.445, zoom: 15 },
    area2: { lng: 110.375, lat: 28.440, zoom: 15 },
    area3: { lng: 110.400, lat: 28.435, zoom: 15 },
    area4: { lng: 110.386, lat: 28.445, zoom: 13 }
  }
  const area = areas[quickLocation.value]
  if (area && mapInstance) {
    const BMapGL = window.BMapGL
    const [alng, alat] = convertCoord(area.lng, area.lat)
    mapInstance.centerAndZoom(new BMapGL.Point(alng, alat), area.zoom)
    ElMessage.success('已定位到: ' + quickLocation.value)
  }
}

function locateSearch() {
  if (!searchKeyword.value) return
  const found = pipelines.value.find(p =>
    p.name.includes(searchKeyword.value) || p.code.includes(searchKeyword.value)
  )
  if (found && mapInstance) {
    const BMapGL = window.BMapGL
    const mid = found.path[Math.floor(found.path.length / 2)]
    const [mlng, mlat] = convertCoord(mid[0], mid[1])
    mapInstance.centerAndZoom(new BMapGL.Point(mlng, mlat), 16)
    currentPipeline.value = found
    detailDrawerVisible.value = true
    ElMessage.success(`已定位到: ${found.name}`)
  } else {
    ElMessage.warning('未找到匹配的管段')
  }
}

function locatePipeline() {
  if (!mapInstance || !currentPipeline.value) return
  const BMapGL = window.BMapGL
  const item = currentPipeline.value
  let lng, lat
  if (item.path) {
    const mid = item.path[Math.floor(item.path.length / 2)]
    lng = mid[0]; lat = mid[1]
  } else if (item.lng) {
    lng = item.lng; lat = item.lat
  } else {
    return
  }
  const [llng, llat] = convertCoord(lng, lat)
  mapInstance.centerAndZoom(new BMapGL.Point(llng, llat), 16)
  detailDrawerVisible.value = false
}

function viewDetailReport() {
  ElMessage.info('查看详细风险评估报告（演示）')
}

// ==================== 趋势图 ====================
const chartRef = ref(null)
let chartInstance = null

function renderChart() {
  if (!chartRef.value || !currentPipeline.value?.trendData) return
  if (!chartInstance) {
    chartInstance = echarts.init(chartRef.value)
  }
  const data = currentPipeline.value.trendData
  chartInstance.setOption({
    tooltip: { trigger: 'axis' },
    grid: { left: 40, right: 20, top: 20, bottom: 30 },
    xAxis: {
      type: 'category',
      data: ['第1次', '第2次', '第3次', '第4次', '第5次', '第6次'],
      axisLabel: { fontSize: 10 }
    },
    yAxis: {
      type: 'value',
      name: '分',
      min: 0,
      max: 100,
      axisLabel: { fontSize: 10 }
    },
    series: [{
      data: data,
      type: 'line',
      smooth: true,
      lineStyle: { color: '#f56c6c', width: 2 },
      itemStyle: { color: '#f56c6c' },
      areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        { offset: 0, color: 'rgba(245,108,108,0.3)' },
        { offset: 1, color: 'rgba(245,108,108,0.05)' }
      ])}
    }]
  })
}

function onDrawerOpened() {
  nextTick(() => renderChart())
}

// ==================== 生命周期 ====================
watch(detailDrawerVisible, (val) => {
  if (!val) {
    currentPipeline.value = null
    chartInstance = null
  }
})

onMounted(async () => {
  window.addEventListener('mousemove', onWindowMouseMove)
  try {
    await waitForBMapGL()
    nextTick(() => initMap())
  } catch {
    mapError.value = '百度地图加载失败，请刷新页面重试'
  }
})

onBeforeUnmount(() => {
  window.removeEventListener('mousemove', onWindowMouseMove)
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  if (mapInstance) {
    try { mapInstance.destroy() } catch {}
    mapInstance = null
  }
})

// ==================== 全局鼠标移动（用于悬浮卡定位） ====================
function onWindowMouseMove(e) {
  if (hoverPipeline.value) {
    hoverX.value = e.clientX + 12
    hoverY.value = e.clientY - 40
  }
}
</script>

<style scoped>
.pipeline-risk-gis {
  background: #f0f2f6;
  height: 100%;
  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: #303133;
}

.stats-badge {
  display: flex;
  gap: 20px;
}

.stat-item {
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.stat-item.high { color: #f56c6c; }
.stat-item.medium { color: #e6a23c; }
.stat-item.low { color: #67c23a; }

.stat-item .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.stat-item.high .dot { background: #f56c6c; }
.stat-item.medium .dot { background: #e6a23c; }
.stat-item.low .dot { background: #67c23a; }

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

/* 主布局 */
.main-layout {
  display: flex;
  flex: 1;
  overflow: hidden;
  padding: 12px;
  gap: 12px;
}

/* 左侧控制面板 */
.control-panel {
  width: 260px;
  background: #fff;
  border-radius: 12px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  flex-shrink: 0;
}

.panel-section {
  border-bottom: 1px solid #ebeef5;
  padding-bottom: 16px;
}

.panel-section:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.section-title {
  font-weight: 600;
  margin-bottom: 10px;
  font-size: 14px;
  color: #303133;
}

.layer-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.layer-badge {
  font-size: 16px;
}

.layer-badge.high { color: #f56c6c; }
.layer-badge.medium { color: #e6a23c; }
.layer-badge.low { color: #67c23a; }
.layer-badge.hazard { color: #9b59b6; }
.layer-badge.target { color: #409eff; }

.stats-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
}

.high-text { color: #f56c6c; }
.medium-text { color: #e6a23c; }
.low-text { color: #67c23a; }

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12px;
}

.legend-line {
  width: 30px;
  height: 3px;
  display: inline-block;
  border-radius: 1px;
}

.legend-line.high-line { background: #f56c6c; }
.legend-line.medium-line { background: #e6a23c; }
.legend-line.low-line { background: #67c23a; }

.legend-point {
  width: 10px;
  height: 10px;
  display: inline-block;
  border-radius: 50%;
}

.legend-point.hazard-point { background: #9b59b6; }
.legend-point.target-point { background: #409eff; }

/* 右侧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 #ebeef5;
  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;
}

/* 悬浮信息卡 */
.hover-card {
  position: fixed;
  background: rgba(0, 0, 0, 0.82);
  color: #fff;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 12px;
  pointer-events: none;
  z-index: 2000;
  line-height: 1.6;
}

.hover-title {
  font-weight: 600;
  margin-bottom: 4px;
  font-size: 13px;
}

/* 详情抽屉 */
.pipeline-detail {
  padding: 4px;
}

.sub-title {
  font-weight: 600;
  margin: 16px 0 8px 0;
  font-size: 14px;
}

.risk-causes ul {
  margin: 0;
  padding-left: 20px;
}

.risk-causes li {
  margin: 6px 0;
  font-size: 13px;
  color: #606266;
}

.chart-section {
  margin-top: 8px;
}

.trend-chart {
  width: 100%;
  height: 200px;
}

.action-buttons {
  margin-top: 16px;
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}
</style>
