/**
 * 地图模块组合式函数
 * 封装地图列表、导航、编辑等功能的API调用
 *
 * 接口返回格式说明：
 * - getMapList: { status: true, maps: [], states: [] }
 * - getCurrentMap: { status: true, name: 'xxx' }
 * - renameMap: { status: true }
 * - deleteMap: { status: true }
 */
import { ref, computed } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import { saveAs } from 'file-saver'
import * as mapApi from '@/api/robot/map'
import * as controlApi from '@/api/robot/control'

export function useMapList() {
  const loading = ref(false)
  const mapList = ref([])
  const currentMap = ref(null)
  const selectedMap = ref(null)
  const thumbnailCache = new Map() // 缩略图缓存

  // 处理后端返回的地图列表数据
  // 后端返回格式: { status: true, maps: ['map1', 'map2'], states: ['available', 'building'] }
  function processMapListResponse(response) {
    if (!response) return []

    // 兼容两种返回格式
    // 格式1: { status: true, maps: [], states: [] }
    // 格式2: { code: 200, data: [...] }
    if (response.maps && Array.isArray(response.maps)) {
      return response.maps.map((mapName, index) => ({
        id: index + 1,
        map: mapName,
        mapName: mapName,
        name: mapName,
        state: response.states && response.states[index] ? response.states[index] : 'unavailable'
      }))
    }

    // 如果是标准响应格式 { code: 200, data: [...] }
    if (response.data && Array.isArray(response.data)) {
      return response.data.map((item, index) => ({
        id: item.id || index + 1,
        map: item.map || item.mapName || item.name,
        mapName: item.mapName || item.map || item.name,
        name: item.name || item.map || item.mapName,
        state: item.state || item.status || 'available',
        thumbUrl: item.thumbUrl || null
      }))
    }

    return []
  }

  // 获取地图列表
  async function fetchMapList(deviceId) {
    loading.value = true
    try {
      const res = await mapApi.getMapList(deviceId)

      // 兼容处理：request可能已经解包了data
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || (res.code === 200)) {
        mapList.value = processMapListResponse(responseData)
      } else if (res.code !== 200) {
        ElMessage.error(res.msg || '获取地图列表失败')
        mapList.value = []
      }

      return res
    } catch (error) {
      console.error('获取地图列表失败:', error)
      ElMessage.error('获取地图列表失败')
      mapList.value = []
      throw error
    } finally {
      loading.value = false
    }
  }

  // 获取当前地图
  async function fetchCurrentMap(deviceId) {
    try {
      const res = await mapApi.getCurrentMap(deviceId)

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || (res.code === 200)) {
        currentMap.value = responseData.name || responseData.data
      }
      return res
    } catch (error) {
      console.error('获取当前地图失败:', error)
      throw error
    }
  }

  // 获取地图缩略图
  async function fetchMapThumbnail(mapName) {
    if (!mapName) return null

    // 检查缓存
    if (thumbnailCache.has(mapName)) {
      return thumbnailCache.get(mapName)
    }

    try {
      const res = await mapApi.getMapThumbnail(mapName)
      
      // 检查是否是有效的blob
      // if (blob instanceof Blob && blob.size > 0) {
      //   const url = URL.createObjectURL(blob)
      //   thumbnailCache.set(mapName, url)
      //   return url
      // }
      if(res.code === 200 && res.data) {
        return res.data
      }
        
      return null
    } catch (error) {
      console.error('获取缩略图失败:', error)
      return null
    }
  }

  // 批量获取缩略图
  async function fetchThumbnailsForList(mapItems, limit = 6) {
    const items = mapItems.slice(0, limit)

    for (const item of items) {
      const mapName = item.map || item.mapName || item.name
      if (mapName && !item.thumbUrl) {
        try {
          const thumbUrl = await fetchMapThumbnail(mapName)
          if (thumbUrl) {
            item.thumbUrl = thumbUrl
          }
        } catch (e) {
          // 忽略单个缩略图加载失败
        }
      }
    }

    return mapItems
  }

  // 清除缩略图缓存
  function clearThumbnailCache() {
    thumbnailCache.forEach(url => URL.revokeObjectURL(url))
    thumbnailCache.clear()
  }

  // 重命名地图
  async function renameMap(oldName, newName) {
    try {
      const res = await mapApi.renameMap({ map: oldName, rename: newName })

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        ElMessage.success('重命名成功')
        await fetchMapList()
      } else {
        ElMessage.error(responseData.msg || res.msg || '重命名失败')
      }
      return res
    } catch (error) {
      ElMessage.error('重命名失败')
      throw error
    }
  }

  // 删除地图
  async function removeMap(mapName) {
    try {
      const res = await mapApi.deleteMap({ map: mapName })

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        ElMessage.success('删除成功')
        mapList.value = mapList.value.filter(m => (m.map || m.mapName || m.name) !== mapName)
      } else {
        ElMessage.error(responseData.msg || res.msg || '删除失败')
      }
      return res
    } catch (error) {
      ElMessage.error('删除失败')
      throw error
    }
  }

  // 下载地图
  async function downloadMap(mapName, components) {
    const loading = ElLoading.service({
      text: '正在压缩地图文件，请耐心等待...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    try {
      // 1. 压缩
      await mapApi.compressMapExport({ map: mapName, ignore: [] })

      // 2. 下载
      const blob = await mapApi.downloadMapExport(mapName)
      if (blob instanceof Blob && blob.size > 0) {
        saveAs(blob, `${mapName}.zip`)
        ElMessage.success('下载成功')
      } else {
        ElMessage.error('下载失败：文件无效')
      }
    } catch (error) {
      if (error.message?.includes('timeout')) {
        ElMessage.error('下载超时，请稍后重试')
      } else {
        ElMessage.error('下载失败')
      }
    } finally {
      loading.close()
    }
  }

  // 选择地图
  function selectMap(map) {
    selectedMap.value = map
  }

  return {
    loading,
    mapList,
    currentMap,
    selectedMap,
    fetchMapList,
    fetchCurrentMap,
    fetchMapThumbnail,
    fetchThumbnailsForList,
    clearThumbnailCache,
    renameMap,
    removeMap,
    downloadMap,
    selectMap
  }
}

