<template>
  <div id="map_container"></div>
</template>

<script setup name="MapViewport">
import * as Cesium from 'cesium'
import { onMounted, onBeforeUnmount } from 'vue'
import { useRoute } from 'vue-router'
import useMapStore from '@/map/stores/mapStore'

const props = defineProps({
  // 是否加载默认底图，也就是天地图
  isLoadDefaultBaseMap: {
    type: Boolean,
    default: true
  }
})

const mapStore = useMapStore()
const route = useRoute()
let viewer = null

Cesium.Ion.defaultAccessToken = import.meta.env.VITE_CESIUM_ION_TOKEN || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyMGE2MTYzOS02OTA3LTRhZDEtYmFmYi01YWZmNDJmZGRlODgiLCJpZCI6MTEwNDE2LCJpYXQiOjE3NjY3MTE5MzR9.MtiUq510xS8C3Wm1rgHCloJqv0dlxIL0CfOIHj4uHBY'

onMounted(() => {
  initViewer()
})

onBeforeUnmount(() => {
  try {
    mapStore.destroy()
  } catch (error) {
    console.warn('销毁地图实例失败', error)
  }
})

async function initViewer() {
  viewer = new Cesium.Viewer('map_container', {
    terrain: Cesium.Terrain.fromWorldTerrain(),
    infoBox: false,
    imageryProvider: false,
    baseLayerPicker: false,
    sceneModePicker: false,
    homeButton: false,
    fullscreenButton: false,
    timeline: false,
    navigationHelpButton: false,
    navigationInstructionsInitiallyVisible: false,
    animation: false,
    geocoder: false,
    sceneMode: Cesium.SceneMode.SCENE3D,
    selectionIndicator: false,
    shouldAnimate: false,
  })

  viewer.scene.sun.show = false
  viewer.scene.moon.show = false
  viewer.scene.skyBox.show = false // 关闭天空盒
  viewer.scene.globe.show = true

  // 隐藏版权信息
  viewer.cesiumWidget.creditContainer.style.display = 'none'
  try {
    if (viewer.animation?.container) {
      viewer.animation.container.style.display = 'none'
    }
    if (viewer.timeline?.container) {
      viewer.timeline.container.style.display = 'none'
    }
  } catch (error) {
    console.warn('隐藏时间轴/动画控件失败', error)
  }

  if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
    viewer.resolutionScale = window.devicePixelRatio
  }

  // 注入全局地图 Store
  mapStore.init(viewer)
  const { camera } = mapStore.services()

  const skipInitialView = route.meta?.skipInitialCameraView
  if (mapStore.cameraPosition) {
    viewer.camera.setView({
      destination: mapStore.cameraPosition,
      orientation: {
        heading: mapStore.cameraPosture.heading,
        pitch: mapStore.cameraPosture.pitch,
        roll: mapStore.cameraPosture.roll,
      },
    })
    if (!mapStore.homeView) {
      camera.rememberHomeFromCurrent()
    }
  } else if (!skipInitialView) {
    await applyInitialCameraView()
  }
  if (props.isLoadDefaultBaseMap) {
    await loadBaseMap()
  }

}

async function applyInitialCameraView() {
  const { camera } = mapStore.services()

  try {
    const viewConfig = await mapStore.getInitialCameraView()

    if (viewConfig.type === 'extent') {
      await camera.fitBounds(viewConfig.value)
    } else if (viewConfig.type === 'center') {
      const { lon, lat, height } = viewConfig.value
      await camera.setCenter(lon, lat, height)
    }

    camera.rememberHomeFromCurrent()
  } catch (error) {
    console.error('应用初始相机视图失败:', error)
    await camera.setCenter(0, 0, 20000000)
    camera.rememberHomeFromCurrent()
  }
}

async function loadBaseMap() {
  const { layer } = mapStore.services()

  try {
    const currentGroupId = mapStore.getCurrentBaseMapGroupId()
    if (!currentGroupId) {
      console.warn('未找到默认底图组')
      return
    }

    // 加载所有底图组的图层，但只显示当前激活组
    for (const group of mapStore.baseMapGroups) {
      const groupId = group.Attribute?.rid || group.Rid
      const shouldShow = groupId === currentGroupId
      const layers = mapStore.getBaseMapLayersForGroup(groupId)

      for (const layerConfig of layers) {
        await layer.addLayer({
          id: layerConfig.id,
          type: layerConfig.type,
          url: layerConfig.url,
          options: { visible: shouldShow },
          meta: layerConfig.meta,
        })
      }
    }
  } catch (error) {
    console.error('加载底图失败:', error)

    if (!viewer) {
      return
    }

    try {
      const imageryLayers = viewer.imageryLayers
      imageryLayers?.removeAll()
      const fallbackProvider = await Cesium.IonImageryProvider.fromAssetId(2)
      imageryLayers?.addImageryProvider(fallbackProvider)
      console.info('已回退到 Cesium Ion Bing Maps 底图')
    } catch (fallbackError) {
      console.error('Cesium Ion 底图回退失败:', fallbackError)
    }
  }
}
</script>

<style scoped lang="scss">
#map_container {
  width: 100%;
  height: 100%;
}
</style>
