/*
  地图 Store
  - 统一管理 Cesium Viewer 生命周期（init/destroy/isReady/onReady/getViewer）
  - 暴露 services() 获取子服务：
    - layer 图层管理（影像/矢量/地形/原语）：添加/移除/显隐/透明度/顺序/卷帘
    - camera 相机视角：中心/视图/飞行/范围/缩放
    - query 查询拾取与坐标转换：屏幕坐标 -> 地理坐标、实体拾取
    - entity 实体：点/线/面/标签 增删查与分层管理
  注意：
  - Store 不主动销毁外部传入的 viewer，仅管理自身所添加的资源。
*/

import * as Cesium from 'cesium'
import { defineStore } from 'pinia'
import { DEFAULT_VECTOR_LAYER_ID } from '@/map/utils/utils'
import { createLayerService } from '@/map/services/createLayerService'
import { createCameraService } from '@/map/services/createCameraService'
import { createQueryService } from '@/map/services/createQueryService'
import { createEntityService } from '@/map/services/createEntityService'
import baseMap from '@/map/data/baseMap.json'
import mapBaseConfig from '@/map/data/mapBaseConfig.json'

const DEFAULT_HOME_VIEW = {
  lon: 0,
  lat: 0,
  height: 1500,
  heading: 0,
  pitch: -45,
  roll: 0,
}

const DEFAULT_MAP_SIZE = Object.freeze({
  top:0,
  left:0,
  width: '100%',
  height: '100%',
  zIndex: 1
})

function normalizeMapDimension(value, fallback) {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return `${value}px`
  }
  if (typeof value === 'string' && value.trim()) {
    return value.trim()
  }
  return fallback
}

function normalizeHomeView(view) {
  if (!view || typeof view !== 'object') return null
  const toNumber = (value, fallback) => {
    const num = Number(value)
    return Number.isFinite(num) ? num : fallback
  }
  return {
    lon: toNumber(view.lon, DEFAULT_HOME_VIEW.lon),
    lat: toNumber(view.lat, DEFAULT_HOME_VIEW.lat),
    height: toNumber(view.height, DEFAULT_HOME_VIEW.height),
    heading: toNumber(view.heading, DEFAULT_HOME_VIEW.heading),
    pitch: toNumber(view.pitch, DEFAULT_HOME_VIEW.pitch),
    roll: toNumber(view.roll, DEFAULT_HOME_VIEW.roll),
  }
}