export function useMapControl(deviceId) {
  // 录制/构建/SLAM状态
  const isRecording = ref(false)
  const isBuilding = ref(false)
  const isSlaming = ref(false)
  const recordingMapName = ref('')
  const buildingMapName = ref('')
  const slamMapName = ref('')
  const buildingProgress = ref(0)

  // 导航状态
  const isNavigating = ref(false)
  const currentTask = ref(null)

  // ==================== 录制操作 ====================

  async function startRecord(mapName) {
    try {
      recordingMapName.value = mapName
      isRecording.value = true
      const res = await controlApi.startRecord(deviceId, mapName)
      if (res.code === 200) {
        ElMessage.success('开始录制')
      }
      return res
    } catch (error) {
      isRecording.value = false
      ElMessage.error('开始录制失败')
      throw error
    }
  }

  async function stopRecord(mapName) {
    try {
      const res = await controlApi.stopRecord(deviceId, mapName)
      if (res.code === 200) {
        ElMessage.success('停止录制')
        isRecording.value = false
        recordingMapName.value = ''
      }
      return res
    } catch (error) {
      ElMessage.error('停止录制失败')
      throw error
    }
  }

  // ==================== 构建地图 ====================

  async function startBuild(mapName, buildSteps) {
    try {
      buildingMapName.value = mapName
      isBuilding.value = true
      buildingProgress.value = 0
      const res = await controlApi.startBuild(deviceId, mapName, buildSteps)
      if (res.code === 200) {
        ElMessage.success('开始构建地图')
      }
      return res
    } catch (error) {
      isBuilding.value = false
      ElMessage.error('开始构建失败')
      throw error
    }
  }

  async function stopBuild() {
    try {
      const res = await controlApi.stopBuild(deviceId)
      if (res.code === 200) {
        ElMessage.success('停止构建')
        isBuilding.value = false
        buildingMapName.value = ''
        buildingProgress.value = 0
      }
      return res
    } catch (error) {
      ElMessage.error('停止构建失败')
      throw error
    }
  }
  async function completedBuild(mapName, funcName) {
    try {
      const res = await controlApi.completedBuild(mapName, funcName)
      return res
    } catch (error) {
      ElMessage.error('构建失败')
      throw error
    }
  }

  function updateBuildingProgress(progress) {
    buildingProgress.value = progress
  }

  // ==================== 实时SLAM ====================

  async function startSlam(mapName) {
    try {
      slamMapName.value = mapName
      isSlaming.value = true
      const res = await controlApi.startSlam(deviceId, mapName)
      if (res.code === 200) {
        ElMessage.success('开始实时建图')
      }
      return res
    } catch (error) {
      isSlaming.value = false
      ElMessage.error('开始实时建图失败')
      throw error
    }
  }

  async function stopSlam() {
    try {
      const res = await controlApi.stopSlam(deviceId)
      if (res.code === 200) {
        ElMessage.success('停止实时建图')
        isSlaming.value = false
        // slamMapName.value = ''
      }
      return res
    } catch (error) {
      ElMessage.error('停止实时建图失败')
      throw error
    }
  }

  // ==================== 导航操作 ====================

  async function startNavigation(mapName) {
    try {
      const res = await controlApi.startNavigation(deviceId, mapName)
      if (res.code === 200) {
        ElMessage.success('开启导航')
        isNavigating.value = true
      }
      return res
    } catch (error) {
      ElMessage.error('开启导航失败')
      throw error
    }
  }

  async function stopNavigation() {
    try {
      const res = await controlApi.stopNavigation(deviceId)
      if (res.code === 200) {
        ElMessage.success('关闭导航')
        isNavigating.value = false
      }
      return res
    } catch (error) {
      ElMessage.error('关闭导航失败')
      throw error
    }
  }

  async function restartNavigation(mapName) {
    try {
      const res = await controlApi.restartNavigation(deviceId, mapName)
      if (res.code === 200) {
        ElMessage.success('重启导航')
      }
      return res
    } catch (error) {
      ElMessage.error('重启导航失败')
      throw error
    }
  }

  // ==================== 定位操作 ====================

  async function initPose(x, y, yaw) {
    try {
      const res = await controlApi.initPose(deviceId, x, y, yaw)
      if (res.code === 200) {
        ElMessage.success('位姿初始化请求已发送')
      }
      return res
    } catch (error) {
      ElMessage.error('位姿初始化失败')
      throw error
    }
  }

  async function initPoseByNid(nid) {
    try {
      const res = await controlApi.initPoseByNid(deviceId, nid)
      if (res.code === 200) {
        ElMessage.success('位姿初始化请求已发送')
      }
      return res
    } catch (error) {
      ElMessage.error('位姿初始化失败')
      throw error
    }
  }

  // ==================== 任务操作 ====================

  async function gotoTargetByNid(mapName, nid) {
    try {
      const res = await controlApi.gotoTargetByNid(deviceId, mapName, nid)
      if (res.code === 200) {
        ElMessage.info('前往目标点请求已发送')
        currentTask.value = { mapName, nid }
      }
      return res
    } catch (error) {
      ElMessage.error('前往目标点失败')
      throw error
    }
  }

  async function gotoTargetByCoord(mapName, x, y) {
    try {
      const res = await controlApi.gotoTargetByCoord(deviceId, mapName, x, y)
      if (res.code === 200) {
        ElMessage.info('前往目标点请求已发送')
        currentTask.value = { mapName, x, y }
      }
      return res
    } catch (error) {
      ElMessage.error('前往目标点失败')
      throw error
    }
  }

  async function pauseTask() {
    try {
      const res = await controlApi.pauseTask(deviceId)
      if (res.code === 200) {
        ElMessage.info('任务已暂停')
      }
      return res
    } catch (error) {
      ElMessage.error('暂停任务失败')
      throw error
    }
  }

  async function resumeTask() {
    try {
      const res = await controlApi.resumeTask(deviceId)
      if (res.code === 200) {
        ElMessage.info('任务已继续')
      }
      return res
    } catch (error) {
      ElMessage.error('继续任务失败')
      throw error
    }
  }

  async function cancelTask() {
    try {
      const res = await controlApi.cancelTask(deviceId)
      if (res.code === 200) {
        ElMessage.info('任务已取消')
        currentTask.value = null
      }
      return res
    } catch (error) {
      ElMessage.error('取消任务失败')
      throw error
    }
  }

  // ==================== 急停 ====================

  async function emergencyStop(type = 'soft') {
    try {
      const res = await controlApi.emergencyStop(deviceId, type)
      if (res.code === 200) {
        ElMessage.warning('急停指令已发送')
      }
      return res
    } catch (error) {
      ElMessage.error('急停失败')
      throw error
    }
  }

  async function releaseEmergencyStop() {
    try {
      const res = await controlApi.releaseEmergencyStop(deviceId)
      if (res.code === 200) {
        ElMessage.success('已释放急停')
      }
      return res
    } catch (error) {
      ElMessage.error('释放急停失败')
      throw error
    }
  }

  // ==================== 标定 ====================

  async function executeCalibration(mapName, calibrationPoints) {
    try {
      const res = await controlApi.executeCalibration(deviceId, mapName, calibrationPoints)
      if (res.code === 200) {
        ElMessage.success('标定请求已发送')
      }
      return res
    } catch (error) {
      ElMessage.error('标定失败')
      throw error
    }
  }

  return {
    // 状态
    isRecording,
    isBuilding,
    isSlaming,
    isNavigating,
    recordingMapName,
    buildingMapName,
    slamMapName,
    buildingProgress,
    currentTask,
    
    // 录制
    startRecord,
    stopRecord,
    
    // 构建
    startBuild,
    stopBuild,
    completedBuild,
    updateBuildingProgress,
    
    // 实时SLAM
    startSlam,
    stopSlam,
    
    // 导航
    startNavigation,
    stopNavigation,
    restartNavigation,
    
    // 定位
    initPose,
    initPoseByNid,
    
    // 任务
    gotoTargetByNid,
    gotoTargetByCoord,
    pauseTask,
    resumeTask,
    cancelTask,
    
    // 急停
    emergencyStop,
    releaseEmergencyStop,
    
    // 标定
    executeCalibration
  }
}

