<!--监测设备 GIS 一张图-->
<template>
  <div class="monitor-device-gis">
    <!-- 页面头部 -->
    <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 smart-dot"></i>智能井盖 {{ smartCount }}</span>
          <span class="stat-item"><i class="dot water-dot"></i>水位计 {{ waterCount }}</span>
          <span class="stat-item"><i class="dot gas-dot"></i>气体监测 {{ gasCount }}</span>
          <span class="stat-item"><i class="dot vibration-dot"></i>震动监测 {{ vibrationCount }}</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="smart">智能井盖</el-checkbox>
              <el-checkbox value="standard">普通井盖监测</el-checkbox>
              <el-checkbox value="explosion">防爆井盖</el-checkbox>
            </div>
            <div class="layer-group">
              <div class="group-title">环境监测设备</div>
              <el-checkbox value="water">水位计</el-checkbox>
              <el-checkbox value="gas">气体监测仪</el-checkbox>
              <el-checkbox value="vibration">震动传感器</el-checkbox>
            </div>
            <div class="layer-group">
              <div class="group-title">设备状态筛选</div>
              <el-checkbox value="online">在线设备</el-checkbox>
              <el-checkbox value="offline">离线设备</el-checkbox>
              <el-checkbox value="alert">告警设备</el-checkbox>
            </div>
          </el-checkbox-group>
        </div>

        <div class="legend-panel">
          <div class="legend-title">图例说明</div>
          <div><span class="legend-marker smart"></span> 智能井盖(正常)</div>
          <div><span class="legend-marker smart-alert"></span> 智能井盖(告警)</div>
          <div><span class="legend-marker water"></span> 水位计</div>
          <div><span class="legend-marker gas"></span> 气体监测仪</div>
          <div><span class="legend-marker vibration"></span> 震动传感器</div>
          <div><span class="legend-marker offline"></span> 离线设备</div>
        </div>

        <div class="info-stats">
          <div class="info-title">测绘数据统计</div>
          <div>设备总数: {{ totalDevices }}</div>
          <div>在线设备: {{ onlineCount }}</div>
          <div>告警设备: {{ alertCount }}</div>
          <div>覆盖区域: 8个街道</div>
        </div>

        <!-- 快速定位 -->
        <div class="quick-locate">
          <div class="info-title">快速定位</div>
          <el-select v-model="quickLocation" placeholder="选择区域" size="small" @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>

      <!-- 右侧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">
            <el-tag size="small" type="info">在线率: {{ onlineRate }}%</el-tag>
            <span class="coords">当前坐标: {{ currentLng.toFixed(4) }}, {{ currentLat.toFixed(4) }}</span>
          </div>
        </div>
        <div class="map-wrapper" ref="mapContainer">
          <canvas id="monitorMapCanvas" ref="canvasRef" @click="onMapClick" @mousemove="updateCoordinates"></canvas>
          <!-- 悬浮信息卡 -->
          <div v-if="hoverDevice" class="hover-card" :style="{ top: hoverY + 'px', left: hoverX + 'px' }">
            <div class="hover-title">{{ hoverDevice.name }}</div>
            <div>类型: {{ hoverDevice.typeName }}</div>
            <div>状态: {{ hoverDevice.status === 'online' ? '在线' : hoverDevice.status === 'alert' ? '告警' : '离线' }}</div>
            <div v-if="hoverDevice.battery">电量: {{ hoverDevice.battery }}%</div>
            <div v-if="hoverDevice.value">实时值: {{ hoverDevice.value }}</div>
            <div>位置: {{ hoverDevice.address }}</div>
          </div>
        </div>

        <!-- 右侧详情抽屉 -->
        <el-drawer v-model="detailDrawerVisible" :title="`设备详情 - ${currentDevice?.name}`" size="450px" direction="rtl">
          <div v-if="currentDevice" class="device-detail">
            <el-descriptions :column="1" border>
              <el-descriptions-item label="设备编号">{{ currentDevice.code }}</el-descriptions-item>
              <el-descriptions-item label="设备名称">{{ currentDevice.name }}</el-descriptions-item>
              <el-descriptions-item label="设备类型">{{ currentDevice.typeName }}</el-descriptions-item>
              <el-descriptions-item label="设备型号">{{ currentDevice.model || 'WATCHMAN-S2' }}</el-descriptions-item>
              <el-descriptions-item label="当前状态">
                <el-tag :type="currentDevice.status === 'online' ? 'success' : currentDevice.status === 'alert' ? 'danger' : 'info'">
                  {{ currentDevice.status === 'online' ? '在线' : currentDevice.status === 'alert' ? '告警' : '离线' }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="详细地址">{{ currentDevice.address }}</el-descriptions-item>
              <el-descriptions-item label="经纬度">{{ currentDevice.lng }}, {{ currentDevice.lat }}</el-descriptions-item>
              <el-descriptions-item label="所属区域">{{ currentDevice.district || '浦东新区' }}</el-descriptions-item>
              <el-descriptions-item label="权属单位">{{ currentDevice.ownerUnit || '市政工程管理处' }}</el-descriptions-item>
              <el-descriptions-item label="安装日期">{{ currentDevice.installDate || '2024-03-15' }}</el-descriptions-item>
              <el-descriptions-item v-if="currentDevice.battery" label="电池电量">{{ currentDevice.battery }}%</el-descriptions-item>
              <el-descriptions-item v-if="currentDevice.signal" label="信号强度">{{ currentDevice.signal }}%</el-descriptions-item>
              <el-descriptions-item v-if="currentDevice.value" label="实时监测值">{{ currentDevice.value }}</el-descriptions-item>
              <el-descriptions-item v-if="currentDevice.threshold" label="报警阈值">{{ currentDevice.threshold }}</el-descriptions-item>
            </el-descriptions>
            <div class="history-section" v-if="currentDevice.records?.length">
              <div class="sub-title">历史告警记录</div>
              <el-timeline>
                <el-timeline-item v-for="record in currentDevice.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(['smart', 'water', 'gas', 'vibration', 'online'])

// --- 模拟监测设备数据 ---
const monitorDevices = ref([
  // 智能井盖
  { id: 1, code: 'SM-1001', name: '人民路智能井盖', type: 'smart', typeName: '智能井盖', lng: 121.487, lat: 31.249, address: '人民路与解放路口东50m', district: '浦东新区', status: 'online', battery: 87, signal: 92, value: '倾斜2.3°', threshold: '8°', ownerUnit: '市政工程管理处', installDate: '2024-03-15', records: [] },
  { id: 2, code: 'SM-1002', name: '世纪大道智能井盖', type: 'smart', typeName: '智能井盖', lng: 121.505, lat: 31.235, address: '世纪大道福山路口', district: '浦东新区', status: 'alert', battery: 34, signal: 45, value: '倾斜12.5°', threshold: '8°', ownerUnit: '市政工程管理处', installDate: '2024-01-20', records: [{ id: 1, time: '2025-04-02 14:23:15', type: 'danger', content: '倾斜角度超过阈值' }] },
  { id: 3, code: 'SM-1003', name: '张杨路智能井盖', type: 'smart', typeName: '智能井盖', lng: 121.52, lat: 31.242, address: '张杨路松林路口', district: '浦东新区', status: 'online', battery: 92, signal: 88, value: '倾斜0.5°', threshold: '8°', ownerUnit: '市政工程管理处', installDate: '2024-05-10', records: [] },
  { id: 4, code: 'SM-1004', name: '龙阳路智能井盖', type: 'smart', typeName: '智能井盖', lng: 121.51, lat: 31.215, address: '龙阳路白杨路口', district: '浦东新区', status: 'offline', battery: 0, signal: 0, value: '离线', threshold: '8°', ownerUnit: '市政工程管理处', installDate: '2023-11-08', records: [] },
  // 防爆井盖
  { id: 5, code: 'EX-2001', name: '滨江路防爆井盖', type: 'explosion', typeName: '防爆井盖', lng: 121.502, lat: 31.238, address: '滨江路化工园区南门', district: '浦东新区', status: 'alert', battery: 28, signal: 42, value: '水位62cm', threshold: '40cm', ownerUnit: '水务集团', installDate: '2024-06-20', records: [{ id: 1, time: '2025-04-02 13:55:02', type: 'danger', content: '水位超限告警' }] },
  // 水位计
  { id: 6, code: 'WT-3001', name: '浦东南路水位计', type: 'water', typeName: '水位计', lng: 121.49, lat: 31.23, address: '浦东南路400号', district: '浦东新区', status: 'online', battery: 76, signal: 85, value: '水位28cm', threshold: '50cm', ownerUnit: '水务集团', installDate: '2024-02-18', records: [] },
  { id: 7, code: 'WT-3002', name: '东方路水位计', type: 'water', typeName: '水位计', lng: 121.53, lat: 31.248, address: '东方路蓝村路口', district: '浦东新区', status: 'alert', battery: 52, signal: 63, value: '水位58cm', threshold: '50cm', ownerUnit: '水务集团', installDate: '2024-03-01', records: [{ id: 1, time: '2025-04-02 10:15:22', type: 'warning', content: '水位接近阈值' }] },
  // 气体监测仪
  { id: 8, code: 'GS-4001', name: '石化区气体监测仪', type: 'gas', typeName: '气体监测仪', lng: 121.524, lat: 31.239, address: '石化大道南侧', district: '浦东新区', status: 'alert', battery: 45, signal: 55, value: 'H₂S 28ppm', threshold: '15ppm', ownerUnit: '生态环境局', installDate: '2024-07-15', records: [{ id: 1, time: '2025-04-02 09:30:00', type: 'danger', content: '气体浓度超标' }] },
  { id: 9, code: 'GS-4002', name: '高新区气体监测仪', type: 'gas', typeName: '气体监测仪', lng: 121.512, lat: 31.242, address: '高新大道云计算中心旁', district: '浦东新区', status: 'online', battery: 88, signal: 94, value: 'CH₄ 2.5ppm', threshold: '10ppm', ownerUnit: '生态环境局', installDate: '2024-08-10', records: [] },
  // 震动传感器
  { id: 10, code: 'VB-5001', name: '古城街震动传感器', type: 'vibration', typeName: '震动传感器', lng: 121.478, lat: 31.258, address: '古城街北段树下', district: '浦东新区', status: 'alert', battery: 62, signal: 71, value: '震动112mg', threshold: '80mg', ownerUnit: '市政设施管理处', installDate: '2024-04-22', records: [{ id: 1, time: '2025-04-02 12:10:33', type: 'warning', content: '异常震动检测' }] },
  { id: 11, code: 'VB-5002', name: '南港路震动传感器', type: 'vibration', typeName: '震动传感器', lng: 121.495, lat: 31.228, address: '南港路旧车站段', district: '浦东新区', status: 'online', battery: 94, signal: 90, value: '震动15mg', threshold: '80mg', ownerUnit: '市政设施管理处', installDate: '2024-05-05', records: [] },
  // 普通井盖监测
  { id: 12, code: 'ST-6001', name: '中山路普通井盖', type: 'standard', typeName: '普通井盖监测', lng: 121.488, lat: 31.252, address: '中山路与人民路口', district: '浦东新区', status: 'online', battery: 78, signal: 82, value: '正常', threshold: '', ownerUnit: '市政工程管理处', installDate: '2024-01-10', records: [] }
])

// 统计数据
const totalDevices = computed(() => monitorDevices.value.length)
const smartCount = computed(() => monitorDevices.value.filter(d => d.type === 'smart' || d.type === 'explosion' || d.type === 'standard').length)
const waterCount = computed(() => monitorDevices.value.filter(d => d.type === 'water').length)
const gasCount = computed(() => monitorDevices.value.filter(d => d.type === 'gas').length)
const vibrationCount = computed(() => monitorDevices.value.filter(d => d.type === 'vibration').length)
const onlineCount = computed(() => monitorDevices.value.filter(d => d.status === 'online').length)
const alertCount = computed(() => monitorDevices.value.filter(d => d.status === 'alert').length)
const onlineRate = computed(() => ((onlineCount.value / totalDevices.value) * 100).toFixed(1))

// 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 searchKeyword = ref('')
const quickLocation = ref('')
const currentLng = ref(121.505)
const currentLat = ref(31.235)
const hoverDevice = ref(null)
const hoverX = ref(0), hoverY = ref(0)
const currentDevice = ref(null)
const detailDrawerVisible = ref(false)

// 坐标转换
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('人民路', 200, 300)
  ctx.fillText('张杨路', 450, 280)
  ctx.fillText('龙阳路', 180, 370)
  ctx.fillText('东方路', 580, 200)
  ctx.fillText('滨江路', 400, 150)
}

