<!--燃气管网基础设施gis一张图-->
<template>
  <div class="gas-gis-dashboard">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <el-icon><MapLocation /></el-icon>
        <span class="title">燃气管网GIS一张图</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 point-dot"></i>燃气管点 {{ gasPointCount }}</span>
          <span class="stat-item"><i class="dot manhole-dot"></i>窨井 {{ manholeCount }}</span>
        </div>
      </div>
      <div class="header-right">
        <el-input
            v-model="searchKeyword"
            placeholder="搜索管点/井盖编号/位置"
            clearable
            :prefix-icon="Search"
            style="width: 240px"
            size="default"
        />
        <el-button type="primary" :icon="Refresh" @click="refreshMap">刷新</el-button>
        <el-button :icon="FullScreen" @click="fitBounds">全图</el-button>
      </div>
    </div>

    <!-- 主内容区：左侧图层控制 + 右侧GIS地图 -->
    <div class="main-layout">
      <!-- 左侧图层控制面板 -->
      <div class="layer-panel">
        <div class="layer-header">
          <el-icon></el-icon> 图层控制
        </div>
        <div class="layer-tree">
          <el-checkbox-group v-model="visibleLayers">
            <div class="layer-group">
              <div class="group-title">燃气管线</div>
              <el-checkbox value="highPressure">高压管线</el-checkbox>
              <el-checkbox value="mediumPressure">中压管线</el-checkbox>
              <el-checkbox value="lowPressure">低压管线</el-checkbox>
            </div>
            <div class="layer-group">
              <div class="group-title">燃气管点</div>
              <el-checkbox value="valve">阀门</el-checkbox>
              <el-checkbox value="regulator">调压器</el-checkbox>
              <el-checkbox value="meter">流量计</el-checkbox>
              <el-checkbox value="terminal">终端节点</el-checkbox>
            </div>
            <div class="layer-group">
              <div class="group-title">窨井设施</div>
              <el-checkbox value="manhole">窨井盖</el-checkbox>
              <el-checkbox value="inspection">检查井</el-checkbox>
            </div>
          </el-checkbox-group>
        </div>
        <div class="legend-panel">
          <div class="legend-title">图例说明</div>
          <div><span class="legend-line high"></span> 高压管线</div>
          <div><span class="legend-line medium"></span> 中压管线</div>
          <div><span class="legend-line low"></span> 低压管线</div>
          <div><span class="legend-point valve"></span> 阀门</div>
          <div><span class="legend-point regulator"></span> 调压器</div>
          <div><span class="legend-point meter"></span> 流量计</div>
          <div><span class="legend-point manhole"></span> 窨井</div>
        </div>
        <div class="info-stats">
          <div class="info-title">测绘数据统计</div>
          <div>管线总长: {{ pipelineTotalLength }} km</div>
          <div>管点总数: {{ gasPointCount }}</div>
          <div>窨井总数: {{ manholeCount }}</div>
          <div>覆盖面积: 156.8 km²</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="locateCurrent">定位</el-button>
          </el-button-group>
          <div class="coordinate-info">
            当前坐标: {{ currentLng.toFixed(4) }}, {{ currentLat.toFixed(4) }}
          </div>
        </div>
        <div class="map-wrapper" ref="mapContainer">
          <canvas id="gasMapCanvas" ref="canvasRef" @click="onMapClick" @mousemove="updateCoordinates"></canvas>
          <!-- 悬浮信息卡 -->
          <div v-if="hoverFeature" class="hover-card" :style="{ top: hoverY + 'px', left: hoverX + 'px' }">
            <div class="hover-title">{{ hoverFeature.name }}</div>
            <div>类型: {{ hoverFeature.typeName }}</div>
            <div v-if="hoverFeature.pressure">压力等级: {{ hoverFeature.pressure }}</div>
            <div v-if="hoverFeature.diameter">管径: {{ hoverFeature.diameter }}mm</div>
            <div v-if="hoverFeature.material">材质: {{ hoverFeature.material }}</div>
            <div>位置: {{ hoverFeature.address || hoverFeature.location }}</div>
          </div>
        </div>

        <!-- 右侧详情抽屉 -->
        <el-drawer v-model="detailDrawerVisible" :title="`设施详情 - ${currentFeature?.name}`" size="420px" 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.typeName }}</el-descriptions-item>
              <el-descriptions-item label="设施编号">{{ currentFeature.code || '—' }}</el-descriptions-item>
              <el-descriptions-item label="详细地址">{{ currentFeature.address || currentFeature.location }}</el-descriptions-item>
              <el-descriptions-item label="经纬度">{{ currentFeature.lng }}, {{ currentFeature.lat }}</el-descriptions-item>
              <el-descriptions-item label="所属区域">{{ currentFeature.district || '浦东新区' }}</el-descriptions-item>
              <el-descriptions-item label="权属单位">{{ currentFeature.ownerUnit || '燃气集团' }}</el-descriptions-item>
              <el-descriptions-item label="建设年份">{{ currentFeature.buildYear || '2020' }}</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.pressure" label="压力等级">{{ currentFeature.pressure }}</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.diameter" label="管径">{{ currentFeature.diameter }}mm</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.material" label="材质">{{ currentFeature.material }}</el-descriptions-item>
              <el-descriptions-item v-if="currentFeature.manholeType" label="井盖类型">{{ currentFeature.manholeType }}</el-descriptions-item>
            </el-descriptions>
            <div class="history-section" v-if="currentFeature.records?.length">
              <div class="sub-title">运维记录</div>
              <el-timeline>
                <el-timeline-item v-for="record in currentFeature.records" :key="record.id" :timestamp="record.time" :type="record.type">
                  {{ record.content }}
                </el-timeline-item>
              </el-timeline>
            </div>
          </div>
        </el-drawer>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { MapLocation, Search, Refresh, FullScreen, ZoomIn, ZoomOut, Location } from '@element-plus/icons-vue'

