<template>
  <div class="navigation-container">
    <div class="map-stage" ref="mapStage">
      <div class="main-content">
        <!-- 当前操作类型标记 -->
        <div class="hand-ment-mark">
          <el-tag type="danger" effect="dark" size="small" v-if="nowHandMenu">{{ nowHandMenu }}</el-tag>
        </div>

        <!-- 障碍物警告提示 -->
        <div class="obstacle-warning" v-if="obstacleWarning.show" :class="'obstacle-' + obstacleWarning.level">
          <div class="warning-content">
            <div class="warning-icon">
              <i class="el-icon-warning-outline" v-if="obstacleWarning.level === 'warning'"></i>
              <i class="el-icon-error" v-if="obstacleWarning.level === 'danger'"></i>
              <i class="el-icon-info" v-if="obstacleWarning.level === 'info'"></i>
            </div>
            <div class="warning-text">
              <div class="warning-title">障碍物检测</div>
              <div class="warning-message">{{ obstacleWarning.message }}</div>
              <div class="obstacle-distances" v-if="obstacleData.left > 0 || obstacleData.front > 0 || obstacleData.right > 0">
                <span v-if="obstacleData.left > 0" class="distance-item">
                  左: {{ obstacleData.left.toFixed(1) }}m
                </span>
                <span v-if="obstacleData.front > 0" class="distance-item">
                  前: {{ obstacleData.front.toFixed(1) }}m
                </span>
                <span v-if="obstacleData.right > 0" class="distance-item">
                  右: {{ obstacleData.right.toFixed(1) }}m
                </span>
              </div>
            </div>
            <div class="warning-close" @click="closeObstacleWarning">
              <i class="el-icon-close"></i>
            </div>
          </div>
        </div>

        <!-- 遇障停车提示（基于run_state） -->
        <div class="obstacle-stop-warning" v-if="obstacleStopState.showWarning">
          <div class="stop-warning-content">
            <div class="countdown-circle">
              <div class="countdown-number">
                {{ obstacleStopState.replanTimeLeft > 999 ? '999+' : obstacleStopState.replanTimeLeft }}
              </div>
              <div class="countdown-label">秒</div>
            </div>
            <div class="stop-warning-text">
              <div class="stop-warning-title">遇障停车</div>
              <div class="stop-warning-message">检测到前方障碍物，系统将自动重规划路径</div>
              <div class="stop-warning-state">当前状态: {{ obstacleStopState.runStateText }}</div>
            </div>
            <div class="stop-warning-actions">
              <el-button
                type="primary"
                size="small"
                @click="handleReplanRequest"
                :disabled="obstacleStopState.isReplanning"
              >
                {{ obstacleStopState.isReplanning ? '重规划中...' : '立即重规划' }}
              </el-button>
            </div>
          </div>
        </div>

        <!-- 地图组件 -->
        <OlMap 
          ref="olmap" 
          :width="olWidth + 'px'" 
          :height="olHeight + 'px'" 
          backgroundColor="#F5F5F5" 
          :mapName="mapName"
          :pointSwitch="settingParams.pointId" 
          :baseLayerShow="settingParams.baseMap" :robotPoseData="laserPositionData"
          :pointSelectionEnabled="selectPointMode" :poseInitEnable="initPoseMode" @addNowPoint="addNowPoint"
          :isRobotFollow="settingParams.follow" @initNavigationResult="initNavigationResult"
          :showPointcloud="settingParams.pointCloud"
          :showRoadNetwork="settingParams.showRoadNetwork"
          :showDefaultControls="false"></OlMap>

        <!-- 左侧工具条浮层 -->
        <MapToolbar
          class="nav-toolbar"
          preset="nav"
          :selectedKey="selectedKey"
          :hasRobotPosition="true"
          :isConnected="true"
          :isBusy="false"
          :isFullscreen="isFullscreen"
          @zoom-in="onZoomIn"
          @zoom-out="onZoomOut"
          @center-robot="onCenterRobot"
          @toggle-fullscreen="onToggleFullscreen"
          @confirm-init="handleConfirmInit"
          @confirm-reboot="handleConfirmReboot"
          @confirm-stop="handleConfirmStop"
        />

        <!-- 右侧信息面板浮层 -->
        <RightPanel
          mode="nav"
          panelType="nav"
          :overlay="true"
          v-model:visible="rightVisible"
          :realtime-info="realtimeInfo"
          :waypoint-list="waypoints"
          :task-list="tasks"
          :setting-params="settingParams"
          :emergency-stop-enabled="emergencyStopEnabled"
          :navigation-stack-status="navigationStackStatus"
          :current-navigation-task="currentNavigationTask"
          :navigation-status="navigationStatus"
          :is-navigating="isNavigating"
          @wp-select="onWpSelect"
          @wp-send="onWpSend"
          @wp-create="onWpCreate"
          @wp-edit="onWpEdit"
          @wp-remove="onWpRemove"
          @wp-move-up="onWpMoveUp"
          @wp-move-down="onWpMoveDown"
          @wp-batch-remove="onWpBatchRemove"
          @wp-goto="onWpGoto"
          @wp-goto-single="onWpGotoSingle"
          @wp-create-task="onWpCreateTask"
          @wp-selection-change="onWpSelectionChange"
          @map-select-mode-change="onMapSelectModeChange"
          @task-view="onTaskView"
          @task-edit="onTaskEdit"
          @task-start="onTaskStart"
          @task-pause="onTaskPause"
          @task-resume="onTaskResume"
          @task-stop="onTaskStop"
          @task-remove="onTaskRemove"
          @setting-change="onSettingChange"
          @emergency-stop-release="executeEmergencyStopRelease"
          @navigation-pause="handleNavigationPause"
          @navigation-resume="handleNavigationResume"
          @navigation-stop="handleNavigationStop"
        />
      </div>

      <!-- 目标点编辑对话框 -->
      <el-dialog
        title="目标点编辑"
        v-model="pointEditDiaShow"
        width="480px"
        @close="clearActionDia"
        class="waypoint-edit-dialog"
        :close-on-click-modal="false"
        center
      >
        <div class="dialog-content">
          <el-form :model="pointEditData" label-width="90px" size="small" class="waypoint-form">
            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-location-outline"></i>
                位置信息
              </h4>
              <el-form-item label="X坐标(m)">
                <el-input v-model="pointEditData.x" placeholder="请输入X坐标值" class="coordinate-input">
                </el-input>
              </el-form-item>
              <el-form-item label="Y坐标(m)">
                <el-input v-model="pointEditData.y" placeholder="请输入Y坐标值" class="coordinate-input">
                </el-input>
              </el-form-item>
            </div>

            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-guide"></i>
                路径配置
              </h4>
              <el-form-item label="规划类型">
                <el-select v-model="pointEditData.type" placeholder="请选择路径类型" style="width: 100%">
                  <el-option v-for="item in planOptions" :key="item.value" :label="item.label" :value="item.value">
                    <span style="float: left">{{ item.label }}</span>
                    <span style="float: right; color: #8492a6; font-size: 13px">{{ item.value === 0 ? '自由规划' : '路网约束' }}</span>
                  </el-option>
                </el-select>
              </el-form-item>
            </div>

            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-setting"></i>
                动作配置
                <el-button type="text" size="small" @click="appendActionMenu" class="add-action-btn">
                  <i class="el-icon-plus"></i><span>添加动作</span>
                </el-button>
              </h4>
              <div class="action-list">
                <div v-for="(item, index) in pointEditData.actionMenuList" :key="index" class="action-item">
                  <div class="action-header">
                    <span class="action-index">{{ index + 1 }}</span>
                    <el-select v-model="item.value" placeholder="请选择动作" size="small" @change="changeAction(index)" style="flex: 1;">
                      <el-option v-for="option in actionOptions" :key="option.value" :label="option.label" :value="option.value"></el-option>
                    </el-select>
                    <el-button v-if="index > 0" type="text" size="small" @click="removeActionMenu(index)" class="remove-btn">
                      <i class="el-icon-close"></i>
                    </el-button>
                  </div>
                  <div v-if="'other' in item" class="action-params">
                    <el-input v-model="item.other" placeholder="等待时间" size="small" style="width: 120px;">
                      <template #append>秒</template>
                    </el-input>
                  </div>
                </div>
              </div>
            </div>
          </el-form>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="pointEditDiaShow = false">取 消</el-button>
            <el-button type="primary" @click="submitEditPoint">
              <i class="el-icon-check"></i> 保存修改
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 创建任务对话框 -->
      <el-dialog
        title="创建任务"
        v-model="taskGenerateDiaShow"
        width="480px"
        @close="closeTaskGenerate"
        class="task-create-dialog"
        :close-on-click-modal="false"
        center
      >
        <div class="dialog-content">
          <el-form :model="generateTaskParam" label-width="90px" size="small" class="task-form">
            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-s-order"></i>
                任务信息
              </h4>
              <el-form-item label="任务名称">
                <el-input v-model="generateTaskParam.taskName" placeholder="请输入任务名称" class="task-input">
                </el-input>
              </el-form-item>
              <el-form-item label="执行次数">
                <el-input-number
                  v-model="generateTaskParam.count"
                  controls-position="right"
                  :min="1"
                  :max="100"
                  class="task-input-number"
                  style="width: 100%"
                ></el-input-number>
              </el-form-item>
            </div>

            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-time"></i>
                执行计划
              </h4>
              <el-form-item label="开始时间">
                <el-time-picker
                  v-model="generateTaskParam.time"
                  format="HH:mm"
                  value-format="HH:mm:ss"
                  :picker-options="{
                    selectableRange: '00:00:00 - 23:59:59'
                  }"
                  placeholder="选择时间"
                  class="task-time-picker"
                  style="width: 100%"
                >
                </el-time-picker>
              </el-form-item>
              <el-form-item label="执行日期">
                <el-checkbox-group v-model="generateTaskParam.date" class="task-date-group">
                  <el-checkbox label="1">周一</el-checkbox>
                  <el-checkbox label="2">周二</el-checkbox>
                  <el-checkbox label="3">周三</el-checkbox>
                  <el-checkbox label="4">周四</el-checkbox>
                  <el-checkbox label="5">周五</el-checkbox>
                  <el-checkbox label="6">周六</el-checkbox>
                  <el-checkbox label="7">周日</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </div>
          </el-form>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="closeTaskGenerate()">取 消</el-button>
            <el-button type="primary" @click="submitTaskGenerate">
              <i class="el-icon-check"></i> 创建任务
            </el-button>
          </span>
        </template>
      </el-dialog>

      <!-- 任务编辑对话框 -->
      <el-dialog
        title="编辑任务"
        v-model="taskEditDiaShow"
        width="480px"
        @close="closeTaskEdit"
        class="task-create-dialog"
        :close-on-click-modal="false"
        center
      >
        <div class="dialog-content">
          <el-form :model="editTaskParam" label-width="90px" size="small" class="task-form">
            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-s-order"></i>
                任务信息
              </h4>
              <el-form-item label="任务名称">
                <el-input v-model="editTaskParam.taskName" placeholder="请输入任务名称" class="task-input">
                </el-input>
              </el-form-item>
              <el-form-item label="执行次数">
                <el-input-number
                  v-model="editTaskParam.count"
                  controls-position="right"
                  :min="1"
                  :max="100"
                  class="task-input-number"
                  style="width: 100%"
                ></el-input-number>
              </el-form-item>
            </div>

            <div class="form-section">
              <h4 class="section-title">
                <i class="el-icon-time"></i>
                执行计划
              </h4>
              <el-form-item label="开始时间">
                <el-time-picker
                  v-model="editTaskParam.time"
                  format="HH:mm"
                  value-format="HH:mm:ss"
                  :picker-options="{
                    selectableRange: '00:00:00 - 23:59:59'
                  }"
                  placeholder="选择时间"
                  class="task-time-picker"
                  style="width: 100%"
                >
                </el-time-picker>
              </el-form-item>
              <el-form-item label="执行日期">
                <el-checkbox-group v-model="editTaskParam.date" class="task-date-group">
                  <el-checkbox label="1">周一</el-checkbox>
                  <el-checkbox label="2">周二</el-checkbox>
                  <el-checkbox label="3">周三</el-checkbox>
                  <el-checkbox label="4">周四</el-checkbox>
                  <el-checkbox label="5">周五</el-checkbox>
                  <el-checkbox label="6">周六</el-checkbox>
                  <el-checkbox label="7">周日</el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </div>
          </el-form>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="closeTaskEdit()">取 消</el-button>
            <el-button type="primary" @click="submitTaskEdit">
              <i class="el-icon-check"></i> 保存修改
            </el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onBeforeUnmount, onActivated, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import OlMap from "@/components/OlMap"
import MapToolbar from "../components/shared/MapToolbar.vue"
import RightPanel from "../components/shared/RightPanel.vue"
import { FullscreenOperations, RobotPositionUtils } from "@/utils/map-operations"
import { listTask, addTask, delTask, getTask, updateTask, updateTaskStatus } from "@/api/map/task"
import { initWebSocket, disconnect, sendMessage } from "@/utils/websocket"
import {
  initPose,
  initPoseByNid,
  startNavigation,
  stopNavigation,
  restartNavigation,
  startNavStandard,
  gotoTargetByCoord,
  gotoTarget,
  requestPlanning,
  startTask,
  pauseTask,
  resumeTask,
  cancelTask,
  replan,
  emergencyStop,
  releaseEmergencyStop
} from "@/api/robot/mqtt"

// 获取路由
const route = useRoute()

// WebSocket设备ID
const wsDeviceId = ref('ld000001')

// Refs
const mapStage = ref(null)
const olmap = ref(null)

const nowHandMenu = ref('')
const mapName = ref(route.params.mapName || '')
const laserPositionData = reactive({
  x: 0,
  y: 0,
  angle: 0
})

// 设置相关
const settingDrawer = ref(false)
const pointDrawer = ref(false)
const taskDrawer = ref(false)
const pointEditDiaShow = ref(false)
const taskGenerateDiaShow = ref(false)
const taskEditDiaShow = ref(false)
const taskViewDiaShow = ref(false)

const selectPointMode = ref(false)
const initPoseMode = ref(false)

const settingParams = reactive({
  pointCloud: false,
  baseMap: true,
  pointId: false,
  follow: false,
  network: false,
  showRoadNetwork: true
})

const single = ref(true)
const multiple = ref(true)
const taskDataList = ref([])

// 目标点编辑数据
const pointEditData = reactive({
  id: '',
  x: '',
  y: '',
  type: '',
  actionMenuList: []
})

// 生成任务参数
const generateTaskParam = reactive({
  taskId: '',
  taskName: '',
  count: 1,
  time: '',
  date: [],
  selectedWaypoints: []
})

// 编辑任务参数
const editTaskParam = reactive({
  originalTaskName: '',
  taskId: '',
  taskName: '',
  count: 1,
  time: '',
  date: [],
  selectedWaypoints: []
})

const taskViewData = ref({})
const pointList = ref([])
const pointIds = ref([])

// 选项
const planOptions = ref([
  { label: '自由路径', value: 0 },
  { label: '路网路径', value: 1 }
])

