/**
 * 应急力量地图交互 Composable
 * 处理应急力量标记点的点击事件，使用 HTML Overlay 显示详情信息
 *
 * @module composables/useEmergencyForceInteraction
 */

import { ref, watch, onBeforeUnmount } from 'vue'
import * as Cesium from 'cesium'
import { fetchEmergencyForceDetail } from '../api/emergencyForce'

/**
 * 应急力量地图交互 Hook
 *
 * @param {Object} mapStore - 地图 Store 实例
 * @param {Object} options - 配置选项
 * @param {boolean} [options.flyToPoint=false] - 点击时是否飞行到点位
 * @param {number} [options.flyDuration=1.5] - 飞行动画时长（秒）
 * @param {number} [options.flyDistance=500] - 飞行后的相机距离（米）
 * @returns {Object} 交互状态和方法
 */
export function useEmergencyForceInteraction(mapStore, options = {}) {
  // ==================== 配置选项 ====================

  const config = {
    flyToPoint: options.flyToPoint ?? false,
    flyDuration: options.flyDuration ?? 1.5,
    flyDistance: options.flyDistance ?? 500
  }

  // ==================== 状态管理 ====================

  /**
   * 是否启用交互
   */
  const enabled = ref(false)

  /**
   * 当前选中的实体
   */
  const selectedEntity = ref(null)

  /**
   * Tooltip 是否可见
   */
  const tooltipVisible = ref(false)

  /**
   * Tooltip 屏幕位置
   * @type {Ref<{x: number, y: number}|null>}
   */
  const tooltipPosition = ref(null)

  /**
   * Tooltip 数据
   * @type {Ref<{qxmc?: string, yjllpz?: string, wzQtwz?: string}>}
   */
  const tooltipData = ref({})

  /**
   * 加载状态
   */
  const loading = ref(false)

  /**
   * 错误信息
   */
  const error = ref('')

  /**
   * 请求取消控制器
   */
  const abortController = ref(null)

  /**
   * Cesium 事件处理器
   */
  let clickHandler = null

  /**
   * postRender 事件监听器
   */
  let postRenderListener = null

  // ==================== 工具函数 ====================

  /**
   * 获取 Cesium Viewer 实例
   * @returns {Cesium.Viewer|null}
   */
  const getViewer = () => {
    if (!mapStore.isReady()) {
      console.warn('地图尚未就绪')
      return null
    }
    return mapStore.getViewer()
  }

  /**
   * 取消正在进行的请求
   */
  const cancelRequest = () => {
    if (abortController.value) {
      try {
        abortController.value.abort()
      } catch (error) {
        console.warn('取消请求失败', error)
      } finally {
        abortController.value = null
      }
    }
  }

  /**
   * 更新 Tooltip 位置
   * 将 3D 世界坐标转换为屏幕坐标
   * 特别处理 clampToGround 实体，确保使用地形高度
   */
  const updateTooltipPosition = () => {
    if (!selectedEntity.value || !tooltipVisible.value) {
      return
    }

    const viewer = getViewer()
    if (!viewer) return

    try {
      const position = selectedEntity.value.position?.getValue(Cesium.JulianDate.now())
      if (!position) return

      // 处理 clampToGround 实体
      // 对于使用 CLAMP_TO_GROUND 的 billboard，需要获取实际的地形高度
      let clampedPosition = position

      // 转换为地理坐标
      const cartographic = Cesium.Cartographic.fromCartesian(position)

      // 尝试获取地形高度
      if (viewer.scene.globe) {
        const height = viewer.scene.globe.getHeight(cartographic)

        // 如果成功获取地形高度，使用地形高度重建位置
        if (Cesium.defined(height)) {
          cartographic.height = height
          clampedPosition = Cesium.Cartographic.toCartesian(cartographic)
        } else {
          // 备用方案：尝试使用 clampToHeight
          const clampedCartesian = viewer.scene.clampToHeight(position)
          if (clampedCartesian) {
            clampedPosition = clampedCartesian
          }
        }
      }

      // 使用修正后的位置进行屏幕坐标转换
      const screenPosition = viewer.scene.cartesianToCanvasCoordinates(clampedPosition)
      if (screenPosition) {
        tooltipPosition.value = {
          x: screenPosition.x,
          y: screenPosition.y
        }
      }
    } catch (error) {
      console.error('更新 Tooltip 位置失败:', error)
    }
  }

  /**
   * 注册 postRender 监听器
   * 实时更新 Tooltip 位置（相机移动时）
   */
  const registerPostRenderListener = () => {
    const viewer = getViewer()
    if (!viewer || postRenderListener) return

    postRenderListener = () => {
      updateTooltipPosition()
    }

    viewer.scene.postRender.addEventListener(postRenderListener)
  }

  /**
   * 注销 postRender 监听器
   */
  const unregisterPostRenderListener = () => {
    const viewer = getViewer()
    if (!viewer || !postRenderListener) return

    try {
      viewer.scene.postRender.removeEventListener(postRenderListener)
      postRenderListener = null
    } catch (error) {
      console.error('注销 postRender 监听器失败:', error)
    }
  }

  /**
   * 相机飞行到指定实体
   * @param {Cesium.Entity} entity - 目标实体
   * @returns {Promise<void>}
   */
  const flyToEntity = async (entity) => {
    const viewer = getViewer()
    if (!viewer || !config.flyToPoint) return

    try {
      const position = entity.position?.getValue(Cesium.JulianDate.now())
      if (!position) return

      await viewer.camera.flyTo({
        destination: position,
        duration: config.flyDuration,
        offset: new Cesium.HeadingPitchRange(
          0,
          Cesium.Math.toRadians(-45),
          config.flyDistance
        )
      })
    } catch (error) {
      console.error('相机飞行失败:', error)
    }
  }

  /**
   * 显示 Tooltip
   * @param {Cesium.Entity} entity - 目标实体
   * @param {Object} data - 详情数据
   */
  const showTooltip = (entity, data) => {
    selectedEntity.value = entity
    tooltipData.value = data
    tooltipVisible.value = true
    updateTooltipPosition()
    registerPostRenderListener()
  }

  /**
   * 隐藏 Tooltip
   */
  const hideTooltip = () => {
    tooltipVisible.value = false
    tooltipPosition.value = null
    tooltipData.value = {}
    selectedEntity.value = null
    error.value = ''
    unregisterPostRenderListener()
  }

  // ==================== 核心逻辑 ====================

  /**
   * 处理应急力量实体点击
   * @param {Cesium.Entity} entity - 被点击的实体
   */
  const handleEmergencyForceClick = async (entity) => {
    // 取消之前的请求
    cancelRequest()

    // 提取 rid
    const rid = entity.properties?.rid?.getValue()

    if (!rid) {
      console.warn('应急力量实体缺少 rid 属性')
      error.value = '缺少标识信息'
      showTooltip(entity, {})
      return
    }

    // 显示加载状态
    loading.value = true
    error.value = ''
    showTooltip(entity, {})

    // 可选：飞行到点位
    await flyToEntity(entity)

    // 创建取消控制器
    const controller = new AbortController()
    abortController.value = controller

    try {
      // 请求详情数据
      const response = await fetchEmergencyForceDetail(rid, {
        signal: controller.signal
      })

      // 检查是否仍然选中该实体
      if (selectedEntity.value !== entity) {
        return
      }

      // 解析响应数据
      let detailData = response
      if (response && typeof response === 'object') {
        if (response.data) {
          detailData = response.data
        }
      }

      // 更新 Tooltip 数据
      tooltipData.value = {
        qxmc: detailData.qxmc || '',
        yjllpz: detailData.yjllpz || '',
        wzQtwz: detailData.wzQtwz || ''
      }
    } catch (err) {
      // 处理请求取消
      if (err.name === 'AbortError' || err.name === 'CanceledError') {
        return
      }

      // 处理其他错误
      console.error('加载应急力量详情失败:', err)

      let errorMessage = '加载失败'
      if (err.response) {
        errorMessage += `: ${err.response.status}`
        if (err.response.data?.message) {
          errorMessage += ` - ${err.response.data.message}`
        }
      } else if (err.message) {
        errorMessage += `: ${err.message}`
      }

      error.value = errorMessage
    } finally {
      loading.value = false
      abortController.value = null
    }
  }

  /**
   * 处理地图点击事件
   * @param {Object} click - 点击事件对象
   */
  const handleMapClick = (click) => {
    if (!enabled.value) return

    const viewer = getViewer()
    if (!viewer) return

    try {
      // 拾取点击的对象
      const pickedObject = viewer.scene.pick(click.position)

      // 检查是否点击了应急力量实体
      if (
        pickedObject &&
        pickedObject.id &&
        pickedObject.id.id &&
        typeof pickedObject.id.id === 'string' &&
        pickedObject.id.id.startsWith('emergencyForce-')
      ) {
        // 点击了应急力量标记
        handleEmergencyForceClick(pickedObject.id)
      } else {
        // 点击了其他地方，隐藏 Tooltip
        if (tooltipVisible.value) {
          hideTooltip()
        }
      }
    } catch (error) {
      console.error('处理地图点击失败:', error)
    }
  }

  /**
   * 注册点击事件监听器
   */
  const registerClickHandler = () => {
    const viewer = getViewer()
    if (!viewer) {
      console.warn('无法注册点击事件：地图未就绪')
      return
    }

    // 避免重复注册
    if (clickHandler) {
      console.warn('点击事件已注册')
      return
    }

    try {
      clickHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      clickHandler.setInputAction(
        handleMapClick,
        Cesium.ScreenSpaceEventType.LEFT_CLICK
      )
      console.log('应急力量点击事件已注册')
    } catch (error) {
      console.error('注册点击事件失败', error)
    }
  }

  /**
   * 注销点击事件监听器
   */
  const unregisterClickHandler = () => {
    if (clickHandler) {
      try {
        clickHandler.destroy()
        clickHandler = null
        console.log('应急力量点击事件已注销')
      } catch (error) {
        console.error('注销点击事件失败', error)
      }
    }
  }

  /**
   * 清理所有资源
   */
  const cleanup = () => {
    cancelRequest()
    hideTooltip()
    unregisterClickHandler()
    unregisterPostRenderListener()
    loading.value = false
  }

  // ==================== 生命周期 ====================

  /**
   * 监听启用状态变化
   */
  watch(enabled, (newValue) => {
    if (newValue) {
      // 启用交互
      if (mapStore.isReady()) {
        registerClickHandler()
      } else {
        // 等待地图就绪
        mapStore.onReady(() => {
          if (enabled.value) {
            registerClickHandler()
          }
        })
      }
    } else {
      // 禁用交互
      cleanup()
    }
  })

  /**
   * 组件卸载前清理
   */
  onBeforeUnmount(() => {
    cleanup()
  })

  // ==================== 返回接口 ====================

  return {
    // 状态
    enabled,
    loading,
    tooltipVisible,
    tooltipPosition,
    tooltipData,
    error,

    // 方法
    cleanup,
    hideTooltip
  }
}
