<template>
  <div class="map-container">
    <div ref="mapNodeRef" class="map-node" />

    <!-- 底图切换 -->
    <div class="basemap-panel" v-show="showBasemapMenu">
      <el-radio-group v-model="currentBasemap" @change="onBasemapChange" size="small">
        <el-radio-button value="taihu">太湖一张图</el-radio-button>
        <el-radio-button value="tianditu_img">天地图影像</el-radio-button>
        <el-radio-button value="tianditu_vec">天地图矢量</el-radio-button>
      </el-radio-group>
    </div>

    <!-- 图层按钮 -->
    <div class="layer-btn" @click="showBasemapMenu = !showBasemapMenu" title="图层切换">
      <el-icon :size="22"><Operation /></el-icon>
    </div>

    <!-- 全图 -->
    <div class="full-extent-btn" @click="zoomToFull" title="全图">
      <el-icon :size="22"><FullScreen /></el-icon>
    </div>

    <!-- 经纬度 -->
    <div class="coord-bar" v-show="showCoords">
      经度 {{ coordLng }} &nbsp; 纬度 {{ coordLat }}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, shallowRef } from 'vue'
import MapView from '@arcgis/core/views/MapView'
import Map from '@arcgis/core/Map'
import WebTileLayer from '@arcgis/core/layers/WebTileLayer'
import TileLayer from '@arcgis/core/layers/TileLayer'
import MapImageLayer from '@arcgis/core/layers/MapImageLayer'
import Extent from '@arcgis/core/geometry/Extent'
import SpatialReference from '@arcgis/core/geometry/SpatialReference'
import Graphic from '@arcgis/core/Graphic'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'
import { basemapGroups, taihuServiceLayers } from './config/layers'

const emit = defineEmits(['mapReady', 'mapClick'])

// ---- map ----
const mapNodeRef = ref(null)
const mapView = shallowRef(null)
const currentBasemap = ref('taihu')
const showBasemapMenu = ref(false)
const showCoords = ref(false)
const coordLng = ref('')
const coordLat = ref('')
const layerGroups = shallowRef({})

// 太湖流域范围 [119.92, 31.17], WGS84 (wkid 4490)
const taihuCenter = [119.92, 31.17]
const taihuZoom = 9
const fullExtent = new Extent({ xmin: 115, ymin: 29, xmax: 123, ymax: 33, spatialReference: SpatialReference.WGS84 })

// ---- create WMTS layer from URL template ----
function createWmtsLayer(cfg) {
  // 替换 {subDomain} 占位符
  const subDomains = cfg.subDomains || ['t0']
  const urlTemplate = cfg.urlTemplate.replace('{subDomain}', subDomains[0])
  // ArcGIS WebTileLayer uses {level},{col},{row} pattern
  const arcgisUrl = urlTemplate
    .replace(/\{level\}/g, '{level}')
    .replace(/\{row\}/g, '{row}')
    .replace(/\{col\}/g, '{col}')
  return new WebTileLayer({
    id: cfg.id,
    title: cfg.title,
    urlTemplate: arcgisUrl,
    subDomains: subDomains,
    visible: cfg.visible !== false,
    opacity: cfg.opacity || 1
  })
}

// ---- create layers for a basemap group ----
function createBasemapLayers(key) {
  const group = basemapGroups[key]
  if (!group) return []
  return group.layers.map((cfg) => {
    // ArcGIS REST tile layer (SuperMap 兼容)
    if (cfg.type === 'mapserver' || cfg.url?.includes('/MapServer')) {
      return new MapImageLayer({
        id: cfg.id,
        title: cfg.title,
        url: cfg.url,
        visible: cfg.visible !== false
      })
    }
    // WMTS template URL
    return createWmtsLayer(cfg)
  })
}