const actionOptions = ref([
  { label: '原地等待', value: 0 },
  { label: '开始录制', value: 1 },
  { label: '结束录制', value: 2 },
  { label: '添加建图轨迹', value: 3 },
  { label: '挂钩挂载', value: 4 },
  { label: '挂钩卸载', value: 5 }
])

const olWidth = ref(0)
const olHeight = ref(0)

const panelVisible = ref(true)
const rightVisible = ref(true)
const activeTab = ref('info')
const lastTab = ref('info')

const mockTasks = ref([
  { id: 1, name: '巡检任务A', nodes: 5, status: 'idle' },
  { id: 2, name: '运输任务B', nodes: 3, status: 'running' },
  { id: 3, name: '清扫任务C', nodes: 8, status: 'paused' }
])

const realtimeInfo = reactive({
  currentMap: route.params.mapName || 'Unknown',
  currentTask: '',
  speed: '',
  speedCommand: '',
  coordinates: '',
  heading: '',
  totalDistance: '',
  registrationError: '',
  batteryLevel: '',
  batteryDetails: {
    capacity: 0,
    temperature: 0,
    voltage: 0,
    current: 0,
    charging: false,
    other: []
  }
})

const robotPoseData = reactive({
  x: 1.813,
  y: -63.931,
  angle: 0.000
})

const isConnected = ref(true)
const isBusy = ref(false)
const isFullscreen = ref(false)

const navigationStackStatus = ref('unknown')
const emergencyStopEnabled = ref(false)

const fullscreenCleanup = ref(null)

// 目标点相关
const selectedWaypointIds = ref([])
const waypointSingle = ref(true)
const waypointMultiple = ref(true)

// 导航相关
const waypoints = ref([])
const currentNavigationTask = ref(null)
const isNavigating = ref(false)
const navigationStatus = ref('idle')
const lastGotoRequest = ref(null)

// 任务相关
const currentExecutingTask = ref(null)
const taskQueue = ref([])
const isTaskExecuting = ref(false)
const taskExecutionStatus = ref('idle')
const currentTaskWaypointIndex = ref(0)
const taskRealtimeInfo = reactive({
  odom: { total: 0, remain: 0 },
  time: { total: 0, remain: 0, duration: 0 },
  driveMode: 'auto',
  autoReady: true
})
const lastTaskExecRequest = ref(null)
const tasks = ref([])

const currentViewTaskWaypointIds = ref([])
const taskViewAutoCloseTimer = ref(null)
const taskListTimer = ref(null)

// 定时任务
const scheduledTasksToday = ref([])
const scheduledTasksExecuted = ref([])
const currentScheduledTask = ref(null)
const lastTaskStartTime = ref({})
const autoExecuteTimer = ref(null)
const autoExecuteEnabled = ref(true)

// 障碍物检测
const obstacleData = reactive({
  left: 0,
  front: 0,
  right: 0,
  timestamp: 0
})

const obstacleWarning = reactive({
  show: false,
  level: 'info',
  message: '',
  direction: '',
  distance: 0,
  autoHideTimer: null
})

const obstacleSettings = reactive({
  warningDistance: 3.0,
  dangerDistance: 1.0,
  autoHideDelay: 5000,
  enableWarning: true
})

const obstacleStopState = reactive({
  counter: 0,
  replanTimeLeft: 0,
  showWarning: false,
  isReplanning: false,
  runState: 0,
  runStateText: '未知'
})

// Computed
const selectedKey = computed(() => {
  if (initPoseMode.value) return 'init-pose'
  return ''
})

const robotPosition = computed(() => {
  if (robotPoseData && (robotPoseData.x !== 0 || robotPoseData.y !== 0)) {
    return [robotPoseData.x, robotPoseData.y]
  }
  return null
})

const hasValidRobotPosition = computed(() => {
  return !!robotPosition.value
})

const isMapReady = computed(() => {
  return !!getMapInstance()
})

const navigationStatusText = computed(() => {
  switch(navigationStatus.value) {
    case 'idle': return '空闲'
    case 'planning': return '规划中'
    case 'navigating': return '导航中'
    case 'arrived': return '已到达'
    case 'failed': return '失败'
    default: return '未知'
  }
})

const canStartNavigation = computed(() => {
  return !isNavigating.value && navigationStatus.value !== 'planning'
})

const currentNavigationTarget = computed(() => {
  if (!currentNavigationTask.value) return null
  const waypoint = currentNavigationTask.value.waypoint
  return `${waypoint.name || '目标点' + waypoint.id} (${waypoint.x}, ${waypoint.y})`
})

const taskExecutionStatusText = computed(() => {
  switch(taskExecutionStatus.value) {
    case 'idle': return '空闲'
    case 'executing': return '执行中'
    case 'paused': return '暂停'
    case 'completed': return '已完成'
    case 'failed': return '失败'
    case 'cancelled': return '已取消'
    default: return '未知'
  }
})

const currentTaskDescription = computed(() => {
  if (!currentExecutingTask.value) return null
  const task = currentExecutingTask.value
  const progress = `${currentTaskWaypointIndex.value}/${task.points?.length || 0}`
  return `${task.taskName} (${progress})`
})

const canStartNewTask = computed(() => {
  return !isTaskExecuting.value && !isNavigating.value
})

const taskProgressInfo = computed(() => {
  if (!currentExecutingTask.value || !taskRealtimeInfo) return null
  return {
    taskName: currentExecutingTask.value.taskName,
    waypointProgress: `${currentTaskWaypointIndex.value}/${currentExecutingTask.value.points?.length || 0}`,
    totalDistance: `${(taskRealtimeInfo.odom.total / 1000).toFixed(2)}km`,
    remainDistance: `${(taskRealtimeInfo.odom.remain / 1000).toFixed(2)}km`,
    totalTime: formatSeconds(taskRealtimeInfo.time.total),
    remainTime: formatSeconds(taskRealtimeInfo.time.remain),
    duration: formatSeconds(taskRealtimeInfo.time.duration),
    driveMode: taskRealtimeInfo.driveMode === 'auto' ? '自动' : '手动',
    autoReady: taskRealtimeInfo.autoReady
  }
})

const todayScheduleInfo = computed(() => {
  const pendingTasks = scheduledTasksToday.value.filter(
    taskName => !scheduledTasksExecuted.value.includes(taskName) &&
    (!currentScheduledTask.value || currentScheduledTask.value.name !== taskName)
  )
  return {
    total: scheduledTasksToday.value.length,
    executed: scheduledTasksExecuted.value.length,
    running: currentScheduledTask.value ? 1 : 0,
    pending: pendingTasks.length,
    currentRunning: currentScheduledTask.value,
    pendingList: pendingTasks
  }
})

const hasScheduleRunning = computed(() => {
  return currentScheduledTask.value !== null
})

const scheduledTasksPending = computed(() => {
  return scheduledTasksToday.value.filter(
    taskName => !scheduledTasksExecuted.value.includes(taskName) &&
    (!currentScheduledTask.value || currentScheduledTask.value.name !== taskName)
  )
})

// Watch
watch(() => route.params.mapName, (newMapName, oldMapName) => {
  console.log("mapName变化检测:", { newMapName, oldMapName });
  
  if (newMapName && newMapName !== mapName.value) {
    console.log(`路由变化，更新mapName: ${oldMapName} -> ${newMapName}`)
    mapName.value = newMapName
  }
})

watch(panelVisible, () => {
  nextTick(() => {
    updateOlCss()
  })
})

watch(selectPointMode, (newVal) => {
  if (newVal) {
    initPoseMode.value = false
  }
})

watch(initPoseMode, (newVal) => {
  if (newVal) {
    selectPointMode.value = false
  }
})

watch(() => realtimeInfo.coordinates, (newCoordinates) => {
  if (newCoordinates) {
    const position = RobotPositionUtils.parseCoordinates(newCoordinates)
    if (position) {
      robotPoseData.x = position.x
      robotPoseData.y = position.y
    }
  }
}, { immediate: true })

// 生命周期
onMounted(() => {
  console.log("route.params.mapName",route.params.mapName);
  
  // 使用 nextTick 确保 DOM 尺寸已计算
  nextTick(() => {
    updateOlCss()
    // 地图容器尺寸初始化后再次调用确保生效
    setTimeout(() => {
      updateOlCss()
      // 调用 OlMap 组件的 updateMapSize 确保地图正确初始化
      if (olmap.value && olmap.value.updateMapSize) {
        olmap.value.updateMapSize()
      }
      const map = getMapInstance()
      if (map) {
        map.updateSize()
      }
    }, 200)
  })
  
  window.addEventListener('resize', updateOlCss)

  // 初始化WebSocket连接
  initWebSocketConnection()

  loadTaskList()
  startTaskListTimer()

  fullscreenCleanup.value = FullscreenOperations.addFullscreenListener((fsIsFullscreen) => {
    isFullscreen.value = fsIsFullscreen
    nextTick(() => {
      updateOlCss()
      const map = getMapInstance()
      if (map) {
        map.updateSize()
      }
    })
  })

  setInterval(() => {
    calculateTodayScheduledTasks()
  }, 60 * 60 * 1000)

  startAutoExecuteTimer()
})

onActivated(() => {
  console.log('导航页面被激活')

  const newMapName = route.params.mapName || ''
  console.log("mapName变化检测",route.params.mapName);
  
  if (mapName.value !== newMapName) {
    console.log(`更新mapName: ${mapName.value} -> ${newMapName}`)
    mapName.value = newMapName
  }

  nextTick(() => {
    updateOlCss()
    
    // 调用 OlMap 组件的 updateMapSize 确保地图正确初始化
    if (olmap.value && olmap.value.updateMapSize) {
      olmap.value.updateMapSize()
    }

    const map = getMapInstance()
    if (map) {
      setTimeout(() => {
        map.updateSize()
        console.log('地图尺寸已更新')
      }, 100)
    }

    if (olmap.value && olmap.value.refresh) {
      setTimeout(() => {
        olmap.value.refresh()
      }, 150)
    }
  })
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', updateOlCss)

  if (fullscreenCleanup.value) {
    fullscreenCleanup.value()
  }

  if (taskViewAutoCloseTimer.value) {
    clearTimeout(taskViewAutoCloseTimer.value)
  }

  stopTaskListTimer()
  stopAutoExecuteTimer()

  if (obstacleWarning.autoHideTimer) {
    clearTimeout(obstacleWarning.autoHideTimer)
  }

  // 断开WebSocket连接
  disconnect()
})

// 方法
const goto = () => {
  // 原有功能已移至其他方法
}

// WebSocket消息处理
const handleWsMessage = (type, message) => {
  console.log("主题：",type);
  switch (type) {
    case 'pose':
      handleLaserPose(message)
      break
    case 'task':
      handleTaskRealtimeInfoFromWs(message)
      break
    case 'trajectory':
      handleTrajectoryDataFromWs(message)
      break
    case 'arrive':
      handleArriveEventFromWs(message)
      break
    case 'navigation':
      handleNavigationResponseFromWs(message)
      break
    case 'planning':
      handlePlanningResponseFromWs(message)
      break
    case 'raw':
      // 处理通过WebSocket转发的原始数据
      if (message.topic && message.topic.includes('battery')) {
        handleBatteryDataFromRaw(message)
      }
      break
    case 'asm':
      handleAsmResponseFromWs(message)
      break
    case 'battery':
      // 处理电池信息
      handleBatteryInfoFromWs(message)
      break
  }
}

// 初始化WebSocket连接
const initWebSocketConnection = () => {
  initWebSocket({
    // deviceId: wsDeviceId.value,
    onConnect: () => {
      console.log('[Navigation] WebSocket连接成功')
    },
    onDisconnect: () => {
      console.log('[Navigation] WebSocket连接断开')
    },
    onMessage: (type, message) => {
      handleWsMessage(type, message)
    },
    onError: (error) => {
      console.error('[Navigation] WebSocket错误:', error)
    }
  })
}

const handleInitReply = (message) => {
  // 初始化回复处理
}

// 通过WebSocket发送消息的辅助函数
const sendWsMessage = (topic, data) => {
  const destination = `${topic}`
  sendMessage(destination, data)
}

// WebSocket版本的位姿消息处理
const handleLaserPoseFromWs = (message) => {
  console.log("接受到pose消息",message);
  
  try {
    const pose = message.data || message
    const { xyz, rpy } = pose

    const oldX = laserPositionData.x
    const oldY = laserPositionData.y

    laserPositionData.x = xyz[0]
    laserPositionData.y = xyz[1]
    laserPositionData.angle = rpy[2]

    realtimeInfo.coordinates = `(${xyz[0]}, ${xyz[1]}, ${xyz[2] || 0})`
    realtimeInfo.heading = rpy[2] + '°'

    if (pose.velocity || pose.heading) {
      realtimeInfo.speed = (pose.heading || 0) + 'm/s'
      realtimeInfo.speedCommand = (pose.velocity || 0) + 'm/s'
    }

    if (pose.odometer !== undefined) {
      realtimeInfo.totalDistance = pose.odometer + 'm'
    }

    if (pose.confidence !== undefined) {
      realtimeInfo.registrationError = pose.confidence
    }

    const positionChanged = Math.abs(xyz[0] - oldX) > 0.005 || Math.abs(xyz[1] - oldY) > 0.005

    if (positionChanged && olmap.value && olmap.value.currentTrajectory) {
      const currentTrajectory = olmap.value.currentTrajectory
      if (currentTrajectory && currentTrajectory.length > 0) {
        const distanceToTarget = calculateDistanceToTrajectory([laserPositionData.x, laserPositionData.y], currentTrajectory)
        const progress = calculateCurrentProgress(currentTrajectory)
        if (progress > 0) {
          progressInfo.progress = progress
        }
      }
    }
  } catch (error) {
    console.error('[Navigation] 解析位姿消息失败:', error)
  }
}

// WebSocket版本的任务实时信息处理
const handleTaskRealtimeInfoFromWs = (message) => {
  try {
    const data = message.payload || message
    if (data.battery !== undefined) {
      realtimeInfo.batteryLevel = (data.battery * 100).toFixed(2) + '%'
    }
    if (data.state !== undefined) {
      realtimeInfo.robotState = data.state
    }
  } catch (error) {
    console.error('[Navigation] 解析任务实时信息失败:', error)
  }
}

// WebSocket版本的轨迹数据处理
const handleTrajectoryDataFromWs = (message) => {
  handleTrajectoryData(message)
}

// WebSocket版本的到达事件处理
const handleArriveEventFromWs = (message) => {
  handleArriveEvent(message)
}

// WebSocket版本的导航响应处理
const handleNavigationResponseFromWs = (message) => {
  const data = message.payload || message
  // 处理导航相关的响应
  if (data.success !== undefined) {
    if (data.action === 'start') {
      handleNavigationStartReply(data)
    } else if (data.action === 'stop') {
      handleNavigationStopReply(data)
    }
  }
}

// WebSocket版本的规划响应处理
const handlePlanningResponseFromWs = (message) => {
  handlePlanResponse(message)
}

// WebSocket版本的ASM响应处理
const handleAsmResponseFromWs = (message) => {
  const data = message.payload || message
  if (data.result !== undefined) {
    handleNavigationRestartReply(data)
  }
}