export function useRoadmap() {
  const loading = ref(false)
  const roadmapData = ref(null)
  const pathList = ref([])

  // 获取路网数据
  async function fetchRoadmap(mapName) {
    loading.value = true
    try {
      const res = await mapApi.getRoadMapGeoJson(mapName)

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        roadmapData.value = responseData.data
      } else {
        roadmapData.value = null
      }
      return res
    } catch (error) {
      console.error('获取路网数据失败:', error)
      ElMessage.error('获取路网数据失败')
      roadmapData.value = null
      throw error
    } finally {
      loading.value = false
    }
  }

  // 保存路网数据
  async function saveRoadmap(mapName, geoJson) {
    loading.value = true
    try {
      const res = await mapApi.saveRoadMapGeoJson({ map: mapName, geojson: geoJson })

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        ElMessage.success('保存成功')
      } else {
        ElMessage.error(responseData.msg || res.msg || '保存失败')
      }
      return res
    } catch (error) {
      ElMessage.error('保存失败')
      throw error
    } finally {
      loading.value = false
    }
  }

  // 获取任务路线列表
  async function fetchPathList(mapName) {
    try {
      const res = await mapApi.listPath(mapName)

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (res.code === 200 || responseData.status === true) {
        pathList.value = responseData.data || responseData.paths || []
      }
      return res
    } catch (error) {
      ElMessage.error('获取路线列表失败')
      throw error
    }
  }

  // 添加路线
  async function addPath(data) {
    try {
      const res = await mapApi.addPath(data)

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        ElMessage.success('添加成功')
        await fetchPathList(data.map)
      } else {
        ElMessage.error(responseData.msg || res.msg || '添加失败')
      }
      return res
    } catch (error) {
      ElMessage.error('添加失败')
      throw error
    }
  }

  // 删除路线
  async function removePath(mapName, pathName) {
    try {
      const res = await mapApi.deletePath({ map: mapName, path: pathName })

      // 兼容处理
      const responseData = res.data !== undefined ? res.data : res

      if (responseData.status === true || res.code === 200) {
        ElMessage.success('删除成功')
        pathList.value = pathList.value.filter(p => p.name !== pathName)
      } else {
        ElMessage.error(responseData.msg || res.msg || '删除失败')
      }
      return res
    } catch (error) {
      ElMessage.error('删除失败')
      throw error
    }
  }

  return {
    loading,
    roadmapData,
    pathList,
    fetchRoadmap,
    saveRoadmap,
    fetchPathList,
    addPath,
    removePath
  }
}