// 可见图层
const visibleLayers = ref(['highPressure', 'mediumPressure', 'lowPressure', 'valve', 'regulator', 'meter', 'manhole'])

// --- 模拟燃气管线数据 (线段)---
const pipelines = ref([
  { id: 'P1', name: '张杨路高压管线', type: 'highPressure', pressure: '高压', diameter: 500, material: '钢管', color: '#f56c6c', lineWidth: 4,
    coordinates: [[121.48, 31.24], [121.50, 31.245], [121.52, 31.24], [121.54, 31.235]] },
  { id: 'P2', name: '世纪大道中压管线', type: 'mediumPressure', pressure: '中压', diameter: 300, material: 'PE管', color: '#e6a23c', lineWidth: 3,
    coordinates: [[121.49, 31.23], [121.51, 31.228], [121.53, 31.225], [121.55, 31.22]] },
  { id: 'P3', name: '浦东南路低压管线', type: 'lowPressure', pressure: '低压', diameter: 150, material: 'PE管', color: '#67c23a', lineWidth: 2,
    coordinates: [[121.485, 31.255], [121.50, 31.25], [121.515, 31.248], [121.53, 31.245]] },
  { id: 'P4', name: '龙阳路中压管线', type: 'mediumPressure', pressure: '中压', diameter: 250, material: '钢管', color: '#e6a23c', lineWidth: 3,
    coordinates: [[121.47, 31.22], [121.49, 31.218], [121.51, 31.215], [121.53, 31.212]] }
])

// 模拟燃气管点数据
const gasPoints = ref([
  { id: 'V1', name: '世纪大道阀门井', type: 'valve', typeName: '阀门', code: 'VAL-001', lng: 121.505, lat: 31.235, address: '世纪大道与浦电路口', district: '浦东新区', ownerUnit: '燃气集团输配分公司', buildYear: '2019', records: [] },
  { id: 'V2', name: '张杨路调压站', type: 'regulator', typeName: '调压器', code: 'REG-012', lng: 121.52, lat: 31.242, address: '张杨路628号', district: '浦东新区', ownerUnit: '燃气集团', buildYear: '2018', records: [] },
  { id: 'V3', name: '龙阳路流量计', type: 'meter', typeName: '流量计', code: 'MET-005', lng: 121.51, lat: 31.215, address: '龙阳路2000号', district: '浦东新区', ownerUnit: '燃气集团', buildYear: '2020', records: [] },
  { id: 'V4', name: '浦电路终端节点', type: 'terminal', typeName: '终端节点', code: 'TER-023', lng: 121.49, lat: 31.23, address: '浦电路400号', district: '浦东新区', ownerUnit: '燃气集团', buildYear: '2021', records: [] },
  { id: 'V5', name: '东方路阀门', type: 'valve', typeName: '阀门', code: 'VAL-045', lng: 121.53, lat: 31.248, address: '东方路与浦建路口', district: '浦东新区', ownerUnit: '燃气集团', buildYear: '2019', records: [] }
])