// 处理电池信息
const handleBatteryInfoFromWs = (message) => {
  try {
    const data = message.data || message
    if (data.capacity !== undefined) {
      // capacity范围0.0~1.0，转换为百分比
      const capacityPercent = (data.capacity * 100).toFixed(0)
      realtimeInfo.batteryLevel = capacityPercent + '%'

      // 更新电池详细信息
      if (realtimeInfo.batteryDetails === undefined) {
        realtimeInfo.batteryDetails = {}
      }
      realtimeInfo.batteryDetails.capacity = data.capacity
      realtimeInfo.batteryDetails.temperature = data.temperature
      realtimeInfo.batteryDetails.voltage = data.voltage
      realtimeInfo.batteryDetails.current = data.current
      realtimeInfo.batteryDetails.charging = data.charging
      realtimeInfo.batteryDetails.other = data.other

      console.log(`[Navigation] 电池信息更新: ${capacityPercent}%, 温度: ${data.temperature}°C, 电压: ${data.voltage}V, 充电: ${data.charging}`)
    }
  } catch (error) {
    console.error('[Navigation] 解析电池信息失败:', error)
  }
}

// 处理原始数据中的电池信息
const handleBatteryDataFromRaw = (message) => {
  try {
    const data = message.payload || message
    if (data.capacity !== undefined) {
      const capacityPercent = (data.capacity * 100).toFixed(0)
      realtimeInfo.batteryLevel = capacityPercent + '%'
    }
  } catch (error) {
    console.error('[Navigation] 解析原始电池信息失败:', error)
  }
}

const handleLaserPose = (message) => {
  try {
    const data = message.data || message
    const { xyz, rpy, blh, heading } = data

    const oldX = laserPositionData.x
    const oldY = laserPositionData.y

    laserPositionData.x = xyz[0]
    laserPositionData.y = xyz[1]
    laserPositionData.angle = rpy[2]

    realtimeInfo.coordinates = `(${xyz[0]}, ${xyz[1]}, ${xyz[2]})`
    realtimeInfo.heading = rpy[2] + '°'
    realtimeInfo.speed = data.heading !== null ? data.heading : 0 + 'm/s'
    realtimeInfo.speedCommand = data.velocity !== null ? data.velocity : 0 + 'm/s'
    realtimeInfo.totalDistance = data.odometer !== null ? data.odometer : 0 + 'm'
    realtimeInfo.registrationError = data.confidence

    if (data.runState !== null && data.runState !== undefined) {
      obstacleStopState.runState = data.runState
      obstacleStopState.runStateText = getRunStateText(data.runState)

      if (data.runState === 4) {
        if (obstacleStopState.counter < 25) {
          obstacleStopState.counter++
        }
        if (obstacleStopState.isReplanning) {
          obstacleStopState.isReplanning = false
        }
      } else {
        if (obstacleStopState.counter > 0) {
          obstacleStopState.counter--
        }
      }
    }

    if (data.replan !== undefined) {
      obstacleStopState.replanTimeLeft = data.replan
    }

    if (obstacleStopState.counter >= 20) {
      if (!obstacleStopState.showWarning) {
        obstacleStopState.showWarning = true
        console.log('检测到稳定遇障状态，显示警告')
      }
    } else {
      if (obstacleStopState.showWarning) {
        obstacleStopState.showWarning = false
        console.log('遇障状态解除，隐藏警告')
      }
    }

    const positionChanged = Math.abs(xyz[0] - oldX) > 0.005 || Math.abs(xyz[1] - oldY) > 0.005

    if (positionChanged && olmap.value && olmap.value.currentTrajectory) {
      const currentTrajectory = olmap.value.currentTrajectory
      const reachedTarget = checkIfReachedTarget(currentTrajectory)

      if (!reachedTarget) {
        console.log(`机器人位置更新，重新绘制实时轨迹: (${xyz[0].toFixed(3)}, ${xyz[1].toFixed(3)})`)
        if (olmap.value.updateRealtimeTrajectory) {
          olmap.value.updateRealtimeTrajectory([xyz[0], xyz[1]])
        }
      }
    }
  } catch (e) {
    console.error("解析失败:", e)
  }
}

const handlePlanResponse = (message) => {
  console.log("路径规划响应:", message)
  if (message.status === 'ok' && message.args && message.args.length > 0) {
    const planData = message.args[0]
    console.log("规划路径数据:", planData)

    if (planData.path && planData.path.length > 0) {
      const plannedPath = planData.path.map(point => {
        if (planData.div) {
          return [point[0] / planData.div, point[1] / planData.div]
        }
        return [point[0], point[1]]
      })

      console.log("绘制规划路径，点数:", plannedPath.length)

      if (olmap.value && olmap.value.clearTrajectory) {
        olmap.value.clearTrajectory()
        console.log('已清除旧轨迹，准备绘制新的规划路径')
      }

      if (olmap.value && olmap.value.drawTrajectory) {
        olmap.value.drawTrajectory(plannedPath, {
          totalPoints: plannedPath.length,
          currentProgress: 0,
          robotPosition: [laserPositionData.x, laserPositionData.y]
        })
      }

      ElMessage.success(`路径规划成功！规划路径共 ${plannedPath.length} 个点`)
    } else {
      ElMessage.success('路径规划成功！')
    }
  } else {
    ElMessage.error('路径规划失败')
  }
}

const handleTrajectoryData = (message) => {
  console.log("接收到轨迹数据:", message)

  if (!isNavigating.value && !currentNavigationTask.value) {
    console.log('非导航状态，忽略轨迹数据（可能是retain消息）')
    return
  }

  try {
    if (message.args && message.args.length > 0) {
      const trajectoryData = message.args[0]
      const { trj, idx, total, div } = trajectoryData

      const realTrajectory = trj.map(point => [
        point[0] / div,
        point[1] / div
      ])

      const currentProgress = calculateCurrentProgress(realTrajectory)

      if (olmap.value && olmap.value.clearTrajectory) {
        olmap.value.clearTrajectory()
        console.log('已清除旧轨迹，准备绘制新的实时轨迹')
      }

      if (olmap.value && olmap.value.drawTrajectory) {
        olmap.value.drawTrajectory(realTrajectory, {
          totalPoints: total,
          indices: idx,
          currentProgress: currentProgress,
          robotPosition: [laserPositionData.x, laserPositionData.y]
        })
      }

      console.log("轨迹绘制完成，总点数:", total, "轨迹点数:", realTrajectory.length)
    }
  } catch (error) {
    console.error("处理轨迹数据失败:", error)
  }
}

const handleReplanReply = (message) => {
  console.log("重规划响应:", message)
  obstacleStopState.isReplanning = false

  if (message.status === 'ok') {
    ElMessage.success('重规划成功')
  } else {
    ElMessage.error('重规划失败')
  }
}

const handleGotoReply = (message) => {
  console.log("前往目标点响应:", message)
  try {
    if (message.status === 'ok') {
      if (lastGotoRequest.value && message.pub_timestamp === lastGotoRequest.value.timestamp) {
        navigationStatus.value = 'navigating'
        isNavigating.value = true
        ElMessage.success('机器人已接收前往指令，开始导航')
      }
    } else {
      navigationStatus.value = 'failed'
      isNavigating.value = false
      ElMessage.error('前往目标点请求失败')
    }
  } catch (error) {
    console.error("处理goto响应失败:", error)
  }
}

const handleArriveEvent = (message) => {
  console.log("到达目标点事件:", message)
  try {
    if (message.args && message.args.length > 0) {
      const arriveData = message.args[0]
      const { status, coord, nid, error } = arriveData

      if (status === 'ok') {
        navigationStatus.value = 'arrived'
        isNavigating.value = false

        const targetInfo = coord && coord.length > 0 ?
          `(${coord[0][0]}, ${coord[0][1]})` :
          (nid && nid.length > 0 ? `点位${nid[0]}` : '目标点')

        if (currentExecutingTask.value && currentNavigationTask.value?.taskContext) {
          handleTaskWaypointArrival()
        } else {
          ElMessage.success(`已成功到达目标点 ${targetInfo}！`)

          if (olmap.value && olmap.value.clearTrajectory) {
            setTimeout(() => {
              olmap.value.clearTrajectory()
              settingParams.showRoadNetwork = true
              console.log('轨迹已自动清除')
            }, 2000)
          }
        }

        currentNavigationTask.value = null
        lastGotoRequest.value = null
      } else if (status === 'fail') {
        navigationStatus.value = 'failed'
        isNavigating.value = false

        let errorMessage = '前往目标点失败'
        if (error) {
          switch (error) {
            case 21: errorMessage = '前往目标点失败：规划失败'; break
            case 22: errorMessage = '前往目标点失败：偏离车道线'; break
            case 23: errorMessage = '前往目标点失败：任务提前终止'; break
            case 24: errorMessage = '前往目标点失败：定位异常'; break
            default: errorMessage = `前往目标点失败：未知错误(${error})`
          }
        }

        ElMessage.error(errorMessage)

        if (olmap.value && olmap.value.clearTrajectory) {
          olmap.value.clearTrajectory()
          settingParams.showRoadNetwork = true
        }

        currentNavigationTask.value = null
        lastGotoRequest.value = null
      }
    }
  } catch (error) {
    console.error("处理到达事件失败:", error)
  }
}

const handleTaskExecReply = (message) => {
  console.log("任务执行响应:", message)
  try {
    if (message.status === 'ok') {
      if (lastTaskExecRequest.value && message.pub_timestamp === lastTaskExecRequest.value.timestamp) {
        taskExecutionStatus.value = 'executing'
        isTaskExecuting.value = true
        ElMessage.success(`任务 "${currentExecutingTask.value.taskName}" 已开始执行`)
        executeNextWaypoint()
      }
    } else {
      taskExecutionStatus.value = 'failed'
      isTaskExecuting.value = false
      ElMessage.error('任务执行失败')
    }
  } catch (error) {
    console.error("处理任务执行响应失败:", error)
  }
}

const handleTaskCompleteEvent = (message) => {
  console.log("任务完成事件 - 原始消息:", message)
  try {
    if (message.args && message.args.length > 0) {
      const completeData = message.args[0]
      let { name, status } = completeData

      const hasEncodingIssue = name && /[\uFFFD\u00C0-\u00FF]{2,}/.test(name)
      if (hasEncodingIssue) {
        console.warn("检测到编码问题，任务名称包含乱码:", name)
      }

      console.log("解析后的任务名称:", name, "状态:", status)

      let currentTask = null
      let taskNameToDisplay = name

      if (currentExecutingTask.value) {
        currentTask = currentExecutingTask.value
        taskNameToDisplay = currentTask.taskName
        console.log("使用 currentExecutingTask 引用匹配任务:", currentTask.taskName)
      } else {
        currentTask = tasks.value.find(t => t.taskName === name)
        if (!currentTask && hasEncodingIssue) {
          const runningTasks = tasks.value.filter(t => t.status === 'running' || t.status === 'paused')
          if (runningTasks.length === 1) {
            currentTask = runningTasks[0]
            taskNameToDisplay = currentTask.taskName
            console.log("通过运行状态匹配到任务:", currentTask.taskName, "(原name为乱码)")
          }
        }
      }

      if (status === 'ok') {
        taskExecutionStatus.value = 'completed'
        isTaskExecuting.value = false
        ElMessage.success(`任务 "${taskNameToDisplay}" 已成功完成！`)

        if (currentTask && scheduledTasksToday.value.includes(currentTask.taskName)) {
          if (!scheduledTasksExecuted.value.includes(currentTask.taskName)) {
            scheduledTasksExecuted.value.push(currentTask.taskName)
            console.log(`定时任务完成: ${currentTask.taskName}`)
          }
          currentScheduledTask.value = null
        }

        currentExecutingTask.value = null
        currentTaskWaypointIndex.value = 0
        lastTaskExecRequest.value = null

        if (currentTask) {
          currentTask.status = 'completed'
          currentTask.executionStatus = 'completed'
          currentTask.currentWaypointIndex = 0

          const taskInList = tasks.value.find(t => t.taskName === currentTask.taskName || t.taskId === currentTask.taskId)
          if (taskInList && taskInList !== currentTask) {
            taskInList.status = 'completed'
            taskInList.executionStatus = 'completed'
            taskInList.currentWaypointIndex = 0
          }

          const taskNameForReset = currentTask.taskName
          setTimeout(() => {
            const taskToReset = tasks.value.find(t => t.taskName === taskNameForReset)
            if (taskToReset && taskToReset.status === 'completed') {
              taskToReset.status = 'idle'
              taskToReset.executionStatus = 'idle'
            }
          }, 5000)
        }

        if (olmap.value && olmap.value.clearTrajectory) {
          setTimeout(() => {
            olmap.value.clearTrajectory()
            settingParams.showRoadNetwork = true
          }, 3000)
        }
      } else if (status === 'fail') {
        taskExecutionStatus.value = 'failed'
        isTaskExecuting.value = false
        ElMessage.error(`任务 "${taskNameToDisplay}" 执行失败`)

        currentExecutingTask.value = null
        currentTaskWaypointIndex.value = 0
        lastTaskExecRequest.value = null

        if (currentTask) {
          currentTask.status = 'error'
          currentTask.executionStatus = 'failed'
          currentTask.currentWaypointIndex = 0

          const taskInList = tasks.value.find(t => t.taskName === currentTask.taskName || t.taskId === currentTask.taskId)
          if (taskInList && taskInList !== currentTask) {
            taskInList.status = 'error'
            taskInList.executionStatus = 'failed'
            taskInList.currentWaypointIndex = 0
          }

          const taskNameForReset = currentTask.taskName
          setTimeout(() => {
            const taskToReset = tasks.value.find(t => t.taskName === taskNameForReset)
            if (taskToReset && taskToReset.status === 'error') {
              taskToReset.status = 'idle'
              taskToReset.executionStatus = 'idle'
            }
          }, 5000)
        }

        if (olmap.value && olmap.value.clearTrajectory) {
          olmap.value.clearTrajectory()
          settingParams.showRoadNetwork = true
        }
      }
    }
  } catch (error) {
    console.error("处理任务完成事件失败:", error)
  }
}

const handleTaskRealtimeInfo = (message) => {
  try {
    if (message.args && message.args.length > 0) {
      const realtimeData = message.args[0]
      const { odom, time, drive_mode, auto_ready } = realtimeData

      taskRealtimeInfo.odom.total = odom?.tottal || 0
      taskRealtimeInfo.odom.remain = odom?.remain || 0
      taskRealtimeInfo.time.total = time?.total || 0
      taskRealtimeInfo.time.remain = time?.remain || 0
      taskRealtimeInfo.time.duration = time?.duration || 0
      taskRealtimeInfo.driveMode = drive_mode || 'auto'
      taskRealtimeInfo.autoReady = auto_ready !== undefined ? auto_ready : true

      if (currentExecutingTask.value) {
        realtimeInfo.currentTask = currentExecutingTask.value.taskName
        realtimeInfo.totalDistance = `${(odom?.tottal / 1000).toFixed(2)}km` || ''
      }
    }
  } catch (error) {
    console.error("处理任务实时信息失败:", error)
  }
}