const useMapStore = defineStore('map', {
  state: () => ({
    ready: false,
    viewer: null,
    showMap: true,
    cameraPosition: null, // 相机位置（Cesium.Cartesian3 快照）
    cameraPosture: {
      heading: 0,
      pitch: (-90) * (Math.PI / 180),
      roll: 0,
    },
    homeView: null,
    imagerySplitPosition: 0.5,
    layers: {}, // 图层表：id -> record {id,type,obj,owned,show,opacity,meta}
    _readyQueue: [], // 延迟到 viewer 就绪后执行的回调队列
    handlers: {}, // 事件处理器注册表
    _svcs: null, // services 缓存（避免重复创建）
    // 底图配置
    baseMapGroups: baseMap || [], // 底图组配置
    baseMapConfig: mapBaseConfig || [], // 地图基础配置
    currentBaseMapGroupId: null, // 当前激活的底图组ID
    defaultImageryProvider: null, // 默认影像提供者配置
    mapSize: { ...DEFAULT_MAP_SIZE },
  }),

  actions: {
    // 使用外部已创建的 Cesium.Viewer 进行初始化
    init(viewer) {
      if (!viewer) throw new Error('MapStore.init requires a Cesium.Viewer instance')
      if (this.ready && this.viewer === viewer) return
      this.viewer = viewer
      this.ready = true
      try {
        this.viewer.scene.imagerySplitPosition = this.imagerySplitPosition
      } catch (e) { }
      // 绑定相机状态快照监听（debounced）
      try {
        if (this.handlers._cameraChangedCb) {
          this.viewer.camera.changed.removeEventListener(this.handlers._cameraChangedCb)
        }
        const cb = () => {
          if (this.handlers._camDebounce) clearTimeout(this.handlers._camDebounce)
          this.handlers._camDebounce = setTimeout(() => {
            try {
              const cam = this.viewer.scene.camera
              // 记录相机笛卡尔位置与姿态（弧度）
              this.cameraPosition = new Cesium.Cartesian3(cam.position.x, cam.position.y, cam.position.z)
              this.cameraPosture = {
                heading: cam.heading,
                pitch: cam.pitch,
                roll: cam.roll,
              }
            } catch (e) { }
          }, 200)
        }
        this.handlers._cameraChangedCb = cb
        this.viewer.camera.changed.addEventListener(cb)
      } catch (e) { }
      // 确保存在默认矢量数据源图层
      if (!this.layers[DEFAULT_VECTOR_LAYER_ID]) {
        const ds = new Cesium.CustomDataSource(DEFAULT_VECTOR_LAYER_ID)
        this.viewer.dataSources.add(ds)
        this.layers[DEFAULT_VECTOR_LAYER_ID] = {
          id: DEFAULT_VECTOR_LAYER_ID,
          type: 'vector',
          obj: ds,
          owned: true,
          show: true,
          opacity: 1,
          meta: { title: 'Default Vector Layer' },
        }
      }
      // 触发所有 onReady 回调
      const queue = this._readyQueue.slice()
      this._readyQueue = []
      queue.forEach((cb) => {
        try {
          cb(this.viewer)
        } catch (e) { }
      })
    },

    // 清理由 Store 管理的资源（不会销毁外部传入的 Viewer 实例本身）
    destroy() {
      if (!this.viewer) {
        this.ready = false
        this.homeView = null
        this.layers = {}
        this._readyQueue = []
        this.handlers = {}
        return
      }
      const viewer = this.viewer
      try {
        if (this.handlers._cameraChangedCb) viewer.camera.changed.removeEventListener(this.handlers._cameraChangedCb)
        if (this.handlers._camDebounce) clearTimeout(this.handlers._camDebounce)
      } catch (e) { }
      this.homeView = null
      Object.keys(this.layers).forEach((id) => {
        const rec = this.layers[id]
        if (!rec || !rec.owned) return
        try {
          if (rec.type === 'imagery') {
            viewer.imageryLayers.remove(rec.obj, true)
          } else if (rec.type === 'vector' || rec.type === 'datasource') {
            viewer.dataSources.remove(rec.obj, true)
          } else if (rec.type === 'primitive') {
            viewer.scene.primitives.remove(rec.obj)
          } else if (rec.type === 'terrain') {
            if ('terrain' in viewer) viewer.terrain = new Cesium.EllipsoidTerrain()
            else viewer.scene.terrainProvider = new Cesium.EllipsoidTerrain()
          }
        } catch (e) { }
        delete this.layers[id]
      })
      this.handlers = {}
      this.viewer = null
      this.ready = false
      this._readyQueue = []
    },
    setShowMap(v) {
      this.showMap = !!v
    },
    getShowMap() {
      return this.showMap
    },
    setCameraPosition(cameraPosition) {
      this.cameraPosition = cameraPosition ? new Cesium.Cartesian3(cameraPosition.x, cameraPosition.y, cameraPosition.z) : null
    },
    getCameraPosition() {
      return this.cameraPosition
    },
    setCameraPosture(posture) {
      const p = posture || {}
      this.cameraPosture = {
        heading: typeof p.heading === 'number' ? p.heading : 0,
        pitch: typeof p.pitch === 'number' ? p.pitch : (-90) * (Math.PI / 180),
        roll: typeof p.roll === 'number' ? p.roll : 0,
      }
    },
    getCameraPosture() {
      return this.cameraPosture
    },

    setHomeView(view) {
      this.homeView = view ? normalizeHomeView(view) : null
    },
    getHomeView() {
      return this.homeView
    },
    clearHomeView() {
      this.homeView = null
    },

    // 底图配置管理
    getConfig(configName) {
      const rec = this.baseMapConfig.find(i => i.configName === configName)
      return rec ? rec.configValue : undefined
    },

    parseJSONSafe(text) {
      try { return JSON.parse(text) } catch { return undefined }
    },

    getDefaultBaseMapGroup() {
      return Array.isArray(this.baseMapGroups) && this.baseMapGroups.length ? this.baseMapGroups[0] : null
    },

    getCurrentBaseMapGroupId() {
      return this.currentBaseMapGroupId || (this.getDefaultBaseMapGroup()?.Attribute?.rid || this.getDefaultBaseMapGroup()?.Rid)
    },

    setCurrentBaseMapGroup(groupId) {
      this.currentBaseMapGroupId = groupId
    },

    getBaseMapLayersForGroup(groupId) {
      const group = this.baseMapGroups.find(g => (g.Attribute?.rid || g.Rid) === groupId)
      if (!group) return []

      const children = Array.isArray(group.Children) ? group.Children : []
      const groupAttr = group.Attribute || {}
      const groupName = groupAttr.name || group.Name
      const groupThumb = groupAttr.thumbnail || ''
      const groupSortValue = typeof groupAttr.sortValue === 'number' ? groupAttr.sortValue : Number(groupAttr.sortValue) || 0

      return children.map(item => {
        const attr = item.Attribute || {}
        const url = attr.servicePath || ''
        const serviceTypeName = attr.serviceTypeName || ''
        const rid = attr.rid || item.Rid
        const zIndex = typeof attr.sortValue === 'number' ? attr.sortValue : Number(attr.sortValue) || 0

        return {
          id: `basemap:${rid}`,
          rid,
          type: this.resolveLayerType(serviceTypeName, url),
          url,
          zIndex,
          meta: {
            title: attr.name || item.Name,
            zIndex,
            isBaseMap: true,
            baseGroupId: groupId,
            baseGroupName: groupName,
            baseGroupThumbnail: attr.thumbnail || groupThumb,
            baseGroupSortValue: groupSortValue,
            baseLayerRid: rid,
            baseLayerSortValue: zIndex,
          }
        }
      }).filter(layer => layer.type && layer.url)
    },

    resolveLayerType(serviceTypeName, url) {
      let nextType = serviceTypeName || ''
      if (!nextType) {
        if (/(wmts|TILEMATRIXSET)/i.test(url)) {
          nextType = 'WmtsServiceLayer'
        } else if (/(\{z\}|\{x\}|\{y\})/i.test(url)) {
          nextType = 'WebTileLayer'
        }
      }
      return nextType
    },

    async getInitialCameraView() {
      // 1) Extent 优先
      const extentStr = this.getConfig('Extent')
      const extentArr = extentStr ? this.parseJSONSafe(extentStr) : undefined
      if (Array.isArray(extentArr) && extentArr.length === 4) {
        const bbox = extentArr.map(Number) // [minLon, minLat, maxLon, maxLat]
        return { type: 'extent', value: bbox }
      }

      // 2) 其次 InitCenter + InitHeight
      const centerStr = this.getConfig('InitCenter')
      const heightStr = this.getConfig('InitHeight')
      const centerArr = centerStr ? this.parseJSONSafe(centerStr) : undefined
      const height = heightStr ? Number(heightStr) : 1500
      if (Array.isArray(centerArr) && centerArr.length >= 2) {
        // 注意 mapBaseConfig 里中心的顺序 [lat, lon]
        const lat = Number(centerArr[0])
        const lon = Number(centerArr[1])
        return { type: 'center', value: { lon, lat, height } }
      }

      // 3) 兜底
      return { type: 'center', value: { lon: 0, lat: 0, height: 20000000 } }
    },

    getDefaultImageryProvider() {
      if (this.defaultImageryProvider) {
        return this.defaultImageryProvider
      }
      // 尝试从当前底图组获取第一个图层作为默认底图
      const currentGroupId = this.getCurrentBaseMapGroupId()
      if (currentGroupId) {
        const layers = this.getBaseMapLayersForGroup(currentGroupId)
        if (layers.length > 0) {
          const firstLayer = layers[0]
          // 这里可以根据图层类型创建相应的ImageryProvider
          // 为了简化，我们先返回配置，实际创建在GetCesiumViewer中处理
          return {
            type: firstLayer.type,
            url: firstLayer.url,
            meta: firstLayer.meta
          }
        }
      }
      return null
    },

    isReady() {
      return !!this.ready && !!this.viewer
    },

    onReady(cb) {
      if (this.isReady()) {
        try {
          cb(this.viewer)
        } catch (e) { }
        return () => { }
      }
      this._readyQueue.push(cb)
      return () => {
        const i = this._readyQueue.indexOf(cb)
        if (i >= 0) this._readyQueue.splice(i, 1)
      }
    },

    getViewer() {
      if (!this.isReady()) throw new Error('MapStore not ready')
      return this.viewer
    },
    /**
     * 设置地图容器尺寸
     * @param {Object} size
     * @param {string|number} size.width
     * @param {string|number} size.height
     * @param {string|number} size.zIndex
     */
    setMapSize(size) {
      const nextSize = typeof size === 'object' && size !== null ? size : {}
      const nextTop = normalizeMapDimension(nextSize.top, DEFAULT_MAP_SIZE.top)
      const nextLeft = normalizeMapDimension(nextSize.left, DEFAULT_MAP_SIZE.left)
      const nextWidth = normalizeMapDimension(nextSize.width, DEFAULT_MAP_SIZE.width)
      const nextHeight = normalizeMapDimension(nextSize.height, DEFAULT_MAP_SIZE.height)
      const nextZIndex = nextSize.zIndex
      const prevSize = this.mapSize || DEFAULT_MAP_SIZE
      const unchanged =
        prevSize.top === nextTop &&
        prevSize.left === nextLeft &&
        prevSize.width === nextWidth &&
        prevSize.height === nextHeight &&
        prevSize.zIndex === nextZIndex
      if (unchanged) return
      this.mapSize = {
        top: nextTop,
        left: nextLeft,
        width: nextWidth,
        height: nextHeight,
        zIndex: nextZIndex
      }
      try {
        if (typeof window !== 'undefined') {
          window.dispatchEvent(new Event('resize'))
        }
      } catch (error) { }
    },

    /**
     * 重置地图容器尺寸
     */
    resetMapSize() {
      this.mapSize = { ...DEFAULT_MAP_SIZE }
      try {
        if (typeof window !== 'undefined') {
          window.dispatchEvent(new Event('resize'))
        }
      } catch (error) { }
    },

    // 获取服务集合（懒加载并缓存）
    services() {
      const store = this
      if (store._svcs) return store._svcs
      const viewerOrThrow = () => {
        if (!store.isReady()) throw new Error('MapStore not ready')
        return store.viewer
      }

      const layer = createLayerService({ viewerOrThrow, store })
      const camera = createCameraService({ viewerOrThrow, store })
      const query = createQueryService({ viewerOrThrow, getLayers: () => store.layers })
      const entity = createEntityService({ store, layerService: layer })

      store._svcs = { layer, camera, query, entity }
      return store._svcs
    },
  },
})

export default useMapStore
