<template>
  <div class="container">
    <canvas ref="canvas"></canvas>
    <div class="controls">
      <button @click="toggleSimulation">{{ isSimulating ? '停止' : '开始' }}模拟</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const canvas = ref(null)
const ctx = ref(null)
const isSimulating = ref(false)
const simulationInterval = ref(null)
const ws = ref(null)

// 状态管理
const state = ref({
  path: [],       // 飞行路径 [{x, y, heading}]
  currentPos: { x: 0, y: 0, heading: 0 }, // 当前无人机状态
  canvasSize: { width: 0, height: 0 }
})

// 初始化Canvas
const initCanvas = () => {
  const container = document.querySelector('.container')
  state.value.canvasSize = {
    width: container.clientWidth,
    height: container.clientHeight - 40
  }

  canvas.value.width = state.value.canvasSize.width
  canvas.value.height = state.value.canvasSize.height
  ctx.value = canvas.value.getContext('2d')
}

// 绘制无人机（固定翼）
const drawDrone = (x, y, heading) => {
  ctx.value.save()
  ctx.value.translate(x, y)
  ctx.value.rotate((heading * Math.PI) / 180)

  // 绘制机身（三角形）
  ctx.value.beginPath()
  ctx.value.moveTo(0, 0)
  ctx.value.lineTo(-15, 10)
  ctx.value.lineTo(-15, -10)
  ctx.value.closePath()
  ctx.value.fillStyle = '#2c3e50'
  ctx.value.fill()

  // 绘制螺旋桨（圆形）
  ctx.value.beginPath()
  ctx.value.arc(5, 0, 5, 0, Math.PI * 2)
  ctx.value.fillStyle = '#e74c3c'
  ctx.value.fill()

  ctx.value.restore()
}

// 绘制飞行轨迹
const drawPath = () => {
  if (state.value.path.length < 2) return

  ctx.value.beginPath()
  ctx.value.strokeStyle = 'rgba(52, 152, 219, 0.8)'
  ctx.value.lineWidth = 2

  state.value.path.forEach((point, index) => {
    if (index === 0) {
      ctx.value.moveTo(point.x, point.y)
    } else {
      ctx.value.lineTo(point.x, point.y)
    }
  })

  ctx.value.stroke()
}

// 主绘制函数
const draw = () => {
  if (!ctx.value) return

  // 清空画布
  ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)

  // 绘制背景网格
  drawGrid()

  // 绘制轨迹
  drawPath()

  // 绘制无人机
  drawDrone(
    state.value.currentPos.x,
    state.value.currentPos.y,
    state.value.currentPos.heading
  )
}

// 绘制背景网格
const drawGrid = () => {
  ctx.value.strokeStyle = '#ecf0f1'
  ctx.value.lineWidth = 0.5

  // 水平线
  for (let y = 0; y < canvas.value.height; y += 50) {
    ctx.value.beginPath()
    ctx.value.moveTo(0, y)
    ctx.value.lineTo(canvas.value.width, y)
    ctx.value.stroke()
  }

  // 垂直线
  for (let x = 0; x < canvas.value.width; x += 50) {
    ctx.value.beginPath()
    ctx.value.moveTo(x, 0)
    ctx.value.lineTo(x, canvas.value.height)
    ctx.value.stroke()
  }
}

// WebSocket处理
const initWebSocket = () => {
  ws.value = new WebSocket('ws://localhost:8080/flight-data')

  ws.value.onmessage = (event) => {
    const data = JSON.parse(event.data)
    updatePosition(data)
  }

  ws.value.onclose = () => {
    console.log('WebSocket连接关闭')
  }
}

// 更新位置数据
const updatePosition = (data) => {
  state.value.path.push({ ...data })
  state.value.currentPos = data

  // 保持路径长度不超过200个点
  if (state.value.path.length > 200) {
    state.value.path.shift()
  }

  draw()
}

// 模拟数据生成（用于测试）
const generateMockData = () => {
  let x = state.value.canvasSize.width / 2
  let y = state.value.canvasSize.height / 2
  let angle = 0

  return () => {
    angle += 2
    x += 3 * Math.cos(angle * Math.PI / 180)
    y += 3 * Math.sin(angle * Math.PI / 180)

    return {
      x: x % state.value.canvasSize.width,
      y: y % state.value.canvasSize.height,
      heading: angle % 360
    }
  }
}

// 切换模拟
const toggleSimulation = () => {
  isSimulating.value = !isSimulating.value

  if (isSimulating.value) {
    const mockGenerator = generateMockData()
    simulationInterval.value = setInterval(() => {
      updatePosition(mockGenerator())
    }, 50)
  } else {
    clearInterval(simulationInterval.value)
  }
}

// 生命周期钩子
onMounted(() => {
  initCanvas()
  initWebSocket()
  window.addEventListener('resize', initCanvas)
})

onUnmounted(() => {
  window.removeEventListener('resize', initCanvas)
  if (ws.value) ws.value.close()
  if (simulationInterval.value) clearInterval(simulationInterval.value)
})
</script>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  background: #34495e;
  position: relative;
}

canvas {
  background: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.controls {
  position: absolute;
  top: 20px;
  right: 20px;
}

button {
  padding: 8px 16px;
  background: #3498db;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.3s;
}

button:hover {
  background: #2980b9;
}
</style>