const handleTaskStartReply = (message) => {
  console.log("任务开始响应:", message)
  try {
    if (message.status === 'ok') {
      ElMessage.success('任务已成功开始执行')

      if (currentExecutingTask.value) {
        const taskName = currentExecutingTask.value.taskName
        currentExecutingTask.value.status = 'running'
        currentExecutingTask.value.executionStatus = 'executing'

        const taskInList = tasks.value.find(t => t.taskId === currentExecutingTask.value.taskId)
        if (taskInList) {
          taskInList.status = 'running'
          taskInList.executionStatus = 'executing'
        }

        if (scheduledTasksToday.value.includes(taskName)) {
          currentScheduledTask.value = {
            name: taskName,
            startTime: new Date().getTime(),
            status: 'running'
          }
          lastTaskStartTime.value[taskName] = new Date().getTime()
          updateTaskListScheduleStatus()
        }
      }
    } else {
      taskExecutionStatus.value = 'failed'
      isTaskExecuting.value = false

      if (currentExecutingTask.value) {
        currentExecutingTask.value.status = 'idle'
        currentExecutingTask.value.executionStatus = 'failed'

        const taskInList = tasks.value.find(t => t.taskId === currentExecutingTask.value.taskId)
        if (taskInList) {
          taskInList.status = 'idle'
          taskInList.executionStatus = 'failed'
        }
      }

      ElMessage.error('任务开始失败')
    }
  } catch (error) {
    console.error("处理任务开始响应失败:", error)
  }
}

const handleTaskPauseReply = (message) => {
  console.log("暂停任务响应:", message)
  if (message.status === 'ok') {
    taskExecutionStatus.value = 'paused'

    if (currentExecutingTask.value) {
      currentExecutingTask.value.status = 'paused'
      currentExecutingTask.value.executionStatus = 'paused'

      const taskInList = tasks.value.find(t => t.taskId === currentExecutingTask.value.taskId)
      if (taskInList) {
        taskInList.status = 'paused'
        taskInList.executionStatus = 'paused'
      }
    }

    ElMessage.success('任务已暂停')
  } else {
    ElMessage.error('任务暂停失败')
  }
}

const handleTaskResumeReply = (message) => {
  console.log("继续任务响应:", message)
  if (message.status === 'ok') {
    taskExecutionStatus.value = 'executing'

    if (currentExecutingTask.value) {
      currentExecutingTask.value.status = 'running'
      currentExecutingTask.value.executionStatus = 'executing'

      const taskInList = tasks.value.find(t => t.taskId === currentExecutingTask.value.taskId)
      if (taskInList) {
        taskInList.status = 'running'
        taskInList.executionStatus = 'executing'
      }
    }

    ElMessage.success('任务已继续执行')
  } else {
    ElMessage.error('任务继续失败')
  }
}

const handleTaskCancelReply = (message) => {
  console.log("取消任务响应:", message)
  if (message.status === 'ok') {
    taskExecutionStatus.value = 'cancelled'
    isTaskExecuting.value = false

    const cancelledTaskName = currentExecutingTask.value?.taskName

    currentExecutingTask.value = null
    currentTaskWaypointIndex.value = 0
    lastTaskExecRequest.value = null

    if (cancelledTaskName) {
      const taskInList = tasks.value.find(t => t.taskName === cancelledTaskName)
      if (taskInList) {
        taskInList.status = 'idle'
        taskInList.executionStatus = 'idle'
        taskInList.currentWaypointIndex = 0
      }
    }

    ElMessage.success('任务已取消')

    if (olmap.value && olmap.value.clearTrajectory) {
      olmap.value.clearTrajectory()
      settingParams.showRoadNetwork = true
    }
  } else {
    ElMessage.error('任务取消失败')
  }
}

const handleNavigationStartReply = (message) => {
  console.log("导航启动响应:", message)
  try {
    if (message.status === 'ok') {
      navigationStackStatus.value = 'started'
      ElMessage.success('导航系统已启动')
    } else {
      ElMessage.error('导航系统启动失败')
    }
  } catch (error) {
    console.error("处理导航启动响应失败:", error)
  }
}

const handleNavigationStopReply = (message) => {
  console.log("导航停止响应:", message)
  try {
    if (message.status === 'ok') {
      navigationStackStatus.value = 'stopped'
      isNavigating.value = false
      navigationStatus.value = 'idle'
      currentNavigationTask.value = null
      lastGotoRequest.value = null

      if (olmap.value && olmap.value.clearTrajectory) {
        olmap.value.clearTrajectory()
        settingParams.showRoadNetwork = true
      }

      ElMessage.success('导航系统已停止')
    } else {
      ElMessage.error('导航系统停止失败')
    }
  } catch (error) {
    console.error("处理导航停止响应失败:", error)
  }
}

const handleNavigationRestartReply = (message) => {
  console.log("导航重启响应:", message)
  try {
    if (message.status === 'ok') {
      navigationStackStatus.value = 'started'
      isNavigating.value = false
      navigationStatus.value = 'idle'
      currentNavigationTask.value = null
      lastGotoRequest.value = null
      isTaskExecuting.value = false
      taskExecutionStatus.value = 'idle'
      currentExecutingTask.value = null
      currentTaskWaypointIndex.value = 0

      ElMessage.success('导航系统已重启')
      isBusy.value = false
    } else {
      ElMessage.error('导航系统重启失败')
      isBusy.value = false
    }
  } catch (error) {
    console.error("处理导航重启响应失败:", error)
    isBusy.value = false
  }
}

const handleEmergencyStopReply = (message) => {
  console.log("急停控制响应:", message)
  try {
    if (message.status === 'ok') {
      ElMessage.success('急停指令已执行')
    } else {
      ElMessage.error('急停指令执行失败')
    }
  } catch (error) {
    console.error("处理急停控制响应失败:", error)
  }
}

const handleEmergencyStopStatus = (message) => {
  try {
    if (message.args && message.args.length > 0) {
      const stopEnabled = message.args[0]
      const oldStatus = emergencyStopEnabled.value
      emergencyStopEnabled.value = stopEnabled

      if (oldStatus !== stopEnabled) {
        if (stopEnabled) {
          ElMessage.warning('车辆已启用急停状态')
          isNavigating.value = false
          navigationStatus.value = 'idle'
          currentNavigationTask.value = null
          isTaskExecuting.value = false
          taskExecutionStatus.value = 'idle'
        } else {
          ElMessage.info('车辆急停状态已解除')
        }
      }
    }
  } catch (error) {
    console.error("处理急停状态失败:", error)
  }
}

const handleObstacleData = (message) => {
  try {
    if (message.args && message.args.length > 0) {
      const obstacleInfo = message.args[0]
      const obsDistance = obstacleInfo.obs_distanse || obstacleInfo.obs_distance

      if (obsDistance && Array.isArray(obsDistance) && obsDistance.length >= 3) {
        obstacleData.left = obsDistance[0][0] || 0
        obstacleData.front = obsDistance[1][0] || 0
        obstacleData.right = obsDistance[2][0] || 0
        obstacleData.timestamp = message.timestamp || Date.now()

        checkObstacleWarning()

        console.log("障碍物数据更新:", {
          left: obstacleData.left + 'm',
          front: obstacleData.front + 'm',
          right: obstacleData.right + 'm'
        })
      }
    }
  } catch (error) {
    console.error("处理障碍物数据失败:", error)
  }
}

const checkObstacleWarning = () => {
  if (!obstacleSettings.enableWarning) return

  const { left, front, right } = obstacleData
  const { warningDistance, dangerDistance } = obstacleSettings

  let minDistance = Infinity
  let minDirection = ''

  if (left > 0 && left < minDistance) {
    minDistance = left
    minDirection = '左侧'
  }
  if (front > 0 && front < minDistance) {
    minDistance = front
    minDirection = '前方'
  }
  if (right > 0 && right < minDistance) {
    minDistance = right
    minDirection = '右侧'
  }

  if (minDistance !== Infinity) {
    let level = 'info'
    let msg = ''

    if (minDistance <= dangerDistance) {
      level = 'danger'
      msg = `危险！${minDirection}发现障碍物，距离仅${minDistance.toFixed(1)}米`
    } else if (minDistance <= warningDistance) {
      level = 'warning'
      msg = `注意！${minDirection}发现障碍物，距离${minDistance.toFixed(1)}米`
    } else {
      hideObstacleWarning()
      return
    }

    showObstacleWarning(level, msg, minDirection, minDistance)
  } else {
    hideObstacleWarning()
  }
}

const showObstacleWarning = (level, message, direction, distance) => {
  if (obstacleWarning.autoHideTimer) {
    clearTimeout(obstacleWarning.autoHideTimer)
  }

  obstacleWarning.show = true
  obstacleWarning.level = level
  obstacleWarning.message = message
  obstacleWarning.direction = direction
  obstacleWarning.distance = distance
  obstacleWarning.autoHideTimer = null

  if (level !== 'danger') {
    obstacleWarning.autoHideTimer = setTimeout(() => {
      hideObstacleWarning()
    }, obstacleSettings.autoHideDelay)
  }
}

const hideObstacleWarning = () => {
  if (obstacleWarning.autoHideTimer) {
    clearTimeout(obstacleWarning.autoHideTimer)
  }

  obstacleWarning.show = false
  obstacleWarning.level = 'info'
  obstacleWarning.message = ''
  obstacleWarning.direction = ''
  obstacleWarning.distance = 0
  obstacleWarning.autoHideTimer = null
}

const closeObstacleWarning = () => {
  hideObstacleWarning()
}

const getRunStateText = (runState) => {
  const stateMap = {
    1: '正常行驶',
    2: '暂停状态',
    3: '停车待命',
    4: '遇障停车',
    5: '交通管制等待',
    6: '定位切换等待',
    7: '人工接管',
    8: '绕障状态'
  }
  return stateMap[runState] || '未知状态'
}

const handleReplanRequest = async () => {
  if (obstacleStopState.isReplanning) {
    ElMessage.warning('正在请求重规划，请稍候...')
    return
  }

  try {
    await replan()
    obstacleStopState.isReplanning = true
    ElMessage.success('重规划指令已发送')
  } catch (error) {
    console.error('重规划请求失败:', error)
    ElMessage.error('重规划请求失败')
  }
}

const calculateTodayScheduledTasks = () => {
  if (!tasks.value || tasks.value.length === 0) return

  const scheduledTasksList = tasks.value.filter(task => {
    return task.shouldRunToday && task.scheduledTime !== null
  })

  scheduledTasksList.sort((a, b) => {
    if (!a.scheduledTime || !b.scheduledTime) return 0
    return a.scheduledTime.getTime() - b.scheduledTime.getTime()
  })

  scheduledTasksToday.value = scheduledTasksList.map(task => task.taskName)

  console.log(`今日应执行的定时任务 (${scheduledTasksToday.value.length}):`,
    scheduledTasksList.map(t => `${t.taskName} (${t.scheduledTimeStr})`))

  scheduledTasksList.forEach(task => {
    console.log(`⏰ ${task.taskName}:`, {
      time: task.scheduledTimeStr,
      weekDays: task.scheduledWeekDays,
      points: task.points.length,
      count: task.count
    })
  })

  updateTaskListScheduleStatus()
}

const updateTaskListScheduleStatus = () => {
  if (!tasks.value || tasks.value.length === 0) return

  tasks.value.forEach(task => {
    task.scheduleStatus = null
    task.scheduleProgress = null

    if (!scheduledTasksToday.value.includes(task.taskName)) {
      return
    }

    if (currentScheduledTask.value && task.taskName === currentScheduledTask.value.name) {
      task.scheduleStatus = 'schedule-running'
      if (currentExecutingTask.value && currentExecutingTask.value.taskName === task.taskName) {
        task.scheduleProgress = `${currentTaskWaypointIndex.value}/${currentExecutingTask.value.points?.length || 0}`
      }
    } else if (scheduledTasksExecuted.value.includes(task.taskName)) {
      task.scheduleStatus = 'schedule-executed'
    } else {
      task.scheduleStatus = 'schedule-pending'
    }
  })
}

const startAutoExecuteTimer = () => {
  if (!autoExecuteEnabled.value) {
    console.log('定时任务自动执行功能已禁用')
    return
  }

  stopAutoExecuteTimer()

  autoExecuteTimer.value = setInterval(() => {
    checkAndExecuteScheduledTasks()
  }, 30 * 1000)

  console.log('定时任务自动执行功能已启动（每30秒检查一次）')
  checkAndExecuteScheduledTasks()
}

const stopAutoExecuteTimer = () => {
  if (autoExecuteTimer.value) {
    clearInterval(autoExecuteTimer.value)
    autoExecuteTimer.value = null
    console.log('定时任务自动执行功能已停止')
  }
}

const checkAndExecuteScheduledTasks = () => {
  if (!autoExecuteEnabled.value || !tasks.value || tasks.value.length === 0) {
    return
  }

  if (isTaskExecuting.value || isNavigating.value) {
    return
  }

  const now = new Date()
  const currentTime = now.getTime()

  const tasksToExecute = tasks.value.filter(task => {
    if (!task.shouldRunToday || !task.scheduledTime) return false
    if (scheduledTasksExecuted.value.includes(task.taskName)) return false
    if (currentScheduledTask.value && currentScheduledTask.value.name === task.taskName) return false

    const scheduledTimeMs = task.scheduledTime.getTime()
    const timeDiff = currentTime - scheduledTimeMs

    return timeDiff >= 0 && timeDiff < 5 * 60 * 1000
  })

  tasksToExecute.sort((a, b) => a.scheduledTime.getTime() - b.scheduledTime.getTime())

  if (tasksToExecute.length > 0) {
    const taskToExecute = tasksToExecute[0]
    console.log(`自动执行定时任务: ${taskToExecute.taskName} (预定时间: ${taskToExecute.scheduledTimeStr})`)
    executeScheduledTask(taskToExecute)
  }
}

const executeScheduledTask = async (task) => {
  if (!task || !task.points || task.points.length === 0) {
    console.error('任务数据不完整，无法执行:', task.taskName)
    return
  }

  console.log(`开始执行定时任务: ${task.taskName}`)
  console.log(`包含 ${task.points.length} 个目标点`)
  console.log(`执行次数: ${task.count}`)

  try {
    const timestamp = new Date().getTime()

    currentExecutingTask.value = task
    currentTaskWaypointIndex.value = 0
    lastTaskExecRequest.value = { roadmap: mapName.value, task: task.taskName }
    isTaskExecuting.value = true
    taskExecutionStatus.value = 'executing'

    task.status = 'running'
    task.executionStatus = 'executing'

    // 发送启动任务请求
    await startTask(mapName.value, task.taskName)

    ElMessage.success(`自动执行定时任务: ${task.taskName}`)

    console.log(`定时任务 "${task.taskName}" 执行指令已发送`)
  } catch (error) {
    console.error(`执行定时任务 "${task.taskName}" 失败:`, error)
    ElMessage.error(`执行定时任务失败: ${error.message}`)
  }
}