// 获取设备显示样式
function getDeviceStyle(device) {
  // 状态筛选
  if (visibleLayers.value.includes('online') && device.status !== 'online') return null
  if (visibleLayers.value.includes('offline') && device.status !== 'offline') return null
  if (visibleLayers.value.includes('alert') && device.status !== 'alert') return null
  if (!visibleLayers.value.includes(device.type)) return null

  let color = '#67c23a'
  let size = 10
  let shape = 'circle'

  if (device.status === 'alert') {
    color = '#f56c6c'
    size = 14
  } else if (device.status === 'offline') {
    color = '#909399'
    size = 8
  }

  // 按类型区分
  if (device.type === 'smart' || device.type === 'explosion' || device.type === 'standard') {
    shape = 'circle'
    if (device.status !== 'alert') color = '#409eff'
  } else if (device.type === 'water') {
    shape = 'rect'
    if (device.status !== 'alert') color = '#3b82f6'
  } else if (device.type === 'gas') {
    shape = 'triangle'
    if (device.status !== 'alert') color = '#9b59b6'
  } else if (device.type === 'vibration') {
    shape = 'diamond'
    if (device.status !== 'alert') color = '#e6a23c'
  }

  return { color, size, shape }
}

// 绘制设备
function drawDevices() {
  monitorDevices.value.forEach(device => {
    const style = getDeviceStyle(device)
    if (!style) return

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

    // 绘制形状
    ctx.beginPath()
    if (style.shape === 'circle') {
      ctx.arc(x, y, style.size, 0, 2 * Math.PI)
    } else if (style.shape === 'rect') {
      ctx.fillRect(x - style.size/2, y - style.size/2, style.size, style.size)
    } else if (style.shape === 'triangle') {
      ctx.moveTo(x, y - style.size)
      ctx.lineTo(x + style.size, y + style.size/2)
      ctx.lineTo(x - style.size, y + style.size/2)
      ctx.closePath()
    } else if (style.shape === 'diamond') {
      ctx.moveTo(x, y - style.size)
      ctx.lineTo(x + style.size, y)
      ctx.lineTo(x, y + style.size)
      ctx.lineTo(x - style.size, y)
      ctx.closePath()
    }

    ctx.fillStyle = style.color
    ctx.fill()
    ctx.strokeStyle = '#fff'
    ctx.lineWidth = 1.5
    ctx.stroke()

    // 告警设备添加外圈闪烁效果
    if (device.status === 'alert') {
      ctx.beginPath()
      ctx.arc(x, y, style.size + 4, 0, 2 * Math.PI)
      ctx.fillStyle = 'rgba(245,108,108,0.3)'
      ctx.fill()
    }

    // 绘制小标签
    ctx.fillStyle = style.color
    ctx.font = 'bold 9px sans-serif'
    ctx.fillText(device.name.slice(0, 4), x - 12, y - 8)
  })
}

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()
  drawDevices()
}