// 模拟窨井数据
const manholes = ref([
  { id: 'M1', name: '世纪大道窨井', type: 'manhole', typeName: '窨井盖', code: 'MH-1001', lng: 121.50, lat: 31.238, address: '世纪大道福山路口', manholeType: '燃气检查井', depth: 2.5, diameter: 0.8, ownerUnit: '燃气集团', records: [] },
  { id: 'M2', name: '张杨路检查井', type: 'inspection', typeName: '检查井', code: 'IN-023', lng: 121.515, lat: 31.244, address: '张杨路松林路口', manholeType: '阀门井', depth: 3.0, diameter: 1.2, ownerUnit: '燃气集团', records: [] },
  { id: 'M3', name: '浦电路窨井', type: 'manhole', typeName: '窨井盖', code: 'MH-1005', lng: 121.49, lat: 31.228, address: '浦电路向城路口', manholeType: '燃气检查井', depth: 2.2, diameter: 0.7, ownerUnit: '燃气集团', records: [] },
  { id: 'M4', name: '龙阳路检查井', type: 'inspection', typeName: '检查井', code: 'IN-045', lng: 121.525, lat: 31.218, address: '龙阳路白杨路口', manholeType: '调压箱井', depth: 2.8, diameter: 1.0, ownerUnit: '燃气集团', records: [] },
  { id: 'M5', name: '东方路窨井', type: 'manhole', typeName: '窨井盖', code: 'MH-1012', lng: 121.535, lat: 31.25, address: '东方路蓝村路口', manholeType: '燃气检查井', depth: 2.3, diameter: 0.8, ownerUnit: '燃气集团', records: [] }
])

// 统计数据
const pipelineTotalLength = computed(() => {
  // 模拟计算管线总长
  return 48.6
})
const pipelineCount = computed(() => 48.6)
const gasPointCount = computed(() => gasPoints.value.length)
const manholeCount = computed(() => manholes.value.length)

// GIS画布相关
const canvasRef = ref(null)
const mapContainer = ref(null)
let ctx = null
let mapWidth = 0, mapHeight = 0
let mapZoom = 1
let offsetX = 0, offsetY = 0
let dragStart = null
let isDragging = false
const bounds = { minLng: 121.45, maxLng: 121.56, minLat: 31.20, maxLat: 31.27 }

// 交互状态
const currentLng = ref(121.505)
const currentLat = ref(31.235)
const hoverFeature = ref(null)
const hoverX = ref(0), hoverY = ref(0)
const currentFeature = ref(null)
const detailDrawerVisible = ref(false)
const searchKeyword = ref('')

// 坐标转换
function worldToCanvas(lng, lat) {
  const px = (lng - bounds.minLng) / (bounds.maxLng - bounds.minLng) * mapWidth
  const py = (1 - (lat - bounds.minLat) / (bounds.maxLat - bounds.minLat)) * mapHeight
  const cx = mapWidth / 2, cy = mapHeight / 2
  return { x: (px - cx) * mapZoom + cx + offsetX, y: (py - cy) * mapZoom + cy + offsetY }
}

function canvasToWorld(x, y) {
  const cx = mapWidth / 2, cy = mapHeight / 2
  const px = (x - cx - offsetX) / mapZoom + cx
  const py = (y - cy - offsetY) / mapZoom + cy
  const lng = bounds.minLng + (px / mapWidth) * (bounds.maxLng - bounds.minLng)
  const lat = bounds.maxLat - (py / mapHeight) * (bounds.maxLat - bounds.minLat)
  return { lng, lat }
}

// 绘制底图
function drawBaseMap() {
  if (!ctx) return
  ctx.fillStyle = '#eaf5e9'
  ctx.fillRect(0, 0, mapWidth, mapHeight)

  // 绘制网格
  ctx.strokeStyle = '#c8ddc4'
  ctx.lineWidth = 1
  for (let i = 0; i <= 10; i++) {
    const x = (i / 10) * mapWidth
    ctx.beginPath()
    ctx.moveTo(x, 0)
    ctx.lineTo(x, mapHeight)
    ctx.stroke()
    const y = (i / 10) * mapHeight
    ctx.beginPath()
    ctx.moveTo(0, y)
    ctx.lineTo(mapWidth, y)
    ctx.stroke()
  }

  // 绘制道路示意
  ctx.fillStyle = '#a8d0a6'
  ctx.font = '12px "Microsoft YaHei"'
  ctx.fillText('世纪大道', 350, 120)
  ctx.fillText('张杨路', 450, 280)
  ctx.fillText('龙阳路', 200, 370)
  ctx.fillText('东方路', 580, 200)
}