const calculateCurrentProgress = (trajectory) => {
  if (!trajectory || trajectory.length === 0) return 0

  const robotPos = [robotPoseData.x, robotPoseData.y]
  let totalDistance = 0

  for (let i = 0; i < trajectory.length - 1; i++) {
    const segmentLength = Math.sqrt(
      Math.pow(trajectory[i + 1][0] - trajectory[i][0], 2) +
      Math.pow(trajectory[i + 1][1] - trajectory[i][1], 2)
    )
    totalDistance += segmentLength
  }

  if (totalDistance === 0) return 0

  let bestProjectionDistance = 0
  let minDistanceToTrajectory = Infinity

  let accumulatedDistance = 0
  for (let i = 0; i < trajectory.length - 1; i++) {
    const segmentStart = trajectory[i]
    const segmentEnd = trajectory[i + 1]
    const segmentLength = Math.sqrt(
      Math.pow(segmentEnd[0] - segmentStart[0], 2) +
      Math.pow(segmentEnd[1] - segmentStart[1], 2)
    )

    const projection = projectPointToLineSegment(robotPos, segmentStart, segmentEnd)
    const distanceToSegment = projection.distance

    if (distanceToSegment < minDistanceToTrajectory) {
      minDistanceToTrajectory = distanceToSegment
      const projectionDistanceOnSegment = Math.sqrt(
        Math.pow(projection.point[0] - segmentStart[0], 2) +
        Math.pow(projection.point[1] - segmentStart[1], 2)
      )
      bestProjectionDistance = accumulatedDistance + projectionDistanceOnSegment
    }

    accumulatedDistance += segmentLength
  }

  const progressRatio = bestProjectionDistance / totalDistance
  const progressIndex = Math.floor(progressRatio * (trajectory.length - 1))

  if (minDistanceToTrajectory < 5.0) {
    console.log(`机器人轨迹进度: ${progressIndex}/${trajectory.length-1}, 距轨迹距离: ${minDistanceToTrajectory.toFixed(2)}m`)
    return Math.min(progressIndex, trajectory.length - 1)
  }

  return olmap.value?.trajectoryProgress || 0
}

const projectPointToLineSegment = (point, lineStart, lineEnd) => {
  const [px, py] = point
  const [x1, y1] = lineStart
  const [x2, y2] = lineEnd

  const A = px - x1
  const B = py - y1
  const C = x2 - x1
  const D = y2 - y1

  const dot = A * C + B * D
  const lenSq = C * C + D * D

  if (lenSq === 0) {
    return {
      point: [x1, y1],
      distance: Math.sqrt(A * A + B * B)
    }
  }

  let param = dot / lenSq
  param = Math.max(0, Math.min(1, param))

  const projectionX = x1 + param * C
  const projectionY = y1 + param * D

  const distance = Math.sqrt(
    Math.pow(px - projectionX, 2) + Math.pow(py - projectionY, 2)
  )

  return {
    point: [projectionX, projectionY],
    distance: distance
  }
}

const checkIfReachedTarget = (trajectory) => {
  if (!trajectory || trajectory.length === 0) return false

  if (navigationStatus.value === 'arrived' || navigationStatus.value === 'failed') {
    return true
  }

  const robotPos = [laserPositionData.x, laserPositionData.y]
  const targetPos = trajectory[trajectory.length - 1]

  const distanceToTarget = Math.sqrt(
    Math.pow(targetPos[0] - robotPos[0], 2) + Math.pow(targetPos[1] - robotPos[1], 2)
  )

  if (distanceToTarget < 1.0 && isNavigating.value) {
    console.log(`本地检测: 机器人接近目标点，距离: ${distanceToTarget.toFixed(2)}m，等待WebSocket到达确认`)
  }

  return false
}

const publishMsg = () => {}

const updateOlCss = () => {
  const element = mapStage.value
  if (element) {
    const newWidth = element.offsetWidth
    const newHeight = element.offsetHeight
    // 调试日志：检测容器尺寸变化
    if (newWidth === 0 || newHeight === 0) {
      console.warn('[updateOlCss] 容器尺寸为0，可能需要等待DOM渲染完成', { width: newWidth, height: newHeight })
    }
    olWidth.value = newWidth
    olHeight.value = newHeight
  } else {
    console.warn('[updateOlCss] mapStage element 为空')
  }
}

const getMapInstance = () => {
  return olmap.value && olmap.value.map ? olmap.value.map : null
}

const openDraSetting = () => {
  initPoseMode.value = false
  settingDrawer.value = !settingDrawer.value
  if (settingDrawer.value) {
    closeDra()
    nowHandMenu.value = '功能菜单操作'
  } else {
    nowHandMenu.value = ''
  }
}

const openPoint = () => {
  initPoseMode.value = false
  pointDrawer.value = !pointDrawer.value
  if (pointDrawer.value) {
    closeDra()
    nowHandMenu.value = '目标点操作'
  } else {
    nowHandMenu.value = ''
  }
}

const openTask = () => {
  initPoseMode.value = false
  taskDrawer.value = !taskDrawer.value
  if (taskDrawer.value) {
    closeDra()
    nowHandMenu.value = '任务操作'
  } else {
    nowHandMenu.value = ''
  }
}

const closeDra = (type) => {
  settingDrawer.value = false
  pointDrawer.value = false
  taskDrawer.value = false
  if (type == 'hand') {
    activeTab.value = -1
  }
  nowHandMenu.value = ''
}

const handleSelectionChange = (selection) => {
  pointIds.value = selection.map(item => item.id)
  single.value = selection.length !== 1
  multiple.value = !selection.length
}

const editPoint = (row) => {
  pointEditDiaShow.value = true
  pointEditData.id = row.id
  pointEditData.x = row.x
  pointEditData.y = row.y
  pointEditData.type = row.type
  pointEditData.actionMenuList = row.action
}

const removePoint = (row) => {
  const idArr = []
  const ids = row?.id || pointIds.value
  if (ids) {
    idArr.push(...(Array.isArray(ids) ? ids : [ids]))
    idArr.forEach(id => {
      let indexToRemove = pointList.value.findIndex(item => item?.id === id)
      if (indexToRemove !== -1) {
        pointList.value.splice(indexToRemove, 1)
        if (pointList.value.length < 1) {
          olmap.value?.restIdNum()
        }
        olmap.value?.removeCalibrationById(id)
      }
    })
  }
}

const moveUp = () => {
  const index = pointList.value.findIndex(point => point.id == pointIds.value[0])
  if (index !== -1 && index > 0) {
    const temp = pointList.value[index]
    pointList.value[index] = pointList.value[index - 1]
    pointList.value[index - 1] = temp
  }
}

const moveDown = () => {
  const index = pointList.value.findIndex(point => point.id == pointIds.value[0])
  if (index !== -1 && index < pointList.value.length - 1) {
    const temp = pointList.value[index]
    pointList.value[index] = pointList.value[index + 1]
    pointList.value[index + 1] = temp
  }
}

const appendActionMenu = () => {
  pointEditData.actionMenuList.push({ value: 0, other: 0 })
}

const removeActionMenu = (index) => {
  pointEditData.actionMenuList.splice(index, 1)
}

const changeAction = (index) => {
  const item = pointEditData.actionMenuList[index]
  if (item && 'other' in item) {
    delete item.other
  } else {
    item.other = 0
  }
}

const clearActionDia = () => {
  pointEditData.id = ''
  pointEditData.x = ''
  pointEditData.y = ''
  pointEditData.type = ''
  pointEditData.actionMenuList = []
}

const submitEditPoint = () => {
  pointEditDiaShow.value = false
  const point = waypoints.value.find(item => item.id === pointEditData.id)
  if (point) {
    point.x = pointEditData.x
    point.y = pointEditData.y
    point.type = pointEditData.type
    point.action = [...pointEditData.actionMenuList]
    ElMessage.success("目标点数据已修改")
  }
}

const submitTaskGenerate = async () => {
  const orderedPoints = generateTaskParam.selectedWaypoints || []
  if (!generateTaskParam.taskName || orderedPoints.length === 0) {
    ElMessage.warning('请完善任务数据（任务名称和目标点不能为空）!')
    return
  }

  try {
    const coordinates = orderedPoints.map(point => [
      parseFloat(point.x),
      parseFloat(point.y),
      0
    ])

    const plan = orderedPoints.map(point => {
      return point.type === 1 ? 'route' : 'free'
    })

    const action = orderedPoints.map(point => {
      if (!point.action || point.action.length === 0) {
        return []
      }
      return point.action.map(act => {
        if (act.value === 0 && 'other' in act) {
          return { type: 'wait', duration: parseFloat(act.other) || 0 }
        } else {
          const actionTypes = ['wait', 'start_record', 'stop_record', 'add_trajectory', 'hook_mount', 'hook_unmount']
          return { type: actionTypes[act.value] || 'wait' }
        }
      })
    })

    let cron = ''
    if (generateTaskParam.time && generateTaskParam.date.length > 0) {
      let hours, minutes
      if (typeof generateTaskParam.time === 'string') {
        const timeParts = generateTaskParam.time.split(':')
        hours = timeParts[0]
        minutes = timeParts[1]
      } else {
        const timeObj = new Date(generateTaskParam.time)
        hours = String(timeObj.getHours()).padStart(2, '0')
        minutes = String(timeObj.getMinutes()).padStart(2, '0')
      }
      const weekdays = generateTaskParam.date.sort().join(',')
      cron = `00 ${minutes} ${hours} ? * ${weekdays} *`
    }

    const taskData = {
      map: mapName.value,
      path: generateTaskParam.taskName,
      coord_type: 'local',
      cron: cron,
      coord: coordinates,
      plan: plan,
      action: [[]],
      repeate: generateTaskParam.count || 1
    }

    const response = await addTask(taskData)
    console.log("创建任务响应:", response)

    if (response.status === true) {
      ElMessage.success(`任务创建成功！任务包含 ${orderedPoints.length} 个目标点`)
      await loadTaskList()
      restGenerateParam()
      taskGenerateDiaShow.value = false
      selectedWaypointIds.value = []
      console.log("任务创建成功:", taskData)
    } else {
      ElMessage.error('任务创建失败: ' + (response.msg || '未知错误'))
    }
  } catch (error) {
    console.error("创建任务失败:", error)
    ElMessage.error('任务创建失败: ' + (error.message || '未知错误'))
  }
}

const initNavigation = () => {
  closeDra()
  initPoseMode.value = !initPoseMode.value
  nowHandMenu.value = initPoseMode.value ? '初始化导航' : ''
  selectPointMode.value = false
}

