import { ref } from 'vue'
import * as Cesium from 'cesium'
import { useMapStore } from '@/map'
import {
  BEFORE_IMAGERY_CONFIG,
  AFTER_IMAGERY_CONFIG,
  SPLIT_CONFIG,
  getModelCompareConfig
} from '../config/modelCompare.config'
import { use3DTiles } from './use3DTiles'
import { useMapMarkers } from './useMapMarkers'

/**
 * 调试模式开关
 * 生产环境自动关闭详细日志
 */
const DEBUG = import.meta.env.DEV

/**
 * 图层标识常量
 * @constant {string} BEFORE_LAYER_ID - 灾前现场实景图层 ID
 * @constant {string} AFTER_LAYER_ID - 灾后现场实景图层 ID
 */
const BEFORE_LAYER_ID = BEFORE_IMAGERY_CONFIG.id
const AFTER_LAYER_ID = AFTER_IMAGERY_CONFIG.id

/**
 * 模型对比（灾前/灾后影像对比）业务逻辑
 *
 * 技术方案：
 * - 使用单个 Cesium 实例，通过 imagery split（影像分屏）实现左右对比视图
 * - 左侧显示灾前现场实景，右侧显示灾后现场实景
 * - 默认只显示灾后影像，启用对比模式后同时显示两套影像
 *
 * 使用示例：
 * ```js
 * const { isModelCompareActive, initModelCompareLayers, toggleModelCompare } = useModelCompare()
 *
 * // 在地图就绪后初始化图层
 * mapStore.onReady(async () => {
 *   await initModelCompareLayers()
 * })
 *
 * // 切换对比模式
 * await toggleModelCompare(true)  // 启用
 * await toggleModelCompare(false) // 禁用
 * ```
 *
 * @returns {Object} 模型对比相关状态和方法
 * @returns {Ref<boolean>} isModelCompareActive - 模型对比模式是否激活
 * @returns {Function} initModelCompareLayers - 初始化灾前/灾后图层
 * @returns {Function} enableModelCompare - 启用模型对比模式
 * @returns {Function} disableModelCompare - 禁用模型对比模式
 * @returns {Function} toggleModelCompare - 切换模型对比模式
 */
