<script setup lang="ts">
/**
 * 地图监控页
 *
 * 在地图上展示监测设备位置和状态，
 * 可点击设备查看实时数据。
 */
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import maplibregl from 'maplibre-gl'
import { MapManager } from '@/map/MapManager'
import { MapFactory } from '@/map/MapFactory'
import { useMap } from '@/map/composables/useMap'
import { usePopup } from '@/map/composables/usePopup'

const router = useRouter()

// ── 地图状态 ──────────────────────────────────────────────
const { map, loading, error, isReady } = useMap()
const { showPopup, hidePopup } = usePopup()

/** 初始化错误 */
const initError = ref<string | null>(null)

/** 标记是否已添加设备标记 */
const markersAdded = ref(false)

/** 模拟设备点位 */
const devicePoints = ref([
  { id: 1, name: '流量监测仪 A-01', status: 'normal', lat: 30.5, lng: 104.0 },
  { id: 2, name: '压力传感器 P-03', status: 'alarm', lat: 30.51, lng: 104.02 },
  { id: 3, name: '水质监测仪 W-07', status: 'normal', lat: 30.48, lng: 103.98 },
  { id: 4, name: '液位计 L-02', status: 'offline', lat: 30.52, lng: 104.05 },
])

const statusColorMap: Record<string, string> = {
  normal: '#4CAF50',
  alarm: '#F44336',
  offline: '#999',
}

/** 存储动态创建的 Marker，用于清理 */
const markers: maplibregl.Marker[] = []

// ── 添加设备点位标记 ────────────────────────────────────
function addDeviceMarkers(m: maplibregl.Map): void {
  if (markersAdded.value) return
  markersAdded.value = true

  devicePoints.value.forEach((point) => {
    const color = statusColorMap[point.status] || '#999'
    const el = document.createElement('div')
    el.style.cssText = `
      width: 14px; height: 14px; border-radius: 50%;
      background: ${color}; border: 2px solid #fff;
      box-shadow: 0 1px 4px rgba(0,0,0,0.3); cursor: pointer;
    `
    const marker = new maplibregl.Marker({ element: el })
      .setLngLat([point.lng, point.lat])
      .addTo(m)

    // 点击弹出设备信息
    el.addEventListener('click', () => {
      showPopup(
        [point.lng, point.lat],
        `<div class="device-popup">
          <strong>${point.name}</strong><br/>
          <span style="font-size:12px;color:#666">状态: ${point.status}</span><br/>
          <span style="font-size:11px;color:#999">${point.lat}, ${point.lng}</span>
        </div>`,
        { maxWidth: '220px', closeOnClick: true },
      )
    })

    markers.push(marker)
  })
}

function clearMarkers(): void {
  markers.forEach((m) => m.remove())
  markers.length = 0
  markersAdded.value = false
}

// ── 初始化地图 ───────────────────────────────────────────
onMounted(() => {
  const manager = MapManager.getInstance()

  // 如果地图已存在，复用并添加标记
  if (manager.hasMap()) {
    const m = manager.getMap()
    if (m) addDeviceMarkers(m)
    return
  }

  const container = document.getElementById('mapmonitor-container')
  if (!container) {
    initError.value = '地图容器 #mapmonitor-container 未找到'
    return
  }

  try {
    MapFactory.createWithBasemap('osm', {
      container: 'mapmonitor-container',
      zoom: 10,
      center: [104.0, 30.5],
      onLoad: (m) => {
        console.log('[MapMonitoring] 地图已加载')
        addDeviceMarkers(m)
      },
    })
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : '地图初始化失败'
    initError.value = msg
    console.error('[MapMonitoring] 地图创建失败:', err)
  }
})

// ── 监听 isReady，加载标记 ──────────────────────────────
watch(isReady, (ready) => {
  if (ready && map.value && !markersAdded.value) {
    addDeviceMarkers(map.value)
  }
})

// ── 组件卸载 ─────────────────────────────────────────────
onUnmounted(() => {
  clearMarkers()
  hidePopup()
  MapManager.getInstance().destroyMap()
})

// ── 跳转设备详情 ─────────────────────────────────────────
function goEquipmentInfo(id: number) {
  router.push(`/equipmentInfo?id=${id}`)
}
</script>

<template>
  <div class="map-monitoring-page">
    <van-nav-bar title="地图监控" left-text="返回" left-arrow fixed placeholder @click-left="router.back()" />

    <!-- MapLibre 地图容器 -->
    <div id="mapmonitor-container" class="map-area">
      <!-- 加载状态 -->
      <div v-if="!map && loading && !initError" class="map-status map-loading">
        <van-loading type="spinner" size="28" color="var(--color-primary)" />
        <p>地图加载中…</p>
      </div>

      <!-- 初始化错误 -->
      <div v-if="initError" class="map-status map-error-state">
        <van-icon name="warning-o" size="40" color="#F44336" />
        <p>{{ initError }}</p>
      </div>

      <!-- 运行时错误 -->
      <div v-if="error" class="map-error-banner">
        <van-icon name="warning-o" size="14" />
        <span>{{ error }}</span>
      </div>
    </div>

    <!-- 设备点位列表面板（底部浮动） -->
    <div class="device-panel">
      <div class="panel-header">
        <span class="panel-title">设备列表</span>
        <span class="panel-count">共 {{ devicePoints.length }} 台</span>
      </div>
      <div
        v-for="point in devicePoints"
        :key="point.id"
        class="device-item"
        @click="goEquipmentInfo(point.id)"
      >
        <div class="device-dot" :style="{ backgroundColor: statusColorMap[point.status] }" />
        <div class="device-info">
          <span class="device-name">{{ point.name }}</span>
          <span class="device-coord">{{ point.lat }}, {{ point.lng }}</span>
        </div>
        <van-icon name="arrow" color="#ccc" />
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.map-monitoring-page {
  min-height: 100vh;
  background: var(--color-bg-page);
  display: flex;
  flex-direction: column;

  :deep(.van-nav-bar) {
    background: var(--color-primary);
    --van-nav-bar-title-text-color: #fff;
    --van-nav-bar-text-color: #fff;
    --van-nav-bar-icon-color: #fff;
  }
}

.map-area {
  flex: 1;
  position: relative;
  margin: 8px;
  border-radius: 10px;
  overflow: hidden;
  min-height: 300px;

  :deep(.maplibregl-map) {
    width: 100%;
    height: 100%;
  }
}

.map-status {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  border-radius: 10px;
  z-index: 5;
  gap: 8px;

  p {
    margin: 0;
    font-size: 14px;
    color: var(--color-text-placeholder);
  }
}

.map-error-state {
  p {
    color: #F44336;
  }
}

.map-error-banner {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: #fff3f3;
  color: #F44336;
  font-size: 11px;
}

.device-panel {
  background: var(--color-bg-card);
  margin: 0 8px 8px;
  border-radius: 10px;
  overflow: hidden;

  .panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);

    .panel-title {
      font-size: 15px;
      font-weight: 600;
      color: var(--color-text-regular);
    }

    .panel-count {
      font-size: 12px;
      color: var(--color-text-placeholder);
    }
  }

  .device-item {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border);
    cursor: pointer;

    &:last-child {
      border-bottom: none;
    }

    .device-dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      margin-right: 12px;
      flex-shrink: 0;
    }

    .device-info {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 2px;

      .device-name {
        font-size: 14px;
        color: var(--color-text-regular);
      }

      .device-coord {
        font-size: 11px;
        color: var(--color-text-placeholder);
      }
    }
  }
}
</style>
