<template>
  <div class="hazard-map-page">
    <!-- 顶部搜索栏 -->
    <div class="top-bar">
      <el-card shadow="never" class="search-card">
        <el-form :inline="true">
          <el-form-item label="隐患类型">
            <el-select v-model="filterType" placeholder="全部" clearable style="width:140px" @change="applyFilter">
              <el-option v-for="d in hazardTypeDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
            </el-select>
          </el-form-item>
          <el-form-item label="隐患等级">
            <el-select v-model="filterLevel" placeholder="全部" clearable style="width:140px" @change="applyFilter">
              <el-option v-for="d in hazardLevelDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
            </el-select>
          </el-form-item>
          <el-form-item label="整改状态">
            <el-select v-model="filterStatus" placeholder="全部" clearable style="width:140px" @change="onStatusFilterChange">
              <el-option v-for="d in hazardStatusDict" :key="d.dictValue" :label="d.dictLabel" :value="d.dictValue" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="applyFilter">查询</el-button>
            <el-button @click="resetFilter">重置</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 地图容器 -->
    <div id="hazardBaiduMap" class="map-container"></div>
    <div v-if="mapError" class="map-error">{{ mapError }}</div>

    <!-- 左侧隐患列表 -->
    <el-card class="left-list-card" shadow="hover">
      <template #header>
        <div class="left-header">
          <span>隐患列表</span>
          <span class="list-count">共 {{ filteredHazards.length }} 条</span>
        </div>
        <div class="status-tabs">
          <span class="status-tab" :class="{ active: listStatusTab === '' }" @click="switchStatusTab('')">全部</span>
          <span
            v-for="d in hazardStatusDict"
            :key="d.dictValue"
            class="status-tab"
            :class="{ active: listStatusTab === d.dictValue }"
            :style="listStatusTab === d.dictValue ? { color: statusTabColor(d.dictValue), borderBottomColor: statusTabColor(d.dictValue) } : {}"
            @click="switchStatusTab(d.dictValue)"
          >{{ d.dictLabel }}</span>
        </div>
      </template>
      <div class="list-body">
        <div
          v-for="h in filteredHazards"
          :key="h.hazardId"
          class="list-item"
          :class="{ active: activeHazardId === h.hazardId }"
          @click="focusHazard(h)"
        >
          <div class="item-top">
            <span class="dot" :style="{ background: levelColors[h.hazardLevel] }"></span>
            <span class="item-no">{{ h.hazardNo }}</span>
            <el-tag :type="statusTag(h.hazardStatus)" size="small">{{ getDictLabel(hazardStatusDict, h.hazardStatus) }}</el-tag>
          </div>
          <div class="item-info">
            <span>{{ getDictLabel(hazardTypeDict, h.hazardType) }}</span>
            <span class="divider">|</span>
            <span :style="{ color: levelColors[h.hazardLevel], fontWeight: '500' }">{{ getDictLabel(hazardLevelDict, h.hazardLevel) }}隐患</span>
          </div>
          <div class="item-addr">{{ h.remark || h.hazardDesc }}</div>
          <div class="item-time">{{ h.reportTime }}</div>
        </div>
        <el-empty v-if="filteredHazards.length === 0" description="暂无匹配隐患" :image-size="60" />
      </div>
    </el-card>

    <!-- 右侧图例 -->
    <el-card class="legend-card" shadow="hover">
      <template #header><span>图例说明</span></template>
      <div class="legend-items">
        <div class="legend-item" v-for="item in levelLegend" :key="item.value">
          <span class="legend-dot" :style="{ background: item.color }"></span>
          <span>{{ item.label }}隐患</span>
          <span class="legend-count">{{ item.count }}</span>
        </div>
      </div>
    </el-card>

    <!-- 隐患详情抽屉 -->
    <el-drawer v-model="detailVisible" title="隐患详情" size="420px">
      <template v-if="currentHazard">
        <el-descriptions :column="1" border size="small">
          <el-descriptions-item label="隐患编号">{{ currentHazard.hazardNo }}</el-descriptions-item>
          <el-descriptions-item label="隐患类型">{{ getDictLabel(hazardTypeDict, currentHazard.hazardType) }}</el-descriptions-item>
          <el-descriptions-item label="隐患等级">
            <el-tag :type="levelTag(currentHazard.hazardLevel)">{{ getDictLabel(hazardLevelDict, currentHazard.hazardLevel) }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="整改状态">{{ getDictLabel(hazardStatusDict, currentHazard.hazardStatus) }}</el-descriptions-item>
          <el-descriptions-item label="上报单位">{{ currentHazard.reportUnit }}</el-descriptions-item>
          <el-descriptions-item label="上报时间">{{ currentHazard.reportTime }}</el-descriptions-item>
          <el-descriptions-item label="隐患描述">{{ currentHazard.hazardDesc }}</el-descriptions-item>
          <el-descriptions-item label="备注">{{ currentHazard.remark || '-' }}</el-descriptions-item>
          <el-descriptions-item label="整改方案">{{ currentHazard.rectifyPlan || '暂无' }}</el-descriptions-item>
          <el-descriptions-item label="整改反馈">{{ currentHazard.rectifyFeedback || '暂无' }}</el-descriptions-item>
        </el-descriptions>
      </template>
    </el-drawer>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { getDicts } from '@/api/system/dict/data'
import { getHazardMapPoints } from '@/api/pipeNetwork/hazard'

const detailVisible = ref(false)
const currentHazard = ref(null)
const activeHazardId = ref('')
const mapError = ref('')
const loading = ref(false)
let mapInstance = null
let activeInfoWindow = null
let mapMarkers = []

const hazardTypeDict = ref([])
const hazardLevelDict = ref([])
const hazardStatusDict = ref([])

const filterType = ref('')
const filterLevel = ref('')
const filterStatus = ref('')
const listStatusTab = ref('')

function getDictLabel(dict, value) {
  const item = dict.find(d => d.dictValue === String(value))
  return item ? item.dictLabel : value
}

const levelColors = { '0': '#f5222d', '1': '#fa8c16', '2': '#1890ff', '3': '#52c41a' }

function levelTag(level) {
  const map = { '0': 'danger', '1': 'warning', '2': '', '3': 'success' }
  return map[String(level)] || ''
}
function statusTag(status) {
  const map = { '待核查': 'info', '整改中': 'warning', '已整改': 'success', '已闭环': '' }
  return map[status] || 'info'
}
function statusTabColor(status) {
  const map = { '待核查': '#909399', '整改中': '#e6a23c', '已整改': '#67c23a', '已闭环': '#409eff' }
  return map[status] || '#409eff'
}
function switchStatusTab(val) {
  listStatusTab.value = val
  filterStatus.value = val
  applyFilter()
}

// ==================== 隐患数据（从接口加载） ====================
const allHazards = ref([])

const filteredHazards = computed(() => {
  let data = allHazards.value
  if (filterType.value) data = data.filter(h => h.hazardType === filterType.value)
  if (filterLevel.value) data = data.filter(h => h.hazardLevel === filterLevel.value)
  if (listStatusTab.value) data = data.filter(h => h.hazardStatus === listStatusTab.value)
  return data
})

const levelLegend = computed(() =>
  hazardLevelDict.value.map(d => ({
    value: d.dictValue,
    label: d.dictLabel,
    color: levelColors[d.dictValue] || '#999',
    count: allHazards.value.filter(h => h.hazardLevel === d.dictValue).length
  }))
)

// ==================== 百度地图 ====================
const MAP_CENTER = { lng: 110.3965, lat: 28.4638 }
const MAP_DEFAULT_ZOOM = 14

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('hazardBaiduMap')
  if (!el) { mapError.value = '地图容器未找到。'; return }

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

  try {
    mapInstance.centerAndZoom(new BMapGL.Point(MAP_CENTER.lng, MAP_CENTER.lat), MAP_DEFAULT_ZOOM)
    mapInstance.enableScrollWheelZoom(true)
    mapInstance.setMinZoom(12)
    mapInstance.setMaxZoom(18)
  } catch (e) {
    console.error('设置地图中心失败：', e)
  }

  mapInstance.addEventListener('click', () => {
    closeInfoWindow()
    activeHazardId.value = ''
  })

  renderMapMarkers()
}