export function useModelCompare() {
  const mapStore = useMapStore()

  // 初始化 3D Tiles 管理
  const {
    load3DTileset,
    waitForTilesetReady,
    remove3DTileset
  } = use3DTiles()

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

  /** 图层是否已初始化 */
  const initialized = ref(false)

  /** 是否正在执行切换操作（防止并发） */
  const isToggling = ref(false)

  /**
   * 其他影像图层的原始可见性状态
   * 用于在禁用对比模式后恢复原始状态，而非强制全部打开
   * Map<layerId: string, visible: boolean>
   */
  const originalLayerVisibility = new Map()

  /** 灾前 Tileset 引用（用于在禁用时移除） */
  let beforeTilesetRef = null

  /**
   * 从 viewer 中查找指定配置的 3D Tileset
   * @param {Cesium.Viewer} viewer
   * @param {string} configId - 配置ID，'before' 或 'after'
   * @returns {Cesium.Cesium3DTileset | null}
   */
  const findTilesetByConfig = (viewer, configId) => {
    if (!viewer?.scene?.primitives) return null

    const config = getModelCompareConfig()
    const targetUrl = configId === 'after' ? config.after3DTiles.url : config.before3DTiles.url

    // 遍历所有 primitives 查找匹配的 tileset
    for (let i = 0; i < viewer.scene.primitives.length; i++) {
      const primitive = viewer.scene.primitives.get(i)
      if (primitive instanceof Cesium.Cesium3DTileset) {
        // 比较 URL（去除查询参数和尾部斜杠）
        const primitiveUrl = primitive.resource?.url || primitive._url || ''
        const normalizedPrimitiveUrl = primitiveUrl.split('?')[0].replace(/\/$/, '')
        const normalizedTargetUrl = targetUrl.split('?')[0].replace(/\/$/, '')

        if (normalizedPrimitiveUrl === normalizedTargetUrl) {
          return primitive
        }
      }
    }

    return null
  }

  /**
   * 设置所有 entities 的 splitDirection
   * @param {Cesium.Viewer} viewer
   * @param {Cesium.SplitDirection} splitDirection
   */
  const setEntitiesSplitDirection = (viewer, splitDirection) => {
    if (!viewer?.entities) return

    console.log(`[useModelCompare] 设置所有 entities 的 splitDirection 为: ${splitDirection}`)
    let updatedCount = 0

    const entities = viewer.entities.values
    for (let i = 0; i < entities.length; i++) {
      const entity = entities[i]

      // 设置 entity 级别的 splitDirection
      entity.splitDirection = splitDirection

      // 设置图形属性的 splitDirection
      if (entity.billboard) {
        if (typeof entity.billboard.splitDirection === 'object' && entity.billboard.splitDirection.setValue) {
          entity.billboard.splitDirection.setValue(splitDirection)
        } else {
          entity.billboard.splitDirection = new Cesium.ConstantProperty(splitDirection)
        }
      }

      if (entity.polygon) {
        if (typeof entity.polygon.splitDirection === 'object' && entity.polygon.splitDirection.setValue) {
          entity.polygon.splitDirection.setValue(splitDirection)
        } else {
          entity.polygon.splitDirection = new Cesium.ConstantProperty(splitDirection)
        }
      }

      updatedCount++
    }

    console.log(`[useModelCompare] 已更新 ${updatedCount} 个 entities 的 splitDirection`)
  }

  /**
   * 初始化灾前/灾后影像图层
   *
   * - 仅在首次调用时创建图层
   * - 如果地图未就绪，会自动等待地图就绪后再执行
   * - 使用占位符 URL，需在接入真实数据时替换为实际影像服务地址
   *
   * @async
   * @throws {Error} 当图层创建失败时抛出错误
   */
  const initModelCompareLayers = async () => {
    // 防止重复初始化
    if (initialized.value) {
      console.log('[useModelCompare] 图层已初始化，跳过重复初始化')
      return
    }

    /**
     * 实际的图层初始化逻辑
     * @async
     * @private
     */
    const doInit = async () => {
      try {
        const { layer } = mapStore.services()

        // 获取当前环境的配置
        const config = getModelCompareConfig()

        // 检查图层是否已存在（可能被其他模块创建）
        const beforeExists = layer.getLayer(BEFORE_LAYER_ID)
        const afterExists = layer.getLayer(AFTER_LAYER_ID)

        // 创建灾前影像图层
        if (!beforeExists) {
          if (DEBUG) console.log('[useModelCompare] 创建灾前影像图层...')
          await layer.addLayer({
            id: config.before.id,
            type: 'WebTileLayer',
            url: config.before.url,
            options: {
              visible: config.before.visible,
            },
            meta: {
              title: config.before.name,
              sceneType: 'before',
              description: config.before.description
            }
          })
          if (DEBUG) console.log('[useModelCompare] 灾前影像图层创建成功')
        } else {
          if (DEBUG) console.log('[useModelCompare] 灾前影像图层已存在')
        }

        // 创建灾后影像图层
        if (!afterExists) {
          if (DEBUG) console.log('[useModelCompare] 创建灾后影像图层...')
          await layer.addLayer({
            id: config.after.id,
            type: 'WebTileLayer',
            url: config.after.url,
            options: {
              visible: config.after.visible,
            },
            meta: {
              title: config.after.name,
              sceneType: 'after',
              description: config.after.description
            }
          })
          if (DEBUG) console.log('[useModelCompare] 灾后影像图层创建成功')
        } else {
          if (DEBUG) console.log('[useModelCompare] 灾后影像图层已存在')
        }

        initialized.value = true
        if (DEBUG) console.log('[useModelCompare] 图层初始化完成')
      } catch (error) {
        console.error('[useModelCompare] 图层初始化失败:', error)
        throw new Error(`模型对比图层初始化失败: ${error.message}`)
      }
    }

    // 如果地图已就绪，直接执行初始化
    if (mapStore.isReady()) {
      await doInit()
      return
    }

    // 否则等待地图就绪后再执行
    console.log('[useModelCompare] 等待地图就绪...')
    await new Promise((resolve, reject) => {
      mapStore.onReady(async () => {
        try {
          await doInit()
          resolve()
        } catch (error) {
          reject(error)
        }
      })
    })
  }

  /**
   * 启用模型对比模式
   *
   * 启用后：
   * - 左半屏显示灾前影像
   * - 右半屏显示灾后影像
   * - 分割线位置默认为中心（0.5）
   *
   * @async
   */
  const enableModelCompare = async () => {
    if (DEBUG) console.log('[useModelCompare] 启用模型对比模式...')

    // 确保图层已初始化
    await initModelCompareLayers()

    // 如果地图未就绪，无法操作
    if (!mapStore.isReady()) {
      console.warn('[useModelCompare] 地图未就绪，无法启用对比模式')
      return
    }

    try {
      const { layer } = mapStore.services()

      // 检查图层是否存在
      const beforeLayer = layer.getLayer(BEFORE_LAYER_ID)
      const afterLayer = layer.getLayer(AFTER_LAYER_ID)

      if (!beforeLayer || !afterLayer) {
        console.error('[useModelCompare] 图层不存在，无法启用对比模式')
        throw new Error('模型对比图层不存在')
      }

      // 🔧 修复：保存其他影像图层的原始可见性状态
      // 在隐藏图层前先记录它们的状态，以便后续恢复
      originalLayerVisibility.clear() // 清空旧状态
      const allLayers = layer.listLayers()

      allLayers.forEach(layerRecord => {
        if (layerRecord.type === 'imagery' &&
            layerRecord.id !== BEFORE_LAYER_ID &&
            layerRecord.id !== AFTER_LAYER_ID) {
          // 保存原始可见性状态
          originalLayerVisibility.set(layerRecord.id, layerRecord.show)
          // 隐藏图层，避免遮挡分屏效果
          layer.showLayer(layerRecord.id, false)
        }
      })

      if (DEBUG) {
        console.log('[useModelCompare] 已保存图层状态:',
          Array.from(originalLayerVisibility.entries()))
      }

      // 左侧：灾前影像；右侧：灾后影���
      console.log('[useModelCompare] 设置灾前图层为左侧...')
      layer.setSplit(BEFORE_LAYER_ID, 'left')

      console.log('[useModelCompare] 设置灾后图层为右侧...')
      layer.setSplit(AFTER_LAYER_ID, 'right')

      // 设置分割位置为中心（可以后续扩展为可拖动调整）
      console.log('[useModelCompare] 设置分割位置为 0.5...')
      layer.setSplitPosition(0.5)

      // 直接使用新 API 设置分割位置（绕过可能的旧 API 问题）
      const viewer = mapStore.viewer
      if (viewer) {
        // 尝试新 API
        if ('splitPosition' in viewer.scene) {
          viewer.scene.splitPosition = 0.5
          console.log('[useModelCompare] 使用新 API: scene.splitPosition = 0.5')
        }
        // 兼容旧 API
        if ('imagerySplitPosition' in viewer.scene) {
          viewer.scene.imagerySplitPosition = 0.5
          console.log('[useModelCompare] 使用旧 API: scene.imagerySplitPosition = 0.5')
        }

        console.log('[useModelCompare] viewer.scene.splitPosition:', viewer.scene.splitPosition)
        console.log('[useModelCompare] viewer.scene.imagerySplitPosition:', viewer.scene.imagerySplitPosition)

        // 检查所有影像图层
        const imageryLayers = viewer.imageryLayers
        console.log('[useModelCompare] 影像图层总数:', imageryLayers.length)

        for (let i = 0; i < imageryLayers.length; i++) {
          const imgLayer = imageryLayers.get(i)
          console.log(`[useModelCompare] 图层 ${i}:`, {
            show: imgLayer.show,
            alpha: imgLayer.alpha,
            splitDirection: imgLayer.splitDirection
          })
        }
      }

      // 确保两个图层都可见
      console.log('[useModelCompare] 显示灾前图层...')
      layer.showLayer(BEFORE_LAYER_ID, true)

      console.log('[useModelCompare] 显示灾后图层...')
      layer.showLayer(AFTER_LAYER_ID, true)

      // 调试：检查设置后的状态
      const beforeLayerAfter = layer.getLayer(BEFORE_LAYER_ID)
      const afterLayerAfter = layer.getLayer(AFTER_LAYER_ID)

      console.log('[useModelCompare] 设置后的灾前图层:', beforeLayerAfter)
      console.log('[useModelCompare] 灾前图层 splitDirection (设置后):', beforeLayerAfter?.obj?.splitDirection)
      console.log('[useModelCompare] 灾前图层 show:', beforeLayerAfter?.obj?.show)

      console.log('[useModelCompare] 设置后的灾后图层:', afterLayerAfter)
      console.log('[useModelCompare] 灾后图层 splitDirection (设置后):', afterLayerAfter?.obj?.splitDirection)
      console.log('[useModelCompare] 灾后图层 show:', afterLayerAfter?.obj?.show)

      // 再次检查所有图层的最终状态
      if (viewer) {
        console.log('[useModelCompare] === 最终影像图层状态 ===')
        const imageryLayers = viewer.imageryLayers
        for (let i = 0; i < imageryLayers.length; i++) {
          const imgLayer = imageryLayers.get(i)
          console.log(`[useModelCompare] 最终图层 ${i}:`, {
            show: imgLayer.show,
            alpha: imgLayer.alpha,
            splitDirection: imgLayer.splitDirection
          })
        }
      }

      // ============ 处理 3D Tiles 模型 ============
      console.log('[useModelCompare] 开始处理 3D Tiles 模型分割...')

      // 查找灾后模型
      const afterTileset = findTilesetByConfig(viewer, 'after')
      if (afterTileset) {
        console.log('[useModelCompare] 找到灾后3D模型，设置为右侧显示')
        afterTileset.splitDirection = Cesium.SplitDirection.RIGHT
      } else {
        console.warn('[useModelCompare] 未找到灾后3D模型')
      }

      // 查找或加载灾前3D模型
      let beforeTileset = findTilesetByConfig(viewer, 'before')
      if (!beforeTileset) {
        console.log('[useModelCompare] 加载灾前3D模型...')
        beforeTileset = await load3DTileset(
          viewer,
          'before',
          false, // 不自动缩放
          Cesium.SplitDirection.LEFT // 左侧显示
        )

        if (beforeTileset) {
          // 保存引用，用于禁用时移除
          beforeTilesetRef = beforeTileset
          console.log('[useModelCompare] 灾前3D模型加载成功，等待就绪...')
          await waitForTilesetReady(beforeTileset)
          console.log('[useModelCompare] 灾前3D模型已就绪')
        } else {
          console.warn('[useModelCompare] 灾前3D模型加载失败')
        }
      } else {
        console.log('[useModelCompare] 找到已存在的灾前3D模型，设置为左侧显示')
        beforeTileset.splitDirection = Cesium.SplitDirection.LEFT
        beforeTilesetRef = beforeTileset
      }

      // ============ 处理标记点和实体 ============
      console.log('[useModelCompare] 设置所有实体为右侧显示（灾后场景）...')
      setEntitiesSplitDirection(viewer, Cesium.SplitDirection.RIGHT)

      isModelCompareActive.value = true
      console.log('[useModelCompare] 模型对比模式已启用（包含3D模型分割和标记点）')
    } catch (error) {
      console.error('[useModelCompare] 启用模型对比模式失败:', error)
      throw new Error(`启用模型对比模式失败: ${error.message}`)
    }
  }

  /**
   * 禁用模型对比模式
   *
   * 禁用后：
   * - 取消影像分屏
   * - 隐藏灾前影像
   * - 保留灾后影像作为默认视图
   * - 恢复其他图层的原始可见性状态
   *
   * @async
   */
  const disableModelCompare = async () => {
    if (DEBUG) console.log('[useModelCompare] 禁用模型对比模式...')

    // 如果地图未就绪，仅更新状态即可
    if (!mapStore.isReady()) {
      isModelCompareActive.value = false
      console.warn('[useModelCompare] 地图未就绪，仅更新状态')
      return
    }

    try {
      const { layer } = mapStore.services()
      const viewer = mapStore.viewer

      // ============ 处理影像图层 ============
      // 取消影像分屏
      layer.setSplit(BEFORE_LAYER_ID, 'none')
      layer.setSplit(AFTER_LAYER_ID, 'none')

      // 隐藏灾前图层，保留灾后图层
      layer.showLayer(BEFORE_LAYER_ID, false)
      layer.showLayer(AFTER_LAYER_ID, true)

      // 🔧 修复：恢复其他影像图层的原始可见性状态
      // 而非强制全部打开
      if (originalLayerVisibility.size > 0) {
        originalLayerVisibility.forEach((visible, layerId) => {
          layer.showLayer(layerId, visible)
        })
        if (DEBUG) {
          console.log('[useModelCompare] 已恢复影像图层状态:',
            Array.from(originalLayerVisibility.entries()))
        }
        // 清空已恢复的状态记录
        originalLayerVisibility.clear()
      }

      // ============ 处理 3D Tiles 模型 ============
      console.log('[useModelCompare] 开始恢复 3D Tiles 模型状态...')

      // 查找并恢复灾后模型为全屏显示
      const afterTileset = findTilesetByConfig(viewer, 'after')
      if (afterTileset) {
        console.log('[useModelCompare] 恢复灾后3D模型为全屏显示')
        afterTileset.splitDirection = Cesium.SplitDirection.NONE
      }

      // 移除灾前模型
      if (beforeTilesetRef) {
        console.log('[useModelCompare] 移除灾前3D模型')
        viewer.scene.primitives.remove(beforeTilesetRef)
        beforeTilesetRef = null
      }

      // ============ 处理标记点和实体 ============
      console.log('[useModelCompare] 恢复所有实体为全屏显示...')
      setEntitiesSplitDirection(viewer, Cesium.SplitDirection.NONE)

      isModelCompareActive.value = false
      if (DEBUG) console.log('[useModelCompare] 模型对比模式已禁用（包含3D模型和标记点恢复）')
    } catch (error) {
      console.error('[useModelCompare] 禁用模型对比模式失败:', error)
      throw new Error(`禁用模型对比模式失败: ${error.message}`)
    }
  }

  /**
   * 切换模型对比模式
   *
   * @async
   * @param {boolean} active - true 启用，false 禁用
   */
  const toggleModelCompare = async (active) => {
    if (DEBUG) console.log(`[useModelCompare] 切换模型对比模式: ${active ? '启用' : '禁用'}`)

    // 防止并发切换
    if (isToggling.value) {
      console.warn('[useModelCompare] 正在执行切换操作，忽略本次请求')
      return
    }

    // 如果地图未就绪，延迟执行
    if (!mapStore.isReady()) {
      console.warn('[useModelCompare] 地图未就绪，将在地图就绪后执行切换')
      await new Promise((resolve) => {
        mapStore.onReady(() => resolve())
      })
    }

    // 保存之前的状态，用于错误回滚
    const previousState = isModelCompareActive.value

    isToggling.value = true

    try {
      if (active) {
        await enableModelCompare()
      } else {
        await disableModelCompare()
      }
    } catch (error) {
      console.error('[useModelCompare] 切换模型对比模式失败:', error)
      // 在发生错误时恢复到之前的状态
      isModelCompareActive.value = previousState
      throw error
    } finally {
      isToggling.value = false
    }
  }

  return {
    // 状态
    isModelCompareActive,

    // 方法
    initModelCompareLayers,
    enableModelCompare,
    disableModelCompare,
    toggleModelCompare
  }
}

export default useModelCompare