// 绘制管线
function drawPipelines() {
  pipelines.value.forEach(pipeline => {
    if (!visibleLayers.value.includes(pipeline.type)) return

    const points = pipeline.coordinates.map(coord => worldToCanvas(coord[0], coord[1]))
    if (points.length < 2) return

    ctx.beginPath()
    ctx.moveTo(points[0].x, points[0].y)
    for (let i = 1; i < points.length; i++) {
      ctx.lineTo(points[i].x, points[i].y)
    }
    ctx.strokeStyle = pipeline.color
    ctx.lineWidth = pipeline.lineWidth * mapZoom
    ctx.stroke()

    // 绘制管线名称标签
    const midIdx = Math.floor(points.length / 2)
    if (points[midIdx]) {
      ctx.fillStyle = '#333'
      ctx.font = '10px "Microsoft YaHei"'
      ctx.shadowBlur = 0
      ctx.fillText(pipeline.name.slice(0, 8), points[midIdx].x - 20, points[midIdx].y - 5)
    }
  })
}

// 绘制点要素
function drawPoints(points, type, iconColor, size = 8) {
  points.forEach(point => {
    if (!visibleLayers.value.includes(point.type)) return

    const { x, y } = worldToCanvas(point.lng, point.lat)
    if (x < -20 || x > mapWidth + 20 || y < -20 || y > mapHeight + 20) return

    ctx.beginPath()
    ctx.arc(x, y, size, 0, 2 * Math.PI)
    ctx.fillStyle = iconColor
    ctx.fill()
    ctx.strokeStyle = '#fff'
    ctx.lineWidth = 2
    ctx.stroke()

    // 绘制小标签
    ctx.fillStyle = iconColor
    ctx.font = 'bold 10px sans-serif'
    ctx.fillText(point.name.slice(0, 4), x - 10, y - 6)
  })
}

// 绘制窨井（方形）
function drawManholesPoints() {
  manholes.value.forEach(manhole => {
    if (!visibleLayers.value.includes(manhole.type)) return

    const { x, y } = worldToCanvas(manhole.lng, manhole.lat)
    if (x < -20 || x > mapWidth + 20 || y < -20 || y > mapHeight + 20) return

    ctx.fillStyle = '#8B4513'
    ctx.fillRect(x - 6, y - 6, 12, 12)
    ctx.strokeStyle = '#fff'
    ctx.lineWidth = 1.5
    ctx.strokeRect(x - 6, y - 6, 12, 12)
    ctx.fillStyle = '#8B4513'
    ctx.font = '9px sans-serif'
    ctx.fillText('井', x - 3, y + 3)
  })
}

function renderMap() {
  if (!canvasRef.value || !mapContainer.value) return
  const canvas = canvasRef.value
  mapWidth = mapContainer.value.clientWidth
  mapHeight = mapContainer.value.clientHeight
  canvas.width = mapWidth
  canvas.height = mapHeight
  ctx = canvas.getContext('2d')

  drawBaseMap()
  drawPipelines()
  drawPoints(gasPoints.value, 'point', '#409eff', 7)
  drawManholesPoints()
}

// 地图操作
function zoomIn() { mapZoom = Math.min(mapZoom + 0.15, 2.5); renderMap() }
function zoomOut() { mapZoom = Math.max(mapZoom - 0.15, 0.6); renderMap() }
function fitBounds() { mapZoom = 1; offsetX = 0; offsetY = 0; renderMap() }
function locateCurrent() { fitBounds() }
function refreshMap() { renderMap() }

// 坐标显示更新
function updateCoordinates(e) {
  const rect = canvasRef.value.getBoundingClientRect()
  const mouseX = (e.clientX - rect.left) * (mapWidth / rect.width)
  const mouseY = (e.clientY - rect.top) * (mapHeight / rect.height)
  const { lng, lat } = canvasToWorld(mouseX, mouseY)
  currentLng.value = lng
  currentLat.value = lat
}

// 点击事件 - 查询最近的管点或窨井
function onMapClick(e) {
  const rect = canvasRef.value.getBoundingClientRect()
  const mouseX = (e.clientX - rect.left) * (mapWidth / rect.width)
  const mouseY = (e.clientY - rect.top) * (mapHeight / rect.height)

  let minDist = 25
  let hit = null

  // 检查燃气管点
  gasPoints.value.forEach(point => {
    const { x, y } = worldToCanvas(point.lng, point.lat)
    const dist = Math.hypot(mouseX - x, mouseY - y)
    if (dist < minDist) {
      minDist = dist
      hit = point
    }
  })

  // 检查窨井
  manholes.value.forEach(manhole => {
    const { x, y } = worldToCanvas(manhole.lng, manhole.lat)
    const dist = Math.hypot(mouseX - x, mouseY - y)
    if (dist < minDist) {
      minDist = dist
      hit = { ...manhole, isManhole: true }
    }
  })

  if (hit) {
    currentFeature.value = hit
    detailDrawerVisible.value = true
  }
}