function renderMapMarkers() {
  if (!mapInstance || typeof BMapGL === 'undefined') return
  closeInfoWindow()
  mapMarkers.forEach(m => { try { mapInstance.removeOverlay(m) } catch (_) {} })
  mapMarkers = []

  filteredHazards.value.forEach(h => {
    const pt = new BMapGL.Point(h.longitude, h.latitude)
    const color = levelColors[h.hazardLevel] || '#999'
    const isActive = activeHazardId.value === h.hazardId
    const size = isActive ? 16 : 12

    const label = new BMapGL.Label('', {
      position: pt,
      offset: new BMapGL.Size(-size, -size)
    })
    label.setStyle({
      color: '#fff',
      fontSize: '10px',
      fontWeight: 'bold',
      padding: '0',
      backgroundColor: color,
      borderRadius: '50%',
      border: isActive ? '3px solid #fff' : '2px solid #fff',
      boxShadow: isActive ? '0 0 12px rgba(0,0,0,0.5)' : '0 2px 6px rgba(0,0,0,0.3)',
      textAlign: 'center',
      lineHeight: (size * 2) + 'px',
      width: (size * 2) + 'px',
      height: (size * 2) + 'px',
      cursor: 'pointer'
    })

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

    mapInstance.addOverlay(label)
    mapMarkers.push({ overlay: label, hazard: h })
  })
}