// 地图操作
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 refreshMap() { renderMap() }

function locateArea() {
  const areas = {
    area1: { lng: 121.505, lat: 31.235, zoom: 1.5 },
    area2: { lng: 121.502, lat: 31.238, zoom: 1.8 },
    area3: { lng: 121.512, lat: 31.242, zoom: 1.5 },
    area4: { lng: 121.478, lat: 31.258, zoom: 1.5 }
  }
  const area = areas[quickLocation.value]
  if (area) {
    mapZoom = area.zoom
    // 计算偏移使中心点居中
    const center = worldToCanvas(area.lng, area.lat)
    offsetX = mapWidth/2 - center.x
    offsetY = mapHeight/2 - center.y
    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

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

  if (hit) {
    currentDevice.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

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

  if (hit) {
    hoverDevice.value = hit
    hoverX.value = e.clientX + 12
    hoverY.value = e.clientY - 40
  } else {
    hoverDevice.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>
.monitor-device-gis {
  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: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.smart-dot { background: #409eff; }
.water-dot { background: #3b82f6; }
.gas-dot { background: #9b59b6; }
.vibration-dot { background: #e6a23c; }
.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-marker { display: inline-block; width: 12px; height: 12px; margin-right: 8px; border-radius: 50%; vertical-align: middle; }
.legend-marker.smart { background: #409eff; border-radius: 50%; }
.legend-marker.smart-alert { background: #f56c6c; border-radius: 50%; box-shadow: 0 0 0 2px rgba(245,108,108,0.4); }
.legend-marker.water { background: #3b82f6; border-radius: 2px; }
.legend-marker.gas { background: #9b59b6; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 12px solid #9b59b6; background: none; }
.legend-marker.vibration { background: #e6a23c; transform: rotate(45deg); border-radius: 2px; }
.legend-marker.offline { background: #909399; }
.info-stats { background: #f5f7fa; border-radius: 8px; padding: 12px; font-size: 13px; }
.info-stats .info-title { font-weight: 600; margin-bottom: 8px; }
.quick-locate { border-top: 1px solid #e9ecef; padding-top: 12px; }

.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 { display: flex; gap: 16px; align-items: center; 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);
}
.device-detail { padding: 8px; }
.sub-title { font-weight: 600; margin: 16px 0 8px 0; }
</style>