// 鼠标悬浮检测
function onCanvasMouseMove(e) {
  const rect = canvasRef.value.getBoundingClientRect()
  const mouseX = (e.clientX - rect.left) * (mapWidth / rect.width)
  const mouseY = (e.clientY - rect.top) * (mapHeight / rect.height)

  let minDist = 20
  let hit = null

  gasPoints.value.forEach(point => {
    const { x, y } = worldToCanvas(point.lng, point.lat)
    const dist = Math.hypot(mouseX - x, mouseY - y)
    if (dist < minDist) {
      minDist = dist
      hit = point
    }
  })

  manholes.value.forEach(manhole => {
    const { x, y } = worldToCanvas(manhole.lng, manhole.lat)
    const dist = Math.hypot(mouseX - x, mouseY - y)
    if (dist < minDist) {
      minDist = dist
      hit = { ...manhole, isManhole: true }
    }
  })

  if (hit) {
    hoverFeature.value = hit
    hoverX.value = e.clientX + 12
    hoverY.value = e.clientY - 40
  } else {
    hoverFeature.value = null
  }
}

// 拖动地图
function initDragEvents() {
  const canvas = canvasRef.value
  if (!canvas) return

  canvas.addEventListener('mousedown', (e) => {
    dragStart = { x: e.clientX, y: e.clientY, offsetX: offsetX, offsetY: offsetY }
    isDragging = true
    canvas.style.cursor = 'grabbing'
  })

  window.addEventListener('mousemove', (e) => {
    if (!isDragging) return
    const dx = e.clientX - dragStart.x
    const dy = e.clientY - dragStart.y
    offsetX = dragStart.offsetX + dx
    offsetY = dragStart.offsetY + dy
    renderMap()
  })

  window.addEventListener('mouseup', () => {
    isDragging = false
    if (canvasRef.value) canvasRef.value.style.cursor = 'crosshair'
  })
}

// 监听图层变化重新渲染
watch(() => visibleLayers.value, () => renderMap(), { deep: true })

onMounted(() => {
  nextTick(() => {
    renderMap()
    initDragEvents()
    window.addEventListener('resize', renderMap)
  })
})
onUnmounted(() => window.removeEventListener('resize', renderMap))
</script>

<style scoped>
.gas-gis-dashboard {
  background: #f0f2f6;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.page-header {
  background: white;
  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.3rem; font-weight: 600; color: #1f2d3d; }
.stats-badge { display: flex; gap: 16px; }
.stat-item { font-size: 13px; display: flex; align-items: center; gap: 6px; }
.dot { width: 12px; height: 12px; border-radius: 2px; display: inline-block; }
.pipeline-dot { background: #f56c6c; }
.point-dot { background: #409eff; border-radius: 50%; }
.manhole-dot { background: #8B4513; }
.header-right { display: flex; gap: 12px; }

.main-layout {
  display: flex;
  flex: 1;
  overflow: hidden;
  padding: 12px;
  gap: 12px;
}
.layer-panel {
  width: 260px;
  background: white;
  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; display: flex; align-items: center; gap: 8px; }
.layer-group { margin-bottom: 12px; }
.group-title { font-weight: 500; margin-bottom: 8px; font-size: 13px; color: #606266; }
.layer-group .el-checkbox { display: block; margin-left: 8px; margin-bottom: 6px; }
.legend-panel { border-top: 1px solid #e9ecef; padding-top: 12px; }
.legend-title { font-weight: 500; margin-bottom: 8px; font-size: 13px; }
.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; }
.legend-point.valve { background: #409eff; }
.legend-point.regulator { background: #e6a23c; }
.legend-point.meter { background: #67c23a; }
.legend-point.manhole { background: #8B4513; border-radius: 2px; }
.info-stats { background: #f5f7fa; border-radius: 8px; padding: 12px; font-size: 13px; }
.info-stats .info-title { font-weight: 600; margin-bottom: 8px; }

.gis-container {
  flex: 1;
  background: white;
  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;
}
.coordinate-info { font-size: 12px; color: #909399; }
.map-wrapper {
  flex: 1;
  position: relative;
  cursor: crosshair;
}
canvas { width: 100%; height: 100%; display: block; cursor: crosshair; }
.hover-card {
  position: fixed;
  background: rgba(0,0,0,0.8);
  color: white;
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 12px;
  pointer-events: none;
  z-index: 200;
  backdrop-filter: blur(4px);
}
.feature-detail { padding: 8px; }
.sub-title { font-weight: 600; margin: 16px 0 8px 0; }
</style>