function openHazardInfo(h) {
  closeInfoWindow()
  currentHazard.value = h
  activeHazardId.value = h.hazardId
  detailVisible.value = true

  const pt = new BMapGL.Point(h.longitude, h.latitude)
  const color = levelColors[h.hazardLevel] || '#999'
  const levelLabel = getDictLabel(hazardLevelDict.value, h.hazardLevel)
  const typeLabel = getDictLabel(hazardTypeDict.value, h.hazardType)
  const statusLabel = getDictLabel(hazardStatusDict.value, h.hazardStatus)

  const html = `<div style="font-size:13px;max-width:260px;line-height:1.8;">
    <b>${h.hazardNo}</b><br/>
    隐患类型：${typeLabel}<br/>
    隐患等级：<span style="color:${color};font-weight:bold;">${levelLabel}</span><br/>
    整改状态：${statusLabel}<br/>
    上报单位：${h.reportUnit}<br/>
    地址：${h.address}
  </div>`
  activeInfoWindow = new BMapGL.InfoWindow(html, { width: 260, height: 150 })
  mapInstance.openInfoWindow(activeInfoWindow, pt)
  mapInstance.panTo(pt)

  // 更新标记点样式
  renderMapMarkers()
}

// ==================== 列表-地图交互 ====================
function focusHazard(h) {
  if (!mapInstance) return
  openHazardInfo(h)

  // 滚动列表项到可见区域
  const el = document.querySelector(`.list-item.active`)
  if (el) {
    el.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
  }
}

function onStatusFilterChange(val) {
  listStatusTab.value = val || ''
  applyFilter()
}
function applyFilter() {
  activeHazardId.value = ''
  renderMapMarkers()
}
function resetFilter() {
  filterType.value = ''
  filterLevel.value = ''
  filterStatus.value = ''
  listStatusTab.value = ''
  applyFilter()
}

// ==================== 生命周期 ====================
async function loadDicts() {
  try {
    const [typeRes, levelRes, statusRes] = await Promise.all([
      getDicts('hazard_type'),
      getDicts('hazard_level'),
      getDicts('hazard_status')
    ])
    hazardTypeDict.value = typeRes.data || []
    hazardLevelDict.value = levelRes.data || []
    hazardStatusDict.value = statusRes.data || []
  } catch (e) {
    hazardTypeDict.value = [
      { dictValue: '0', dictLabel: '第三方施工破坏' },
      { dictValue: '1', dictLabel: '管道老化腐蚀' },
      { dictValue: '2', dictLabel: '地面沉降' },
      { dictValue: '3', dictLabel: '违章占压' },
      { dictValue: '4', dictLabel: '设备故障' }
    ]
    hazardLevelDict.value = [
      { dictValue: '0', dictLabel: '重大' },
      { dictValue: '1', dictLabel: '较大' },
      { dictValue: '2', dictLabel: '一般' },
      { dictValue: '3', dictLabel: '低风险' }
    ]
    hazardStatusDict.value = [
      { dictValue: '待核查', dictLabel: '待核查' },
      { dictValue: '整改中', dictLabel: '整改中' },
      { dictValue: '已整改', dictLabel: '已整改' },
      { dictValue: '已闭环', dictLabel: '已闭环' }
    ]
  }
}