const restNavigation = async () => {
  try {
    await ElMessageBox.confirm('将重启当前导航, 是否继续?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    ElMessage.success('导航已重启!')
  } catch {
    // 用户取消
  }
}

const offNavigation = async () => {
  try {
    await ElMessageBox.confirm('将关闭当前导航, 是否继续?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    ElMessage.success('导航已关闭!')
  } catch {
    // 用户取消
  }
}

const closeTaskGenerate = () => {
  taskGenerateDiaShow.value = false
  restGenerateParam()
}

const restGenerateParam = () => {
  generateTaskParam.taskId = ''
  generateTaskParam.taskName = ''
  generateTaskParam.count = 1
  generateTaskParam.time = ''
  generateTaskParam.date = []
  generateTaskParam.selectedWaypoints = []
}

const removeTaskItem = async (data) => {
  try {
    await ElMessageBox.confirm('删除名为' + data.taskName + '的任务', '删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    ElMessage.success('已删除!')
    taskDataList.value = taskDataList.value.filter(task => task.taskId !== data.taskId)
  } catch {
    // 用户取消
  }
}

const executeTask = async (data) => {
  try {
    await ElMessageBox.confirm('开始执行任务' + data.taskName + '?', '执行', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    ElMessage.success('任务已开始执行!')
    taskDataList.value.forEach(task => {
      if (task.taskId === data.taskId) {
        task.status = 0
      }
    })
  } catch {
    // 用户取消
  }
}

const test = () => {
  console.log(settingParams)
}

const mapSelectEle = (type) => {
  if (type == 'open') {
    selectPointMode.value = true
    initPoseMode.value = false
    ElMessage.success('已开启选择模式')
  } else {
    selectPointMode.value = false
    ElMessage.info('已关闭选择模式')
  }
}

const addNowPoint = (currentCoordinate, currentPlace) => {
  const coordData = {
    id: currentCoordinate[0],
    name: `目标点${currentCoordinate[0]}`,
    x: currentCoordinate[1].toFixed(3),
    y: currentCoordinate[2].toFixed(3),
    placeX: currentPlace[0].toFixed(3),
    placeY: currentPlace[1].toFixed(3),
    type: 1,
    action: [{ value: 0, other: 0 }]
  }
  waypoints.value.push(coordData)
  ElMessage.success(`已添加目标点: (${coordData.x}, ${coordData.y})`)
}

const initNavigationResult = (position, yaw, nid) => {
  console.log("=== 位姿初始化 ===")
  console.log("位置:", `x=${position[0].toFixed(3)}, y=${position[1].toFixed(3)}`)
  console.log("朝向角(弧度):", yaw.toFixed(4))
  console.log("朝向角(度):", (yaw * 180 / Math.PI).toFixed(2) + "°")
  console.log("点位ID:", nid || "null")

  // 根据是否有nid选择使用哪个接口
  if (nid) {
    initPoseByNid(nid).then(() => {
      ElMessage.success({
        message: `位姿初始化成功！位置: (${position[0].toFixed(2)}, ${position[1].toFixed(2)}), 朝向: ${(yaw * 180 / Math.PI).toFixed(1)}°`,
        duration: 3000
      })
    }).catch(error => {
      console.error('位姿初始化失败:', error)
      ElMessage.error('位姿初始化失败')
    })
  } else {
    initPose(position[0], position[1], yaw).then(() => {
      ElMessage.success({
        message: `位姿初始化成功！位置: (${position[0].toFixed(2)}, ${position[1].toFixed(2)}), 朝向: ${(yaw * 180 / Math.PI).toFixed(1)}°`,
        duration: 3000
      })
    }).catch(error => {
      console.error('位姿初始化失败:', error)
      ElMessage.error('位姿初始化失败')
    })
  }

  initPoseMode.value = false
  nowHandMenu.value = ''
}

const onTabChange = (tabKey) => {
  activeTab.value = tabKey
  lastTab.value = tabKey

  if (tabKey === 'points' && selectPointMode.value) {
    // 保持选点模式
  } else if (tabKey !== 'points') {
    selectPointMode.value = false
    nowHandMenu.value = ''
  }
}

const toggleSelectPointMode = () => {
  selectPointMode.value = !selectPointMode.value
  initPoseMode.value = false
  nowHandMenu.value = selectPointMode.value ? '选点模式' : ''

  if (selectPointMode.value) {
    ElMessage.success('已进入选点模式')
  } else {
    ElMessage.info('已退出选点模式')
  }
}

const clearAllPoints = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有点位吗？', '确认清空', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    waypoints.value = []
    if (olmap.value && olmap.value.restIdNum) {
      olmap.value.restIdNum()
    }
    ElMessage.success('已清空所有点位')
  } catch {
    // 用户取消
  }
}

const handleZoomIn = () => {
  try {
    const map = getMapInstance()
    if (map) {
      const view = map.getView()
      const currentZoom = view.getZoom()
      view.animate({
        zoom: currentZoom + 1,
        duration: 250
      })
    } else if (olmap.value && olmap.value.zoomIn) {
      olmap.value.zoomIn()
    }
  } catch (error) {
    console.warn('地图放大失败:', error)
    ElMessage.warning('地图放大失败')
  }
}

const handleZoomOut = () => {
  try {
    const map = getMapInstance()
    if (map) {
      const view = map.getView()
      const currentZoom = view.getZoom()
      view.animate({
        zoom: Math.max(currentZoom - 1, 1),
        duration: 250
      })
    } else if (olmap.value && olmap.value.zoomOut) {
      olmap.value.zoomOut()
    }
  } catch (error) {
    console.warn('地图缩小失败:', error)
    ElMessage.warning('地图缩小失败')
  }
}

const handleCenterToRobot = () => {
  try {
    const map = getMapInstance()
    if (map) {
      const view = map.getView()

      let centerPoint = [robotPoseData.x, robotPoseData.y]
      if (robotPoseData.x === 0 && robotPoseData.y === 0) {
        centerPoint = view.getCenter()
        console.log('使用地图中心点作为居中位置:', centerPoint)
      } else {
        console.log('使用机器人位置作为居中位置:', centerPoint)
      }

      view.animate({
        center: centerPoint,
        zoom: Math.max(view.getZoom(), 15),
        duration: 500
      })
      ElMessage.success('已居中到机器人位置')
    } else if (olmap.value && olmap.value.centerToRobot) {
      olmap.value.centerToRobot()
      ElMessage.success('已居中到机器人位置')
    } else {
      console.warn('无法获取地图实例')
      ElMessage.warning('地图未就绪，无法居中')
    }
  } catch (error) {
    console.error('定位机器人失败:', error)
    console.log('调试信息:', {
      robotPoseData: robotPoseData,
      robotPosition: robotPosition.value,
      mapReady: !!getMapInstance()
    })
    ElMessage.warning('定位机器人失败: ' + error.message)
  }
}

const handleToggleFullscreen = () => {
  const mapContainer = mapStage.value
  if (!mapContainer) {
    ElMessage.error('无法找到地图容器')
    return
  }

  if (FullscreenOperations.toggleFullscreen(mapContainer)) {
    // 全屏切换成功
  } else {
    ElMessage.error('浏览器不支持全屏功能')
  }
}

const handleConfirmInit = () => {
  initPoseMode.value = true
  selectPointMode.value = false
  nowHandMenu.value = '初始化导航'
  ElMessage.success('已进入位姿初始化模式')
}

const handleConfirmReboot = async () => {
  isBusy.value = true
  try {
    await startNavStandard(mapName.value)
    ElMessage.success('导航重启指令已发送')
  } catch (error) {
    console.error('导航重启请求失败:', error)
    ElMessage.error('导航重启请求失败')
  }

  setTimeout(() => {
    if (isBusy.value) {
      isBusy.value = false
      ElMessage.warning('导航重启响应超时，请检查系统状态')
    }
  }, 15000)
}

const handleConfirmStop = async () => {
  selectPointMode.value = false
  initPoseMode.value = false
  nowHandMenu.value = ''

  try {
    await ElMessageBox.confirm('请选择要执行的操作：', '操作选择', {
      confirmButtonText: '急停',
      cancelButtonText: '停止导航',
      distinguishCancelAndClose: true,
      type: 'warning',
      customClass: 'stop-action-dialog'
    })
    executeEmergencyStop()
  } catch (action) {
    if (action === 'cancel') {
      executeNavigationStop()
    }
  }
}

const executeEmergencyStop = async () => {
  try {
    await emergencyStop(true)
    ElMessage.warning('急停指令已发送')
  } catch (error) {
    console.error('急停请求失败:', error)
    ElMessage.error('急停请求失败')
  }
}

const executeNavigationStop = async () => {
  try {
    await stopNavigation()
    ElMessage.info('导航停止指令已发送')
  } catch (error) {
    console.error('导航停止请求失败:', error)
    ElMessage.error('导航停止请求失败')
  }
}

const executeEmergencyStopRelease = async () => {
  try {
    await releaseEmergencyStop()
    ElMessage.success('解除急停指令已发送')
  } catch (error) {
    console.error('解除急停请求失败:', error)
    ElMessage.error('解除急停请求失败')
  }
}

const handleNavigationPause = async () => {
  if (!isNavigating.value || navigationStatus.value === 'paused') {
    ElMessage.warning('当前没有正在执行的导航任务')
    return
  }

  try {
    await pauseTask()
    navigationStatus.value = 'paused'
    ElMessage.success('导航已暂停')
  } catch (error) {
    console.error('暂停导航请求失败:', error)
    ElMessage.error('暂停导航请求失败')
  }
}

const handleNavigationResume = async () => {
  if (!currentNavigationTask.value || navigationStatus.value !== 'paused') {
    ElMessage.warning('没有可恢复的导航任务')
    return
  }

  try {
    await resumeTask()
    navigationStatus.value = 'navigating'
    ElMessage.success('导航已恢复')
  } catch (error) {
    console.error('恢复导航请求失败:', error)
    ElMessage.error('恢复导航请求失败')
  }
}

const handleNavigationStop = async () => {
  if (!isNavigating.value && navigationStatus.value === 'idle') {
    ElMessage.warning('当前没有导航任务')
    return
  }

  try {
    await ElMessageBox.confirm('确定要停止当前导航任务吗？', '确认停止', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    await cancelTask()

    isNavigating.value = false
    navigationStatus.value = 'idle'
    currentNavigationTask.value = null

    if (olmap.value && olmap.value.clearTrajectory) {
      olmap.value.clearTrajectory()
      settingParams.showRoadNetwork = true
    }

    ElMessage.success('导航任务已停止')
  } catch {
    // 用户取消
  }
}

const showCreateTaskDialog = () => {
  ElMessage.info('创建任务功能待接入')
}

// const startTask = (task) => {
//   task.status = 'running'
//   ElMessage.success(`任务 "${task.name}" 已开始执行`)
// }

/* const pauseTask = (task) => {
  task.status = 'paused'
  ElMessage.warning(`任务 "${task.name}" 已暂停`)
}

const resumeTask = (task) => {
  task.status = 'running'
  ElMessage.success(`任务 "${task.name}" 已继续执行`)
}

const cancelTask = async (task) => {
  try {
    await ElMessageBox.confirm(`确定要取消任务 "${task.name}" 吗？`, '确认取消', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    task.status = 'idle'
    ElMessage.info(`任务 "${task.name}" 已取消`)
  } catch {
    // 用户取消
  }
}

const toggleInitPoseMode = () => {
  initPoseMode.value = !initPoseMode.value
  selectPointMode.value = false
  nowHandMenu.value = initPoseMode.value ? '初始化导航' : ''

  if (initPoseMode.value) {
    ElMessage.success('已进入位姿初始化模式')
  } else {
    ElMessage.info('已退出位姿初始化模式')
  }
} */

const onRestart = () => {
  handleConfirmReboot()
}

const onStop = () => {
  handleConfirmStop()
}

const onInit = () => {
  handleConfirmInit()
}

const onZoomIn = () => {
  handleZoomIn()
}

const onZoomOut = () => {
  handleZoomOut()
}

const onCenterRobot = () => {
  handleCenterToRobot()
}

const onToggleFullscreen = () => {
  handleToggleFullscreen()
}

const getTaskStatusText = (status) => {
  const statusMap = {
    'idle': '空闲',
    'running': '执行中',
    'paused': '暂停'
  }
  return statusMap[status] || '未知'
}

const onWpSelect = (waypoint) => {
  console.log('选择目标点:', waypoint)
  ElMessage.success(`已选择目标点: ${waypoint.name}`)
}

const onWpSend = (waypoint) => {
  console.log('发送目标点:', waypoint)
  ElMessage.success(`已发送目标点: ${waypoint.name}`)
}

const onWpCreate = () => {
  console.log('创建目标点')
  ElMessage.info('创建目标点功能待实现')
}

const onWpEdit = (waypoint) => {
  console.log('编辑目标点:', waypoint)
  pointEditDiaShow.value = true
  pointEditData.id = waypoint.id
  pointEditData.x = waypoint.x
  pointEditData.y = waypoint.y
  pointEditData.type = waypoint.type
  pointEditData.actionMenuList = waypoint.action ? [...waypoint.action] : [{ value: 0, other: 0 }]
}

const onWpRemove = (waypoint) => {
  console.log('删除目标点:', waypoint)
  waypoints.value = waypoints.value.filter(wp => wp.id !== waypoint.id)
  selectedWaypointIds.value = selectedWaypointIds.value.filter(id => id !== waypoint.id)
  olmap.value?.removeIconHtmlById("calibration-" + waypoint.id)
  ElMessage.success(`已删除目标点: ${waypoint.name || '目标点'}`)
}

const onWpMoveUp = () => {
  if (selectedWaypointIds.value.length !== 1) return

  const selectedId = selectedWaypointIds.value[0]
  const index = waypoints.value.findIndex(wp => wp.id === selectedId)

  if (index > 0) {
    const temp = waypoints.value[index]
    waypoints.value[index] = waypoints.value[index - 1]
    waypoints.value[index - 1] = temp
    ElMessage.success('目标点已上移')
  }
}

const onWpMoveDown = () => {
  if (selectedWaypointIds.value.length !== 1) return

  const selectedId = selectedWaypointIds.value[0]
  const index = waypoints.value.findIndex(wp => wp.id === selectedId)

  if (index < waypoints.value.length - 1) {
    const temp = waypoints.value[index]
    waypoints.value[index] = waypoints.value[index + 1]
    waypoints.value[index + 1] = temp
    ElMessage.success('目标点已下移')
  }
}

const onWpBatchRemove = async () => {
  if (selectedWaypointIds.value.length === 0) return

  try {
    await ElMessageBox.confirm(`确定要删除选中的 ${selectedWaypointIds.value.length} 个目标点吗？`, '批量删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    const waypointsToRemove = waypoints.value.filter(wp => selectedWaypointIds.value.includes(wp.id))

    waypointsToRemove.forEach(wp => {
      olmap.value?.removeIconHtmlById("calibration-" + wp.id)
    })

    waypoints.value = waypoints.value.filter(wp => !selectedWaypointIds.value.includes(wp.id))
    selectedWaypointIds.value = []
    ElMessage.success('目标点删除成功')
  } catch {
    // 用户取消
  }
}

const onWpGoto = async () => {
  if (selectedWaypointIds.value.length !== 1) return

  if (isNavigating.value) {
    ElMessage.warning('机器人正在导航中，请等待任务完成后再发送新任务')
    return
  }

  const selectedWaypoint = waypoints.value.find(wp => wp.id === selectedWaypointIds.value[0])
  console.log('前往目标点:', selectedWaypoint)

  if (selectedWaypoint) {
    if (olmap.value && olmap.value.clearTrajectory) {
      olmap.value.clearTrajectory()
      console.log('已清除之前的轨迹')
    }

    const timestamp = new Date().getTime()

    currentNavigationTask.value = {
      waypoint: selectedWaypoint,
      timestamp: timestamp,
      status: 'planning'
    }
    lastGotoRequest.value = { roadmap: mapName.value, coord: [[Number(selectedWaypoint.x), Number(selectedWaypoint.y)]] }
    navigationStatus.value = 'planning'

    try {
      // 发送路径规划请求
      await requestPlanning(mapName.value, Number(selectedWaypoint.x), Number(selectedWaypoint.y))
      // 发送前往目标点请求
      await gotoTarget(mapName.value, Number(selectedWaypoint.x), Number(selectedWaypoint.y))
      ElMessage.success(`正在发送前往指令: ${selectedWaypoint.name || '目标点' + selectedWaypoint.id} (${selectedWaypoint.x}, ${selectedWaypoint.y})`)
    } catch (error) {
      console.error('发送导航指令失败:', error)
      ElMessage.error('发送导航指令失败')
    }
  }
}

const onWpGotoSingle = async (waypoint) => {
  if (isNavigating.value) {
    ElMessage.warning('机器人正在导航中，请等待任务完成后再发送新任务')
    return
  }

  if (olmap.value && olmap.value.clearTrajectory) {
    olmap.value.clearTrajectory()
    console.log('已清除之前的轨迹')
  }

  const timestamp = new Date().getTime()

  currentNavigationTask.value = {
    waypoint: waypoint,
    timestamp: timestamp,
    status: 'planning'
  }
  lastGotoRequest.value = { roadmap: mapName.value, coord: [[Number(waypoint.x), Number(waypoint.y)]] }
  navigationStatus.value = 'planning'

  try {
    // 发送路径规划请求
    await requestPlanning(mapName.value, Number(waypoint.x), Number(waypoint.y))
    // 发送前往目标点请求
    await gotoTarget(mapName.value, Number(waypoint.x), Number(waypoint.y))
    ElMessage.success(`正在发送前往指令: ${waypoint.name || '目标点' + waypoint.id} (${waypoint.x}, ${waypoint.y})`)
  } catch (error) {
    console.error('发送导航指令失败:', error)
    ElMessage.error('发送导航指令失败')
  }
}

const cancelCurrentNavigation = async () => {
  if (!isNavigating.value) {
    ElMessage.info('当前没有正在进行的导航任务')
    return
  }

  try {
    await ElMessageBox.confirm('确定要取消当前的导航任务吗？', '取消导航', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    navigationStatus.value = 'idle'
    isNavigating.value = false
    currentNavigationTask.value = null
    lastGotoRequest.value = null

    if (olmap.value && olmap.value.clearTrajectory) {
      olmap.value.clearTrajectory()
      settingParams.showRoadNetwork = true
    }

    ElMessage.success('导航任务已取消')
    console.log('用户取消了导航任务')
  } catch {
    // 用户取消
  }
}

const executeNextWaypoint = async () => {
  if (!currentExecutingTask.value || !currentExecutingTask.value.points) {
    console.error('没有正在执行的任务或任务没有目标点')
    return
  }

  const waypointList = currentExecutingTask.value.points
  const currentIndex = currentTaskWaypointIndex.value

  if (currentIndex >= waypointList.length) {
    console.log('所有目标点已执行完成')
    return
  }

  const currentWaypoint = waypointList[currentIndex]
  console.log(`执行目标点 ${currentIndex + 1}/${waypointList.length}:`, currentWaypoint)

  if (olmap.value && olmap.value.clearTrajectory) {
    olmap.value.clearTrajectory()
    console.log('已清除之前的轨迹，准备执行下一个目标点')
  }

  const timestamp = new Date().getTime()

  currentNavigationTask.value = {
    waypoint: currentWaypoint,
    timestamp: timestamp,
    taskContext: {
      taskId: currentExecutingTask.value.taskId,
      waypointIndex: currentIndex,
      totalWaypoints: waypointList.length
    }
  }
  lastGotoRequest.value = { roadmap: mapName.value, coord: [[Number(currentWaypoint.x), Number(currentWaypoint.y)]] }
  navigationStatus.value = 'planning'
  isNavigating.value = true

  try {
    // 发送路径规划请求
    await requestPlanning(mapName.value, Number(currentWaypoint.x), Number(currentWaypoint.y))
    // 发送前往目标点请求
    await gotoTarget(mapName.value, Number(currentWaypoint.x), Number(currentWaypoint.y))
    ElMessage.info(`正在前往第 ${currentIndex + 1} 个目标点: ${currentWaypoint.name || '目标点' + currentWaypoint.id} (${currentWaypoint.x}, ${currentWaypoint.y})`)
  } catch (error) {
    console.error('发送导航指令失败:', error)
    ElMessage.error('发送导航指令失败')
  }
}

const handleTaskWaypointArrival = () => {
  if (!currentExecutingTask.value) return

  currentTaskWaypointIndex.value++
  const totalWaypoints = currentExecutingTask.value.points.length

  console.log(`目标点到达，进度: ${currentTaskWaypointIndex.value}/${totalWaypoints}`)

  if (currentTaskWaypointIndex.value >= totalWaypoints) {
    ElMessage.success(`任务 "${currentExecutingTask.value.taskName}" 的所有目标点已完成！`)
    console.log('任务所有目标点执行完成')
  } else {
    ElMessage.success(`第 ${currentTaskWaypointIndex.value} 个目标点已到达，继续前往下一个目标点...`)
    setTimeout(() => {
      executeNextWaypoint()
    }, 2000)
  }
}

const onWpCreateTask = () => {
  if (selectedWaypointIds.value.length === 0) {
    ElMessage.warning('请先选择要添加到任务中的目标点')
    return
  }

  const selectedWaypointsList = waypoints.value.filter(wp => selectedWaypointIds.value.includes(wp.id))
  console.log(`准备使用 ${selectedWaypointsList.length} 个目标点创建任务`, selectedWaypointsList)

  generateTaskParam.selectedWaypoints = selectedWaypointsList
  taskGenerateDiaShow.value = true
}

const onWpSelectionChange = (selection) => {
  selectedWaypointIds.value = selection.map(wp => wp.id)
  waypointSingle.value = selection.length !== 1
  waypointMultiple.value = selection.length === 0
  console.log('目标点选择变更:', selectedWaypointIds.value)
}

const onMapSelectModeChange = (isActive) => {
  selectPointMode.value = isActive
  initPoseMode.value = false

  if (isActive) {
    ElMessage.success('已开启地图选点模式，点击地图添加目标点')
  } else {
    ElMessage.info('已关闭地图选点模式')
  }
}

const clearTaskViewWaypoints = () => {
  if (taskViewAutoCloseTimer.value) {
    clearTimeout(taskViewAutoCloseTimer.value)
    taskViewAutoCloseTimer.value = null
  }

  if (olmap.value && currentViewTaskWaypointIds.value.length > 0) {
    currentViewTaskWaypointIds.value.forEach(waypointId => {
      if (olmap.value.removeIconHtmlById) {
        olmap.value.removeIconHtmlById(waypointId)
      }
    })
    currentViewTaskWaypointIds.value = []
    console.log('已清除任务查看标记点')
  }
}

const onTaskView = async (task) => {
  console.log('查看任务详情:', task)

  try {
    clearTaskViewWaypoints()

    const response = await getTask(mapName.value, task.taskName)
    console.log('任务详情响应:', response)

    if (response && response.coord && response.coord.length > 0) {
      const waypointList = response.coord.map((coord, index) => ({
        id: index + 1,
        name: `点位${index + 1}`,
        x: coord[0],
        y: coord[1]
      }))

      waypointList.forEach((waypoint, index) => {
        if (olmap.value && olmap.value.addHtmlIcon) {
          const displayId = index + 1
          olmap.value.addHtmlIcon(displayId, waypoint.x, waypoint.y, '', 'task-view')
          currentViewTaskWaypointIds.value.push(`calibration-${displayId}`)
        }
      })

      taskViewAutoCloseTimer.value = setTimeout(() => {
        clearTaskViewWaypoints()
      }, 10000)

      console.log(`显示任务点位:`, waypointList)
    } else {
      ElMessage.warning('该任务没有包含点位数据')
    }
  } catch (error) {
    console.error('加载任务详情失败:', error)
    ElMessage.error('加载任务详情失败: ' + (error.message || '未知错误'))
  }
}

const onTaskEdit = async (task) => {
  console.log('编辑任务:', task)

  try {
    const response = await getTask(mapName.value, task.taskName)
    console.log('任务详情响应:', response)

    if (response) {
      editTaskParam.originalTaskName = task.taskName
      editTaskParam.taskId = task.taskId
      editTaskParam.taskName = task.taskName
      editTaskParam.count = response.repeate || 1

      if (response.cron) {
        const cronParts = response.cron.split(' ')
        if (cronParts.length >= 7) {
          const minutes = String(cronParts[1]).padStart(2, '0')
          const hours = String(cronParts[2]).padStart(2, '0')
          const weekdays = cronParts[5]

          editTaskParam.time = `${hours}:${minutes}:00`

          if (weekdays !== '*' && weekdays !== '?') {
            editTaskParam.date = weekdays.split(',').filter(d => d)
          } else {
            editTaskParam.date = []
          }
        } else if (cronParts.length >= 5) {
          const minutes = String(cronParts[0]).padStart(2, '0')
          const hours = String(cronParts[1]).padStart(2, '0')
          const weekdays = cronParts[4]

          editTaskParam.time = `${hours}:${minutes}:00`

          if (weekdays !== '*' && weekdays !== '?') {
            editTaskParam.date = weekdays.split(',').filter(d => d)
          } else {
            editTaskParam.date = []
          }
        }
      } else {
        editTaskParam.time = ''
        editTaskParam.date = []
      }

      editTaskParam.selectedWaypoints = (response.coord || []).map((coord, index) => ({
        id: index + 1,
        name: `目标点${index + 1}`,
        x: coord[0].toString(),
        y: coord[1].toString(),
        type: response.plan && response.plan[index] === 'route' ? 1 : 0,
        action: response.action && response.action[index] ?
          convertApiActionToEditFormat(response.action[index]) :
          [{ value: 0, other: 0 }]
      }))

      taskEditDiaShow.value = true
    } else {
      ElMessage.error('获取任务详情失败')
    }
  } catch (error) {
    console.error('加载任务详情失败:', error)
    ElMessage.error('加载任务详情失败: ' + (error.message || '未知错误'))
  }
}

const convertApiActionToEditFormat = (actions) => {
  if (!actions || actions.length === 0) {
    return [{ value: 0, other: 0 }]
  }

  return actions.map(action => {
    const actionTypeMap = {
      'wait': 0,
      'start_record': 1,
      'stop_record': 2,
      'add_trajectory': 3,
      'hook_mount': 4,
      'hook_unmount': 5
    }

    const value = actionTypeMap[action.type] || 0
    const result = { value }

    if (action.type === 'wait' && action.duration !== undefined) {
      result.other = action.duration
    }

    return result
  })
}

const closeTaskEdit = () => {
  taskEditDiaShow.value = false
  resetEditTaskParam()
}

const resetEditTaskParam = () => {
  editTaskParam.originalTaskName = ''
  editTaskParam.taskId = ''
  editTaskParam.taskName = ''
  editTaskParam.count = 1
  editTaskParam.time = ''
  editTaskParam.date = []
  editTaskParam.selectedWaypoints = []
}

const submitTaskEdit = async () => {
  const orderedPoints = editTaskParam.selectedWaypoints || []

  if (!editTaskParam.taskName) {
    ElMessage.warning('请输入任务名称')
    return
  }

  if (orderedPoints.length === 0) {
    ElMessage.warning('任务必须包含至少一个目标点')
    return
  }

  try {
    const coordinates = orderedPoints.map(point => [
      parseFloat(point.x),
      parseFloat(point.y),
      0
    ])

    const plan = orderedPoints.map(point => {
      return point.type === 1 ? 'route' : 'free'
    })

    let cron = ''
    if (editTaskParam.time && editTaskParam.date.length > 0) {
      let hours, minutes
      if (typeof editTaskParam.time === 'string') {
        const timeParts = editTaskParam.time.split(':')
        hours = timeParts[0]
        minutes = timeParts[1]
      } else {
        const timeObj = new Date(editTaskParam.time)
        hours = String(timeObj.getHours()).padStart(2, '0')
        minutes = String(timeObj.getMinutes()).padStart(2, '0')
      }
      const weekdays = editTaskParam.date.sort().join(',')
      cron = `00 ${minutes} ${hours} ? * ${weekdays} *`
    }

    const taskData = {
      taskId: editTaskParam.taskId,
      map: mapName.value,
      taskName: editTaskParam.taskName,
      path: editTaskParam.taskName,
      coord_type: 'local',
      cron: cron,
      executeTime: editTaskParam.time || null,
      executeWeekdays: editTaskParam.date.join(',') || null,
      coord: coordinates,
      plan: plan,
      action: [[]],
      repeate: editTaskParam.count || 1
    }

    const response = await updateTask(taskData)
    console.log("更新任务响应:", response)

    if (response.status === true) {
      ElMessage.success('任务更新成功')
      await loadTaskList()
      closeTaskEdit()
    } else {
      ElMessage.error('更新任务失败: ' + (response.msg || '未知错误'))
    }
  } catch (error) {
    console.error("更新任务失败:", error)
      ElMessage.error('更新任务失败: ' + (error.message || '未知错误'))
  }
}

const onTaskStart = async (task) => {
  console.log('开始任务:', task)

  if (isTaskExecuting.value) {
    ElMessage.warning('已有任务正在执行，请先完成或取消当前任务')
    return
  }

  try {
    const response = await getTask(mapName.value, task.taskName)
    console.log('任务详情响应:', response)

    if (response && response.coord && response.coord.length > 0) {
      const waypointList = response.coord.map((coord, index) => ({
        id: index + 1,
        name: `目标点${index + 1}`,
        x: coord[0],
        y: coord[1],
        type: response.plan && response.plan[index] === 'route' ? 1 : 0,
        action: response.action && response.action[index] ? response.action[index] : []
      }))

      task.points = waypointList
      task.totalWaypoints = waypointList.length

      const timestamp = new Date().getTime()

      currentExecutingTask.value = task
      currentTaskWaypointIndex.value = 0
      lastTaskExecRequest.value = { roadmap: mapName.value, task: task.taskName }
      isTaskExecuting.value = true
      taskExecutionStatus.value = 'executing'

      task.status = 'running'
      task.executionStatus = 'executing'

      // 发送启动任务请求
      await startTask(mapName.value, task.taskName)

      ElMessage.success(`正在启动任务 "${task.taskName}"，包含 ${waypointList.length} 个目标点`)
    } else {
      ElMessage.error('任务没有包含目标点，无法执行')
    }
  } catch (error) {
    console.error('获取任务详情失败:', error)
    ElMessage.error('获取任务详情失败: ' + (error.message || '未知错误'))
  }
}

const onTaskPause = async (task) => {
  console.log('暂停任务:', task)

  if (task.status !== 'running') {
    ElMessage.warning('该任务当前未在执行中')
    return
  }

  try {
    await pauseTask()
    task.status = 'paused'
    ElMessage.info('任务已暂停')
  } catch (error) {
    console.error('暂停任务失败:', error)
    ElMessage.error('暂停任务失败')
  }
}

const onTaskStop = async (task) => {
  console.log('停止任务:', task)

  if (!isTaskExecuting.value || currentExecutingTask.value?.taskId !== task.taskId) {
    ElMessage.warning('该任务当前未在执行中')
    return
  }

  try {
    await ElMessageBox.confirm(`确定要取消任务 "${task.taskName}" 吗？`, '取消任务', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    await cancelTask()

    console.log("发送取消任务请求成功")
  } catch {
    // 用户取消
  }
}

const onTaskRemove = async (task) => {
  console.log('删除任务:', task)

  if (isTaskExecuting.value && currentExecutingTask.value?.taskId === task.taskId) {
    ElMessage.warning('任务正在执行中，无法删除。请先停止任务。')
    return
  }

  try {
    await ElMessageBox.confirm(`确定要删除任务 "${task.taskName}" 吗？`, '删除任务', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    try {
      const response = await delTask({
        map: mapName.value,
        path: task.taskName,
        taskId: task.taskId || null
      })

      if (response.status === true) {
        ElMessage.success(`任务 "${task.taskName}" 已删除`)
        await loadTaskList()
      } else {
        ElMessage.error('删除任务失败: ' + (response.msg || '未知错误'))
      }
    } catch (error) {
      console.error("删除任务失败:", error)
      ElMessage.error('删除任务失败: ' + (error.message || '未知错误'))
    }
  } catch {
    // 用户取消
  }
}

const onTaskResume = async (task) => {
  console.log('继续任务:', task)

  if (task.status !== 'paused') {
    ElMessage.warning('该任务当前不在暂停状态')
    return
  }

  try {
    await resumeTask()
    task.status = 'running'
    ElMessage.success('任务已继续')
  } catch (error) {
    console.error('继续任务失败:', error)
    ElMessage.error('继续任务失败')
  }
}

const getTaskStatusTextByStatus = (status) => {
  const statusMap = {
    0: '运行中',
    1: '空闲',
    'idle': '空闲',
    'running': '运行中',
    'paused': '暂停',
    'completed': '已完成',
    'error': '失败'
  }
  return statusMap[status] || '未知'
}

const getTaskStatusClass = (status) => {
  const statusClassMap = {
    0: 'status-running',
    1: 'status-idle',
    'idle': 'status-idle',
    'running': 'status-running',
    'paused': 'status-paused',
    'completed': 'status-completed',
    'error': 'status-error'
  }
  return statusClassMap[status] || 'status-unknown'
}

const formatTime = (time) => {
  if (!time) return '--'
  if (typeof time === 'string') return time
  if (time instanceof Date) {
    return time.toLocaleTimeString('zh-CN', {
      hour12: false,
      hour: '2-digit',
      minute: '2-digit'
    })
  }
  return '--'
}

const formatDate = (dateArray) => {
  if (!dateArray || !Array.isArray(dateArray) || dateArray.length === 0) return '--'

  const dayNames = {
    '1': '周一',
    '2': '周二',
    '3': '周三',
    '4': '周四',
    '5': '周五',
    '6': '周六',
    '7': '周日'
  }

  return dateArray.map(day => dayNames[day] || day).join(', ')
}

const formatSeconds = (seconds) => {
  if (!seconds || seconds < 0) return '00:00:00'

  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = Math.floor(seconds % 60)

  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

const onSettingChange = (setting) => {
  console.log('功能设置变更:', setting)
  settingParams[setting.key] = setting.value

  switch(setting.key) {
    case 'pointCloud':
      ElMessage.info(`点云显示已${setting.value ? '开启' : '关闭'}`)
      break
    case 'baseMap':
      ElMessage.info(`底图显示已${setting.value ? '开启' : '关闭'}`)
      break
    case 'pointId':
      ElMessage.info(`点ID显示已${setting.value ? '开启' : '关闭'}`)
      break
    case 'follow':
      ElMessage.info(`位置跟随已${setting.value ? '开启' : '关闭'}`)
      break
    case 'network':
      ElMessage.info(`网络邻居显示已${setting.value ? '开启' : '关闭'}`)
      break
  }
}

const loadTaskList = async () => {
  try {
    const response = await listTask(mapName.value)
    console.log("任务列表：",response);
    
    if (response.status && response.paths && Array.isArray(response.paths)) {
      const oldTasks = tasks.value || []

      // 新的API返回格式: paths数组每个元素是包含完整信息的对象
      const taskPromises = response.paths.map(async (taskItem) => {
        const taskName = taskItem.taskName || taskItem.path
        const existingTask = oldTasks.find(t => t.taskName === taskName)

        let taskObj = {
          taskId: taskItem.taskId || 0,
          taskName: taskName,
          status: taskItem.status || 'idle',
          count: taskItem.repeatCount || taskItem.repeate || 1,
          time: taskItem.executeTime || '',
          date: taskItem.executeWeekdays ? taskItem.executeWeekdays.split(',') : [],
          cron: taskItem.cron || '',
          points: [],
          executionStatus: 'idle',
          currentWaypointIndex: 0,
          totalWaypoints: 0,
          scheduledTime: null,
          scheduledTimeStr: '',
          scheduledWeekDays: [],
          shouldRunToday: false
        }

        // 解析cron表达式获取定时信息
        if (taskItem.cron) {
          const cronInfo = parseCronExpression(taskItem.cron)
          taskObj.scheduledTimeStr = cronInfo.timeStr || taskObj.time
          taskObj.scheduledWeekDays = cronInfo.weekDays

          if (cronInfo.hours !== null && cronInfo.minutes !== null) {
            const scheduledTime = new Date()
            scheduledTime.setHours(cronInfo.hours, cronInfo.minutes, 0, 0)
            taskObj.scheduledTime = scheduledTime
          }

          const currentDay = new Date().getDay() || 7
          taskObj.shouldRunToday = cronInfo.weekDays.includes(String(currentDay))
        }

        // 解析目标点坐标
        if (taskItem.coord && Array.isArray(taskItem.coord)) {
          taskObj.points = taskItem.coord.map((coord, idx) => ({
            id: idx + 1,
            x: coord[0],
            y: coord[1],
            z: coord[2] || 0,
            type: taskItem.plan && taskItem.plan[idx] === 'route' ? 1 : 0,
            action: taskItem.action && taskItem.action[idx] || []
          }))
          taskObj.totalWaypoints = taskObj.points.length
        }

        // 保留运行中任务的执行状态
        if (currentExecutingTask.value && currentExecutingTask.value.taskName === taskName) {
          taskObj.status = currentExecutingTask.value.status || 'running'
          taskObj.executionStatus = currentExecutingTask.value.executionStatus || 'executing'
          taskObj.currentWaypointIndex = currentTaskWaypointIndex.value || 0
          if (currentExecutingTask.value.points) {
            taskObj.points = currentExecutingTask.value.points
          }
        } else if (existingTask && existingTask.status !== 'idle') {
          console.log(`保留任务状态: ${taskName} - ${existingTask.status}`)
          taskObj.status = existingTask.status
          taskObj.executionStatus = existingTask.executionStatus
          taskObj.currentWaypointIndex = existingTask.currentWaypointIndex
        }

        return taskObj
      })

      tasks.value = await Promise.all(taskPromises)
      console.log("任务列表加载成功，包含完整cron配置:", tasks.value.length, "个任务")
      calculateTodayScheduledTasks()
    } else {
      console.error("加载任务列表失败，响应:", response)
      tasks.value = []
    }
  } catch (error) {
    console.error("加载任务列表异常:", error)
    tasks.value = []
  }
}

const parseCronExpression = (cronStr) => {
  const result = {
    timeStr: '',
    hours: null,
    minutes: null,
    weekDays: []
  }

  if (!cronStr) return result

  try {
    const parts = cronStr.split(' ')

    if (parts.length >= 6) {
      const minutes = parts[1]
      const hours = parts[2]
      const weekdays = parts[5]

      if (hours !== '*' && hours !== '?' && minutes !== '*' && minutes !== '?') {
        result.hours = parseInt(hours)
        result.minutes = parseInt(minutes)
        result.timeStr = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`
      }

      if (weekdays !== '*' && weekdays !== '?') {
        result.weekDays = weekdays.split(',').map(d => d.trim()).filter(d => d)
      }
    } else if (parts.length >= 5) {
      const minutes = parts[0]
      const hours = parts[1]
      const weekdays = parts[4]

      if (hours !== '*' && hours !== '?' && minutes !== '*' && minutes !== '?') {
        result.hours = parseInt(hours)
        result.minutes = parseInt(minutes)
        result.timeStr = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:00`
      }

      if (weekdays !== '*' && weekdays !== '?') {
        result.weekDays = weekdays.split(',').map(d => d.trim()).filter(d => d)
      }
    }
  } catch (error) {
    console.error("解析cron表达式失败:", cronStr, error)
  }

  return result
}

const startTaskListTimer = () => {
  stopTaskListTimer()

  taskListTimer.value = setInterval(() => {
    loadTaskList()
  }, 5000)

  console.log('任务列表定时刷新已启动（每5秒）')
}

const stopTaskListTimer = () => {
  if (taskListTimer.value) {
    clearInterval(taskListTimer.value)
    taskListTimer.value = null
    console.log('任务列表定时刷新已停止')
  }
}
</script>

<style scoped lang="scss">
.point-edit-span {
  display: block;
  margin: 10px 0;
  font-weight: bold;
}

.drawer {
  height: 100%;
  position: absolute;
  top: 0;
  left: 100%;
  border-radius: 0 0 12px 0;
  border-left: 1px solid #F0F0F0;
  padding: 8px 15px;
  border-right: 1px solid #ececec;
  border-bottom: 1px solid #ececec;
  overflow-y: auto;
  background-color: #fff;
  z-index: 1000;
}

.drawer-close {
  position: absolute;
  right: 3px;
  top: 3px;
  cursor: pointer;
}

.drawer-title {
  position: absolute;
  top: -23px;
  left: -8px;
  font-size: 13px;
  font-weight: bold;
  color: #838383;
}

.drawer p {
  font-size: 13px;
  border-left: 5px #D1D1D1 solid;
  padding-left: 5px;
  margin: 8px 0;
  border-radius: 3px 0 0 3px;
}

.img-container {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 7px;
  background: linear-gradient(135deg, #00bcd4, #009688);
  cursor: pointer;
  width: 70%;
  aspect-ratio: 1;
  margin-top: 10px;
}

.img-container:hover {
  transform: scale(1.02);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
  background-color: #00796b;
}

.img-container:active {
  transform: scale(0.98);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  background-color: #004d40;
}

.img-container img {
  opacity: 1;
}

.img-container span {
  font-size: 12px;
  color: #ffffff;
  font-weight: bold;
}

.img-container.active {
  background: linear-gradient(135deg, #007d8d, #004b43);
}

.explore-unit {
  margin-left: 8px;
}

:deep(.el-dialog__body) {
  padding: 20px 20px 0 20px;
}

:deep(.download-map .el-dialog__body) {
  padding: 10px 20px 0 20px !important;
}

:deep(.el-table--medium .el-table__cell) {
  padding: 6px 0;
}

:deep(.action-menu .action-menu_input .el-input__inner) {
  padding: 0 5px;
}

.task-status-tag {
  margin-left: 20px;
}

:deep(.drawer .el-collapse-item__header) {
  height: 38px;
  line-height: 38px;
  color: #767676;
  font-weight: bold;
}

:deep(.drawer .el-collapse-item__content) {
  text-align: left;
  padding-bottom: 10px;
}

:deep(.drawer .el-collapse) {
  border: 1px solid #EBEEF5;
  padding: 0 8px;
  border-radius: 5px;
}

.collapse-content-div {
  margin-top: 0;
}

:deep(.collapse-content-div .el-button--mini) {
  padding: 4px 10px;
}

.hand-ment-mark {
  position: absolute;
  bottom: 12px;
  left: 12px;
  z-index: 1000;
}

.obstacle-warning {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 2000;
  min-width: 320px;
  max-width: 400px;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(10px);
  animation: slideInRight 0.3s ease-out;

  &.obstacle-info {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.95) 0%, rgba(99, 102, 241, 0.95) 100%);
    border: 1px solid rgba(59, 130, 246, 0.3);
  }

  &.obstacle-warning {
    background: linear-gradient(135deg, rgba(245, 158, 11, 0.95) 0%, rgba(251, 191, 36, 0.95) 100%);
    border: 1px solid rgba(245, 158, 11, 0.3);
  }

  &.obstacle-danger {
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.95) 0%, rgba(248, 113, 113, 0.95) 100%);
    border: 1px solid rgba(239, 68, 68, 0.3);
    animation: pulse 2s infinite;
  }

  .warning-content {
    display: flex;
    align-items: flex-start;
    padding: 16px 20px;
    color: white;

    .warning-icon {
      margin-right: 12px;
      margin-top: 2px;
      flex-shrink: 0;

      i {
        font-size: 20px;
        color: white;
      }
    }

    .warning-text {
      flex: 1;

      .warning-title {
        font-size: 14px;
        font-weight: 600;
        margin-bottom: 4px;
        color: white;
      }

      .warning-message {
        font-size: 13px;
        line-height: 1.4;
        margin-bottom: 8px;
        color: rgba(255, 255, 255, 0.95);
      }

      .obstacle-distances {
        display: flex;
        gap: 12px;
        flex-wrap: wrap;

        .distance-item {
          font-size: 11px;
          background: rgba(255, 255, 255, 0.2);
          padding: 2px 8px;
          border-radius: 12px;
          color: white;
          font-weight: 500;
          border: 1px solid rgba(255, 255, 255, 0.3);
        }
      }
    }

    .warning-close {
      margin-left: 8px;
      margin-top: 2px;
      cursor: pointer;
      padding: 4px;
      border-radius: 50%;
      transition: all 0.2s ease;
      flex-shrink: 0;

      &:hover {
        background: rgba(255, 255, 255, 0.2);
      }

      i {
        font-size: 16px;
        color: white;
      }
    }
  }
}

@keyframes slideInRight {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  }
  50% {
    transform: scale(1.02);
    box-shadow: 0 12px 32px rgba(239, 68, 68, 0.3);
  }
}

.obstacle-stop-warning {
  position: absolute;
  top: 80px;
  right: 20px;
  z-index: 2000;
  min-width: 380px;
  border-radius: 12px;
  background: white;
  box-shadow: 0 8px 32px rgba(239, 68, 68, 0.2);
  border: 2px solid #FF5555;
  animation: slideInRight 0.3s ease-out, breathe 2s infinite ease-in-out;

  .stop-warning-content {
    display: flex;
    align-items: center;
    padding: 16px;
    gap: 16px;

    .countdown-circle {
      flex-shrink: 0;
      width: 80px;
      height: 80px;
      border-radius: 50%;
      background: linear-gradient(135deg, #FF5555 0%, #FF8080 100%);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      color: white;
      box-shadow: 0 4px 12px rgba(255, 85, 85, 0.3);

      .countdown-number {
        font-size: 28px;
        font-weight: bold;
        line-height: 1;
      }

      .countdown-label {
        font-size: 12px;
        margin-top: 4px;
        opacity: 0.9;
      }
    }

    .stop-warning-text {
      flex: 1;

      .stop-warning-title {
        font-size: 16px;
        font-weight: 600;
        color: #FF5555;
        margin-bottom: 6px;
      }

      .stop-warning-message {
        font-size: 13px;
        color: #666;
        line-height: 1.4;
        margin-bottom: 6px;
      }

      .stop-warning-state {
        font-size: 12px;
        color: #999;
      }
    }

    .stop-warning-actions {
      flex-shrink: 0;

      .el-button {
        padding: 8px 16px;
        font-size: 13px;
      }
    }
  }
}

@keyframes breathe {
  0%, 100% {
    box-shadow: 0 8px 32px rgba(239, 68, 68, 0.2);
  }
  50% {
    box-shadow: 0 12px 40px rgba(239, 68, 68, 0.35);
  }
}

.notification__title {
  font-size: 1.2rem;
}

.navigation-container {
  width: 100%;
  min-height: calc(100vh - 84px);
  overflow: hidden;
  position: relative;
  background: var(--color-bg-secondary);

  .map-stage {
    position: relative;
    width: 100%;
    height: calc(100vh - 84px);
    min-height: 600px;
    overflow: hidden;
    background: var(--color-bg-secondary);
  }
}

.nav-toolbar {
  position: absolute;
  left: 16px;
  top: 96px;
  z-index: 50;
}

.main-menu {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

:deep(.waypoint-edit-dialog) {
  .el-dialog {
    border-radius: 12px !important;
    overflow: hidden !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    position: fixed !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
  }

  .el-dialog__header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 20px 24px 16px;
    margin: 0;
    border-radius: 12px 12px 0 0 !important;

    .el-dialog__title {
      color: white;
      font-weight: 600;
      font-size: 16px;
    }

    .el-dialog__close {
      color: white;
      font-size: 18px;

      &:hover {
        color: #f0f0f0;
      }
    }
  }

  .el-dialog__body {
    padding: 24px;
    background: #f8fafc;
    margin: 0 !important;
  }

  .el-dialog__footer {
    padding: 16px 24px 24px;
    background: #f8fafc;
    border-top: 1px solid #e2e8f0;
    border-radius: 0 0 12px 12px !important;
    margin: 0 !important;
  }
}

.dialog-content {
  .form-section {
    background: white;
    border-radius: 10px;
    padding: 24px;
    margin-bottom: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    border: 1px solid #f1f5f9;

    &:last-child {
      margin-bottom: 0;
    }

    .section-title {
      display: flex;
      align-items: center;
      margin: 0 0 20px 0;
      font-size: 15px;
      font-weight: 600;
      color: #2d3748;
      border-bottom: 2px solid #e2e8f0;
      padding-bottom: 10px;

      i {
        margin-right: 10px;
        color: #667eea;
        font-size: 18px;
      }

      .add-action-btn {
        margin-left: 12px !important;
        display: inline-flex !important;
        align-items: center !important;
        padding: 4px 8px !important;

        i {
          margin-right: 4px !important;
          font-size: 12px !important;
          color: #667eea !important;
        }

        span {
          font-size: 12px !important;
          color: #667eea !important;
        }
      }
    }
  }

  .waypoint-form {
    .el-form-item {
      margin-bottom: 18px;
      display: flex !important;
      align-items: center !important;

      &:last-child {
        margin-bottom: 0;
      }

      .el-form-item__content {
        flex: 1 !important;
        margin-left: 0 !important;
      }
    }

    .coordinate-input {
      margin-bottom: 4px;
    }

    .el-form-item__label {
      font-weight: 600 !important;
      color: #2d3748 !important;
      padding-right: 12px !important;
      min-width: 100px !important;
      font-size: 14px !important;
      line-height: 44px !important;
      height: 44px !important;
      display: flex !important;
      align-items: center !important;
      margin-bottom: 0 !important;
    }

    .coordinate-input {
      .el-input__inner {
        border-radius: 8px !important;
        border: 1px solid #e2e8f0 !important;
        height: 44px !important;
        font-size: 15px !important;
        padding: 0 16px !important;
        background: #ffffff !important;
        transition: all 0.2s ease !important;

        &:focus {
          border-color: #667eea !important;
          box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
          background: #fafbff !important;
        }

        &:hover {
          border-color: #cbd5e0 !important;
        }
      }
    }
  }
}
</style>