// ---- init ----
onMounted(async () => {
  const layers = createBasemapLayers('taihu')
  layerGroups.value = { taihu: layers }

  const map = new Map({ layers })

  const view = new MapView({
    container: mapNodeRef.value,
    map,
    center: taihuCenter,
    zoom: taihuZoom
  })

  mapView.value = view
  await view.when()

  // 太湖一张图：预加载 ArcGIS 要素服务图层（默认不可见，checkbox 控制显隐）
  taihuServiceLayers.forEach((cfg) => {
    const LayerCtor = cfg.type === 'mapimage' ? MapImageLayer : FeatureLayer
    const layer = new LayerCtor({
      id: cfg.id,
      title: cfg.name,
      url: cfg.url,
      visible: false,
      spatialReference: { wkid: 4490 },
      outFields: ['*']
    })
    map.add(layer)
  })
  taihuServiceLoaded.value = true

  // pointer move → coords
  view.on('pointer-move', (evt) => {
    const pt = view.toMap({ x: evt.x, y: evt.y })
    if (pt) {
      coordLng.value = pt.longitude.toFixed(6)
      coordLat.value = pt.latitude.toFixed(6)
      showCoords.value = true
    }
  })

  // click → identify features and emit
  view.on('click', (evt) => {
    view.hitTest(evt).then((res) => {
      if (res.results.length > 0) {
        const g = res.results[0].graphic
        const layer = g?.layer
        const attrs = g?.attributes || {}
        emit('mapClick', {
          longitude: evt.mapPoint.longitude,
          latitude: evt.mapPoint.latitude,
          x: evt.x, y: evt.y,
          layerId: layer?.id,
          layerTitle: layer?.title,
          layerUrl: layer?.url,
          attributes: attrs
        })
      } else {
        emit('mapClick', {
          longitude: evt.mapPoint.longitude,
          latitude: evt.mapPoint.latitude
        })
      }
    })
  })

  emit('mapReady', { view, map })
})

onUnmounted(() => {
  mapView.value?.destroy()
})

// ---- methods ----
const taihuServiceLoaded = ref(false)

const onBasemapChange = async (key) => {
  if (!mapView.value) return
  // cache layers
  if (!layerGroups.value[key]) {
    layerGroups.value[key] = createBasemapLayers(key)
  }
  const mp = mapView.value.map
  mp.layers.removeAll()
  // add basemap layers
  layerGroups.value[key].forEach((l) => mp.add(l))

  // 太湖一张图：预加载 ArcGIS 要素服务图层（默认不可见）
  if (key === 'taihu' && !taihuServiceLoaded.value) {
    taihuServiceLayers.forEach((cfg) => {
      const LayerCtor = cfg.type === 'mapimage' ? MapImageLayer : FeatureLayer
      const layer = new LayerCtor({
        id: cfg.id,
        title: cfg.name,
        url: cfg.url,
        visible: false
      })
      mp.add(layer)
    })
    taihuServiceLoaded.value = true
  }
}

const zoomToFull = () => {
  mapView.value?.goTo(fullExtent)
}

defineExpose({
  getView: () => mapView.value,
  zoomToFull,
  goTo(point, zoom) {
    mapView.value?.goTo({ target: point, zoom: zoom || 12 })
  },
  addLayer(layer) {
    mapView.value?.map.add(layer)
  },
  removeLayer(id) {
    const l = mapView.value?.map.findLayerById(id)
    if (l) mapView.value.map.remove(l)
  }
})
</script>

<style scoped>
.map-container { width: 100%; height: 100%; position: relative; }
.map-node { width: 100%; height: 100%; }

.basemap-panel {
  position: absolute; bottom: 80px; left: 16px; z-index: 10;
  background: rgba(255,255,255,.92); padding: 6px 10px; border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
}
.layer-btn {
  position: absolute; bottom: 130px; left: 16px; z-index: 10;
  background: white; width: 36px; height: 36px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
}
.layer-btn:hover { background: #e6f7ff; }
.full-extent-btn {
  position: absolute; top: 16px; right: 16px; z-index: 10;
  background: white; width: 36px; height: 36px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,.15);
}
.full-extent-btn:hover { background: #e6f7ff; }
.coord-bar {
  position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); z-index: 10;
  background: rgba(0,0,0,.5); color: #ccc; padding: 2px 16px; border-radius: 3px; font-size: 13px;
}
</style>