async function loadHazards() {
  loading.value = true
  try {
    const res = await getHazardMapPoints()
    allHazards.value = res.data || []
  } catch (e) { console.error(e) } finally { loading.value = false }
}

onMounted(async () => {
  await loadDicts()
  await loadHazards()
  await nextTick()
  waitForBMapGL()
})

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

<style scoped>
.hazard-map-page {
  position: relative;
  width: 100%;
  height: calc(100vh - 100px);
  overflow: hidden;
}

/* 顶部搜索栏 */
.top-bar {
  position: absolute;
  top: 16px;
  left: 16px;
  right: 16px;
  z-index: 1000;
}
.search-card {
  border-radius: 8px;
}
.search-card :deep(.el-card__body) {
  padding: 12px 16px 0;
}

/* 地图 */
.map-container {
  width: 100%;
  height: 100%;
}
.map-error {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #999;
  font-size: 16px;
  z-index: 1001;
}

/* 左侧隐患列表 */
.left-list-card {
  position: absolute;
  left: 16px;
  top: 110px;
  width: 340px;
  max-height: calc(100vh - 200px);
  z-index: 1000;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
}
.left-list-card :deep(.el-card__header) {
  padding: 10px 14px;
}
.left-list-card :deep(.el-card__body) {
  padding: 0;
  flex: 1;
  overflow: hidden;
}
.left-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  font-size: 14px;
}
.list-count {
  font-size: 12px;
  color: #999;
  font-weight: 400;
}
.status-tabs {
  display: flex;
  gap: 6px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid #f0f0f0;
}
.status-tab {
  font-size: 12px;
  padding: 3px 10px;
  cursor: pointer;
  color: #909399;
  border-radius: 3px;
  border-bottom: 2px solid transparent;
  transition: all 0.2s;
}
.status-tab:hover {
  color: #409eff;
}
.status-tab.active {
  color: #409eff;
  font-weight: 500;
  border-bottom-color: #409eff;
}
.list-body {
  max-height: calc(100vh - 320px);
  overflow-y: auto;
  padding: 4px 0;
}
.list-item {
  padding: 10px 14px;
  cursor: pointer;
  border-left: 3px solid transparent;
  border-bottom: 1px solid #f0f0f0;
  transition: all 0.2s;
}
.list-item:hover {
  background: #f5f7fa;
}
.list-item.active {
  background: #ecf5ff;
  border-left-color: #409eff;
}
.item-top {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}
.item-top .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}
.item-no {
  font-weight: 600;
  font-size: 13px;
  color: #303133;
  flex: 1;
}
.item-info {
  font-size: 12px;
  color: #606266;
  margin-bottom: 4px;
  padding-left: 18px;
}
.divider {
  margin: 0 6px;
  color: #ddd;
}
.item-addr {
  font-size: 12px;
  color: #909399;
  padding-left: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.item-time {
  font-size: 11px;
  color: #c0c4cc;
  padding-left: 18px;
  margin-top: 2px;
}

/* 右侧图例 */
.legend-card {
  position: absolute;
  right: 16px;
  top: 110px;
  width: 160px;
  z-index: 1000;
  border-radius: 8px;
}
.legend-card :deep(.el-card__header) {
  padding: 10px 14px;
  font-weight: 600;
  font-size: 14px;
}
.legend-card :deep(.el-card__body) {
  padding: 10px 14px;
}
.legend-items {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}
.legend-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}
.legend-count {
  margin-left: auto;
  color: #999;
  font-size: 12px;
}
</style>
