import { ref, onUnmounted, watch } from 'vue'
import * as Cesium from 'cesium'
import { use3DTiles } from './use3DTiles'
import { useMapMarkers } from '../composables/useMapMarkers'

/**
 * 双地图对比模式
 * 使用两个独立的Cesium Viewer实现并排对比
 * 左侧显示灾前场景，右侧显示灾后场景
 * 单向相机同步：右侧主地图驱动，左侧对比地图跟随
 */
export function useDualMapCompare() {
  /** 左侧Viewer引用 */
  const leftViewer = ref(null)

  /** 右侧Viewer引用 */
  const rightViewer = ref(null)

  /** 对比模式是否激活 */
  const isCompareMode = ref(false)

  /** 相机同步是否启用 */
  const isCameraSyncEnabled = ref(false)

  watch(isCameraSyncEnabled, (newValue) => {
    console.log(`[useDualMapCompare] 相机同步状态变化: ${newValue}`)
    if (newValue) {
      // 启用同步
      if (leftViewer.value && rightViewer.value && !leftViewer.value.isDestroyed() && !rightViewer.value.isDestroyed()) {
        console.log('[useDualMapCompare] 自动启动相机同步')
        startCameraSync(rightViewer.value, leftViewer.value)
      } else {
        console.warn('[useDualMapCompare] 无法自动启动相机同步，Viewer未初始化或已销毁')
      }
    } else {
      // 禁用同步
      console.log('[useDualMapCompare] 自动停止相机同步')
      stopCameraSync()
    }
  })

  /** 相机同步监听器移除函数 */
  let cameraSyncRemover = null

  /** 左侧3D Tileset（灾前） */
  let leftTileset = null

  /** 右侧3D Tileset（灾后，主地图的tileset） */
  let rightTileset = null

  const { load3DTileset } = use3DTiles()

  const { drawCollapseBoundaryLeft } = useMapMarkers()

  /**
   * 初始化左侧Viewer（灾前场景）
   * @param {HTMLElement} container - 容器元素
   * @returns {Cesium.Viewer}
   */
  const initLeftViewer = (container) => {
    if (!container) {
      console.error('[useDualMapCompare] 左侧容器元素不存在')
      return null
    }

    // 验证容器尺寸
    const { clientWidth, clientHeight } = container
    console.log(`[useDualMapCompare] 左侧容器尺寸: ${clientWidth}x${clientHeight}`)

    if (clientWidth <= 0 || clientHeight <= 0) {
      console.error(`[useDualMapCompare] 左侧容器尺寸无效 (width=${clientWidth}, height=${clientHeight})`)
      return null
    }

    // 创建左侧viewer
    const viewer = new Cesium.Viewer(container, {
      animation: false,
      baseLayerPicker: false,
      fullscreenButton: false,
      geocoder: false,
      homeButton: false,
      infoBox: false,
      sceneModePicker: false,
      selectionIndicator: false,
      timeline: false,
      navigationHelpButton: false,
      scene3DOnly: true,
      shouldAnimate: false,
    })

    // 移除默认的Cesium logo和版权信息
    viewer.cesiumWidget.creditContainer.style.display = 'none'

    // 完全禁用左侧Viewer的所有交互（只作为对比显示）
    // viewer.scene.screenSpaceCameraController.enableRotate = false
    // viewer.scene.screenSpaceCameraController.enableTranslate = false
    // viewer.scene.screenSpaceCameraController.enableZoom = false
    // viewer.scene.screenSpaceCameraController.enableTilt = false
    // viewer.scene.screenSpaceCameraController.enableLook = false

    // 将 viewer 实例存储到容器上，供其他模块访问
    container._cesiumViewer = viewer

    leftViewer.value = viewer
    console.log('[useDualMapCompare] 左侧Viewer初始化成功（交互已启用）') // 关键修改

    return viewer
  }

  /**
   * 设置单向相机同步（右→左）
   * 右侧主地图驱动，左侧对比地图跟随
   * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer（主地图，驱动者）
   * @param {Cesium.Viewer} leftViewerInstance - 左侧Viewer（对比地图，跟随者）
   */
  const setupCameraSync = (rightViewerInstance, leftViewerInstance) => {
    if (!rightViewerInstance || !leftViewerInstance) {
      console.warn('[useDualMapCompare] Viewer未初始化，无法设置相机同步')
      return
    }

    console.log('[useDualMapCompare] 设置智能相机同步（右→左）...')

    /** 同步相机状态（带防抖） */
    let isSyncing = false
    const handleCameraSync = () => {
      if (isSyncing) return

      // 防御检查1：viewer 存在性检查
      if (!rightViewerInstance || !leftViewerInstance) {
        return
      }

      // 防御检查2：viewer destroyed 状态检查
      if (rightViewerInstance.isDestroyed?.() || leftViewerInstance.isDestroyed?.()) {
        return
      }

      isSyncing = true

      requestAnimationFrame(() => {
        try {
          // 再次检查（requestAnimationFrame 可能延迟执行）
          if (!rightViewerInstance || !leftViewerInstance) {
            isSyncing = false
            return
          }

          if (rightViewerInstance.isDestroyed?.() || leftViewerInstance.isDestroyed?.()) {
            isSyncing = false
            return
          }

          const rightCamera = rightViewerInstance.camera
          leftViewerInstance.camera.setView({
            destination: rightCamera.position.clone(),  // 他们演示需要不同步相机位置 只同步偏转角信息 后期取消注释
            orientation: {
              heading: rightCamera.heading,
              pitch: rightCamera.pitch,
              roll: rightCamera.roll
            }
          })
        } catch (e) {
          console.warn('[useDualMapCompare] 同步异常:', e)
        } finally {
          isSyncing = false
        }
      })
    }

    const syncController = {
      _isUserInteracting: false,
      _interactionHandlers: [], // 存储 moveStart 监听器
      _moveEndHandler: null,
      _lastPosition: null,
      _interval: null,
      _stopped: false, // 新增：原子性停止标志
      _moveEndReceived: false, // 新增：标记 moveEnd 是否已触发

      start: () => {
        // 重置停止标志
        syncController._stopped = false

        const controller = rightViewerInstance.scene.screenSpaceCameraController

        if (!controller) {
          console.error('[useDualMapCompare] screenSpaceCameraController未初始化')
          return
        }

        // 1. 事件监听逻辑
        if (typeof rightViewerInstance.camera.moveStart?.addEventListener === 'function' &&
          typeof rightViewerInstance.camera.moveEnd?.addEventListener === 'function') {

          // 监听相机移动开始
          const moveStartHandler = rightViewerInstance.camera.moveStart.addEventListener(() => {
            if (syncController._stopped) return // 检查停止标志

            syncController._isUserInteracting = true
            console.log('[useDualMapCompare] 捕获相机操作开始')

            // 改进：只在首次触发时启动递归
            const onDragFrame = () => {
              // 停止检查
              if (syncController._stopped) {
                console.log('[useDualMapCompare] 停止标志已设置，退出递归')
                return
              }

              // viewer 有效性检查
              if (!rightViewerInstance || rightViewerInstance.isDestroyed?.()) {
                console.log('[useDualMapCompare] Viewer已销毁，退出递归')
                return
              }

              if (syncController._isUserInteracting) {
                console.log('[useDualMapCompare] 主同步触发')
                handleCameraSync()
                requestAnimationFrame(onDragFrame)
              }
            }
            requestAnimationFrame(onDragFrame)
          })

          syncController._interactionHandlers.push(moveStartHandler)

          // 2. 监听相机移动结束
          syncController._moveEndHandler = rightViewerInstance.camera.moveEnd.addEventListener(() => {
            if (syncController._stopped) return // 检查停止标志

            if (syncController._isUserInteracting) {
              console.log('[useDualMapCompare] moveEnd 事件触发，等待相机完全停止...')
              // 不要立即重置 _isUserInteracting，让 setInterval 继续检测
              // 标记为"移动已结束但可能还在惯性滑动"
              syncController._moveEndReceived = true
            }
          })

        } else {
          console.warn(`[useDualMapCompare] 相机事件不可用，当前Cesium版本: ${Cesium.VERSION}`)
          return
        }

        // 3. 保险同步逻辑（setInterval）
        syncController._lastPosition = new Cesium.Cartesian3()
        syncController._moveEndReceived = false // 重置标志
        syncController._interval = setInterval(() => {
          // 停止检查
          if (syncController._stopped) return

          // viewer 有效性检查
          if (!rightViewerInstance || rightViewerInstance.isDestroyed?.()) {
            console.log('[useDualMapCompare] Viewer已销毁，停止定时同步')
            if (syncController._interval) {
              clearInterval(syncController._interval)
              syncController._interval = null
            }
            return
          }

          const isMoving = controller.isMoving
          const currentPosition = rightViewerInstance.camera.position

          if (syncController._isUserInteracting) {
            if (isMoving) {
              // 相机正在移动，持续更新位置
              Cesium.Cartesian3.clone(currentPosition, syncController._lastPosition)
              syncController._moveEndReceived = false // 重置标志
            } else {
              // 相机已停止移动
              if (syncController._moveEndReceived) {
                // moveEnd 已触发且相机已停止，执行最终同步
                const positionChanged = !Cesium.Cartesian3.equalsEpsilon(
                  currentPosition,
                  syncController._lastPosition,
                  0.001 // 更高精度
                )

                if (positionChanged) {
                  console.log('[useDualMapCompare] 相机完全停止，执行最终同步')
                  handleCameraSync()
                  Cesium.Cartesian3.clone(currentPosition, syncController._lastPosition)
                } else {
                  console.log('[useDualMapCompare] 相机完全停止，位置无变化')
                }

                // 重置状态
                syncController._isUserInteracting = false
                syncController._moveEndReceived = false
              } else {
                // 相机停止但 moveEnd 未触发（可能是微小移动后停止）
                const positionChanged = !Cesium.Cartesian3.equalsEpsilon(
                  currentPosition,
                  syncController._lastPosition,
                  0.1
                )

                if (positionChanged) {
                  console.log('[useDualMapCompare] 保险同步触发（相机停止但moveEnd未触发）')
                  handleCameraSync()
                  Cesium.Cartesian3.clone(currentPosition, syncController._lastPosition)
                  syncController._isUserInteracting = false
                }
              }
            }
          }
        }, 300)

        console.log('[useDualMapCompare] 智能同步已启动')
      },

      stop: () => {
        // 原子性设置停止标志（最优先）
        syncController._stopped = true

        // 立即清除定时器
        if (syncController._interval) {
          clearInterval(syncController._interval)
          syncController._interval = null
        }

        // 移除事件监听器（需要检查 viewer 是否仍然有效）
        if (rightViewerInstance && !rightViewerInstance.isDestroyed?.()) {
          syncController._interactionHandlers.forEach(handler => {
            if (typeof rightViewerInstance.camera.moveStart?.removeEventListener === 'function') {
              try {
                rightViewerInstance.camera.moveStart.removeEventListener(handler)
              } catch (e) {
                console.warn('[useDualMapCompare] 移除 moveStart 监听器失败:', e)
              }
            }
          })

          if (syncController._moveEndHandler &&
            typeof rightViewerInstance.camera.moveEnd?.removeEventListener === 'function') {
            try {
              rightViewerInstance.camera.moveEnd.removeEventListener(syncController._moveEndHandler)
            } catch (e) {
              console.warn('[useDualMapCompare] 移除 moveEnd 监听器失败:', e)
            }
          }
        }

        syncController._interactionHandlers = []
        syncController._moveEndHandler = null
        syncController._isUserInteracting = false
        syncController._moveEndReceived = false // 重置标志
        syncController._lastPosition = null

        console.log('[useDualMapCompare] 智能同步已完全停止')
      }
    }


    // 启动监听
    syncController.start()

    // 保存移除函数
    cameraSyncRemover = () => {
      syncController.stop()
      console.log('[useDualMapCompare] 智能同步已移除')
    }

    console.log('[useDualMapCompare] 智能同步设置完成')
  }

  /**
   * 启动相机同步
   * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer（主地图，驱动者）
   * @param {Cesium.Viewer} leftViewerInstance - 左侧Viewer（对比地图，跟随者）
   */
  const startCameraSync = (rightViewerInstance, leftViewerInstance) => {
    if (isCameraSyncEnabled.value) {
      setupCameraSync(rightViewerInstance, leftViewerInstance)
      console.log('[useDualMapCompare] 相机同步已启用')
    } else {
      console.warn('[useDualMapCompare] 尝试启用相机同步，但同步开关未开启')
    }
  }

  /**
   * 停止相机同步
   */
  const stopCameraSync = () => {
    if (cameraSyncRemover) {
      cameraSyncRemover()
      cameraSyncRemover = null
      console.log('[useDualMapCompare] 相机同步已停止')
    }
  }

  /**
   * 切换相机同步开关
   * @param {boolean} active - true启用，false禁用
   */
  const toggleCameraSync = (active) => {
    console.log(`[useDualMapCompare] 手动切换相机同步: ${active}`)
    isCameraSyncEnabled.value = active
  }

  /**
   * 启用对比模式
   * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer实例（主地图，灾后场景）
   * @param {Object} options - 配置选项
   * @param {boolean} options.skipLeftModelLoad - 是否跳过左侧模型加载
   * @param {boolean} options.loadLeftModel - 是否仅加载左侧模型（不重新初始化Viewer）
   */
  const enableCompareMode = async (rightViewerInstance, options = {}) => {
    const { skipLeftModelLoad = false, loadLeftModel = false } = options

    // 前置检查: viewer
    if (!rightViewerInstance) {
      const error = new Error('右侧主地图Viewer未初始化')
      console.error('[useDualMapCompare]', error.message)
      throw error
    }

    // 如果只是加载左侧模型（Viewer已存在）
    if (loadLeftModel && leftViewer.value) {
      console.log('[useDualMapCompare] 加载左侧灾前模型...')

      // 在加载模型前，确保左侧相机位置与右侧同步
      if (rightViewerInstance && leftViewer.value) {
        console.log('[useDualMapCompare] 同步相机位置（延迟加载场景）...')
        const rightCamera = rightViewerInstance.camera

        try {
          // 获取右侧相机位置
          const rightPosition = rightCamera.position.clone()

          // 计算右侧相机的右方向向量
          const rightDirection = Cesium.Cartesian3.normalize(
            rightCamera.right,
            new Cesium.Cartesian3()
          )

          // 向左偏移90米
          const offsetPosition = Cesium.Cartesian3.add(
            rightPosition,
            Cesium.Cartesian3.multiplyByScalar(rightDirection, -90, new Cesium.Cartesian3()),
            new Cesium.Cartesian3()
          )

          // 设置左侧相机位置（向左偏移90米）
          leftViewer.value.camera.setView({
            destination: offsetPosition,
            orientation: {
              heading: rightCamera.heading,
              pitch: rightCamera.pitch,
              roll: rightCamera.roll
            }
          })

          // 强制更新
          leftViewer.value.scene.requestRender()
          leftViewer.value.camera.changed.raiseEvent()

          console.log('[useDualMapCompare] 相机位置同步完成')
        } catch (error) {
          console.error('[useDualMapCompare] 相机同步失败:', error)
        }
      }

      try {
        const tileset = await load3DTileset(leftViewer.value, 'before', false)
        if (tileset) {
          leftTileset = tileset
          console.log('[useDualMapCompare] 左侧灾前模型加载完成')
        }
      } catch (error) {
        console.error('[useDualMapCompare] 左侧模型加载失败:', error)
      }
      return
    }

    console.log('[useDualMapCompare] 启用对比模式...')

    rightViewer.value = rightViewerInstance

    // 查找左侧容器（容器已存在于DOM中）
    const leftContainer = document.getElementById('leftCesiumContainer')
    if (!leftContainer) {
      const error = new Error('找不到左侧容器元素 #leftCesiumContainer')
      console.error('[useDualMapCompare]', error.message)
      throw error
    }

    // 先设置状态，触发CSS动画
    isCompareMode.value = true

    // 增强型布局等待策略
    await new Promise(resolve => {
      // 1. 基础等待 → 2. 强制重绘 → 3. 循环检查
      setTimeout(() => {
        // 强制触发浏览器重绘
        void leftContainer.offsetWidth

        // 3. 循环验证容器尺寸
        const startTime = Date.now()
        const checkLayout = () => {
          if (leftContainer.clientWidth > 0 && leftContainer.clientHeight > 0) {
            resolve()
          } else if (Date.now() - startTime < 2000) { // 总等待不超过2秒
            setTimeout(checkLayout, 50)
          } else {
            console.error('左侧容器最终尺寸：',
              `width: ${leftContainer.clientWidth}px, height: ${leftContainer.clientHeight}px`)
            throw new Error('左侧容器布局超时')
          }
        }
        checkLayout()
      }, 350) // 原等待时间保持
    })

    // 初始化左侧Viewer
    const leftViewerInstance = initLeftViewer(leftContainer)
    if (!leftViewerInstance) {
      const error = new Error('左侧Viewer初始化失败')
      console.error('[useDualMapCompare]', error.message)
      isCompareMode.value = false  // 回滚状态
      throw error
    }

    // 等待左侧 viewer 完全初始化
    await new Promise(resolve => setTimeout(resolve, 100))

    // 立即同步右侧相机的当前位置到左侧（关键修复）
    console.log('[useDualMapCompare] 同步初始相机位置...')
    const rightCamera = rightViewerInstance.camera

    // 记录当前右侧相机状态
    console.log('[useDualMapCompare] 右侧相机位置:', {
      position: rightCamera.position,
      heading: Cesium.Math.toDegrees(rightCamera.heading),
      pitch: Cesium.Math.toDegrees(rightCamera.pitch),
      roll: Cesium.Math.toDegrees(rightCamera.roll)
    })

    // 强制同步相机位置（使用多种方式确保成功）
    try {
      // 获取右侧相机位置
      const rightPosition = rightCamera.position.clone()

      // 计算右侧相机的右方向向量
      const rightDirection = Cesium.Cartesian3.normalize(
        rightCamera.right,
        new Cesium.Cartesian3()
      )

      // 向左偏移90米
      const offsetPosition = Cesium.Cartesian3.add(
        rightPosition,
        Cesium.Cartesian3.multiplyByScalar(rightDirection, -90, new Cesium.Cartesian3()),
        new Cesium.Cartesian3()
      )

      // 方式1: 使用 setView (推荐)
      leftViewerInstance.camera.setView({
        destination: offsetPosition,
        orientation: {
          heading: rightCamera.heading,
          pitch: rightCamera.pitch,
          roll: rightCamera.roll
        }
      })

      // 方式2: 直接设置相机属性 (备份方案)
      leftViewerInstance.camera.position = offsetPosition.clone()
      leftViewerInstance.camera.direction = rightCamera.direction.clone()
      leftViewerInstance.camera.up = rightCamera.up.clone()
      leftViewerInstance.camera.right = rightCamera.right.clone()
      console.log('[useDualMapCompare] 初始相机同步成功（向左偏移90米）')

      // 验证同步结果
      const leftCamera = leftViewerInstance.camera
      console.log('[useDualMapCompare] 左侧相机位置:', {
        position: leftCamera.position,
        heading: Cesium.Math.toDegrees(leftCamera.heading),
        pitch: Cesium.Math.toDegrees(leftCamera.pitch),
        roll: Cesium.Math.toDegrees(leftCamera.roll)
      })
    } catch (error) {
      console.error('[useDualMapCompare] 初始相机同步失败:', error)
    }

    // 强制渲染左侧场景
    leftViewerInstance.scene.requestRender()
    leftViewerInstance.camera.changed.raiseEvent()

    // 设置相机同步（单向：右→左），根据开关状态来决定是否启动
    if (isCameraSyncEnabled.value) {
      startCameraSync(rightViewerInstance, leftViewerInstance)
    }

    // 根据选项决定是否加载左侧模型
    if (!skipLeftModelLoad) {
      // 异步加载灾前模型到左侧（不阻塞对比模式启用）
      console.log('[useDualMapCompare] 开始异步加载左侧灾前模型...')
      load3DTileset(leftViewerInstance, 'before', false)
        .then(tileset => {
          if (tileset) {
            leftTileset = tileset
            console.log('[useDualMapCompare] 左侧灾前模型加载完成')
          }
        })
        .catch(error => {
          console.error('[useDualMapCompare] 左侧模型加载失败:', error)
        })
    } else {
      console.log('[useDualMapCompare] 跳过左侧模型加载（将延迟加载）')
    }

    // 右侧保持灾后模型（已加载）

    // 触发左侧viewer resize
    setTimeout(() => {
      if (leftViewerInstance && leftViewerInstance.canvas) {
        leftViewerInstance.resize()
        leftViewerInstance.camera.changed.raiseEvent()
      }
      // 同时触发右侧viewer resize
      if (rightViewerInstance && rightViewerInstance.canvas) {
        rightViewerInstance.resize()
      }
    }, 350)

    console.log('[useDualMapCompare] 对比模式已启用')
  }

  /**
   * 禁用对比模式
   */
  const disableCompareMode = () => {
    console.log('[useDualMapCompare] 禁用对比模式...')

    // 移除相机同步
    stopCameraSync()

    // 销毁左侧Viewer
    if (leftViewer.value && !leftViewer.value.isDestroyed()) {
      // 清理左侧tileset
      if (leftTileset) {
        leftViewer.value.scene.primitives.remove(leftTileset)
        leftTileset = null
      }

      leftViewer.value.destroy()
      leftViewer.value = null
      console.log('[useDualMapCompare] 左侧Viewer已销毁')
    }

    // 清理容器上的 viewer 引用
    const leftContainer = document.getElementById('leftCesiumContainer')
    if (leftContainer && leftContainer._cesiumViewer) {
      delete leftContainer._cesiumViewer
      console.log('[useDualMapCompare] 已清理容器上的 viewer 引用')
    }

    // 触发右侧viewer resize恢复全屏
    if (rightViewer.value && !rightViewer.value.isDestroyed()) {
      setTimeout(() => {
        if (rightViewer.value && rightViewer.value.canvas) {
          rightViewer.value.resize()
        }
      }, 350)
    }

    isCompareMode.value = false
    console.log('[useDualMapCompare] 对比模式已禁用')
  }

  /**
   * 切换对比模式
   * @param {boolean} active - true启用，false禁用
   * @param {Cesium.Viewer} rightViewerInstance - 右侧Viewer实例（主地图）
   * @param {Object} options - 配置选项（传递给 enableCompareMode）
   * @throws {Error} 当切换失败时抛出错误
   */
  const toggleCompareMode = async (active, rightViewerInstance, options) => {
    try {
      console.log(`[useDualMapCompare] 切换对比模式: ${active}`)

      if (active) {
        // 前置检查
        if (!rightViewerInstance) {
          throw new Error('右侧Viewer未初始化,无法启用对比模式')
        }

        await enableCompareMode(rightViewerInstance, options)
        const leftContainer = document.getElementById('leftCesiumContainer')
        if (leftContainer) {
          console.log('[index.vue] 绘制左侧坍塌边界红色虚线...')
          drawCollapseBoundaryLeft(leftContainer)

          console.log('[index.vue] 左侧坍塌边界红色虚线已添加')
        }
      } else {
        disableCompareMode()
      }

      console.log(`[useDualMapCompare] 对比模式切换成功: ${active}`)
    } catch (error) {
      console.error('[useDualMapCompare] 切换对比模式失败:', error)

      // 确保状态回滚
      isCompareMode.value = !active

      // 向上层传播错误
      throw error
    }
  }

  // 清理
  onUnmounted(() => {
    disableCompareMode()
  })

  return {
    leftViewer,
    rightViewer,
    isCompareMode,
    isCameraSyncEnabled,
    enableCompareMode,
    disableCompareMode,
    toggleCompareMode,
    toggleCameraSync,
    startCameraSync,
    stopCameraSync
  }
}

export default useDualMapCompare
