<template>
  <div class="vslam-container">
    <div class="header">
      <h3>地图: {{ mapName }}</h3>
      <div class="controls">
        <el-button type="primary" :icon="VideoPlay" :loading="isPlaying" @click="handlePlay">
          {{ isPlaying ? '播放中' : '开始预览' }}
        </el-button>
        <el-button :icon="Download" @click="handleDownload">下载点云</el-button>
        <el-button @click="handleRefresh">刷新统计</el-button>
      </div>
    </div>

    <div class="content">
      <div class="map-area">
        <OlMap
          ref="olMapRef"
          :map-name="mapName"
          :robot-pose-data="robotPoseData"
          :show-road-network="false"
          :show-point-cloud="showPointCloud"
          @point-cloud-load-end="handlePointCloudLoadEnd"
        />
      </div>

      <div class="stats-panel">
        <h4>实时统计</h4>
        <div class="stat-grid">
          <div class="stat-item">
            <span class="label">关键帧</span>
            <span class="value">{{ statsData.keyFrameCount || 0 }}</span>
          </div>
          <div class="stat-item">
            <span class="label">地图点数</span>
            <span class="value">{{ (statsData.mapPoints || 0).toLocaleString() }}</span>
          </div>
          <div class="stat-item">
            <span class="label">机器人位置</span>
            <span class="value">
              {{ robotPose.x.toFixed(2) }}, {{ robotPose.y.toFixed(2) }}
            </span>
          </div>
          <div class="stat-item">
            <span class="label">朝向角</span>
            <span class="value">{{ (robotPose.heading || 0).toFixed(2) }}°</span>
          </div>
          <div class="stat-item">
            <span class="label">定位状态</span>
            <span class="value" :class="statsData.localizationStatus === 2 ? 'success' : 'warning'">
              {{ getLocalizationStatusText(statsData.localizationStatus) }}
            </span>
          </div>
          <div class="stat-item">
            <span class="label">匹配分数</span>
            <span class="value">{{ statsData.matchScore || 0 }}</span>
          </div>
        </div>

        <h4>点云信息</h4>
        <div class="point-cloud-info">
          <el-checkbox v-model="showPointCloud">显示点云</el-checkbox>
          <el-slider
            v-model="pointCloudSize"
            :min="1"
            :max="10"
            :step="0.5"
            label="点云大小"
          />
          <span>点云大小: {{ pointCloudSize }}</span>
          <el-progress
            :percentage="pointCloudProgress"
            :status="pointCloudProgress >= 100 ? 'success' : undefined"
          />
          <span>{{ pointCloudProgress >= 100 ? '点云加载完成' : '点云加载中...' }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { VideoPlay, Download } from '@element-plus/icons-vue'
import OlMap from '@/components/OlMap/index.vue'
import { useWebSocket } from '@/composables/useWebSocket'
import * as mapApi from '@/api/robot/map'

const route = useRoute()
const router = useRouter()

const mapName = ref(decodeURIComponent(route.params.mapId || ''))
const olMapRef = ref(null)
const isPlaying = ref(false)
const showPointCloud = ref(true)
const pointCloudSize = ref(2)
const pointCloudProgress = ref(0)
const statsData = ref({})
const robotPose = ref({ x: 0, y: 0, heading: 0 })
const robotPoseData = computed(() => robotPose.value)

const deviceId = 'ld000001'
let statsTimer = null

const { robotPose: wsPose } = useWebSocket(deviceId, {
  onPose: (data) => {
    const pose = data.data
    if (pose?.xyz) {
      robotPose.value = { x: pose.xyz[0], y: pose.xyz[1], heading: pose.heading }
    }
  }
})

function getLocalizationStatusText(status) {
  const map = { 0: '初始化', 1: '追踪中', 2: '已定位', 3: '丢失' }
  return map[status] || '未知'
}

async function fetchStats() {
  try {
    const res = await mapApi.getVSlamStatistics(mapName.value)
    if (res.code === 200) {
      statsData.value = res.data || {}
    }
  } catch (e) {
    console.error('获取VSLAM统计失败:', e)
  }
}

function handlePlay() {
  isPlaying.value = !isPlaying.value
  if (isPlaying.value) {
    statsTimer = setInterval(fetchStats, 2000)
    ElMessage.success('开始预览')
  } else {
    if (statsTimer) {
      clearInterval(statsTimer)
      statsTimer = null
    }
    ElMessage.info('停止预览')
  }
}

async function handleDownload() {
  try {
    ElMessage.info('正在请求点云数据...')
    const blob = await mapApi.getPointcloud()
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `${mapName.value}.pcd`
    a.click()
    URL.revokeObjectURL(url)
    ElMessage.success('下载完成')
  } catch (e) {
    ElMessage.error('下载失败')
  }
}

function handleRefresh() {
  fetchStats()
  ElMessage.success('已刷新')
}

function handlePointCloudLoadEnd(totalPoints) {
  pointCloudProgress.value = 100
}

onMounted(async () => {
  if (!mapName.value) {
    ElMessage.error('未指定地图')
    router.back()
    return
  }
  await fetchStats()
  if (showPointCloud.value && olMapRef.value) {
    olMapRef.value.loadPointCloud()
  }
})

onBeforeUnmount(() => {
  if (statsTimer) {
    clearInterval(statsTimer)
  }
})
</script>

<style lang="scss" scoped>
.vslam-container {
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
}
.header {
  padding: 12px 20px;
  background: var(--el-bg-color);
  border-bottom: 1px solid var(--el-border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  h3 { margin: 0; }
}
.content {
  flex: 1;
  display: flex;
  overflow: hidden;
}
.map-area {
  flex: 1;
  position: relative;
}
.stats-panel {
  width: 320px;
  background: var(--el-bg-color);
  border-left: 1px solid var(--el-border-color);
  padding: 16px;
  overflow-y: auto;
  h4 {
    margin: 0 0 12px;
    font-size: 14px;
    color: var(--el-text-color-primary);
    border-bottom: 1px solid var(--el-border-color-light);
    padding-bottom: 8px;
  }
}
.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 20px;
}
.stat-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  .label { font-size: 12px; color: var(--el-text-color-secondary); }
  .value { font-size: 14px; font-weight: 500; }
  .success { color: var(--el-color-success); }
  .warning { color: var(--el-color-warning); }
}
.point-cloud-info {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 13px;
}
</style>
