<template>
  <!-- 包含航空器路由的绘制 -->
  <!-- 气象监测站弹窗 -->
  <!-- <WeatherStationPopup 
    :visible="weatherStationVisible" 
    @close="weatherStationVisible = false" 
  /> -->
  
  <!-- 车辆详情弹窗 -->
  <VehicleDetailPopup 
    :visible="vehicleDetailVisible" 
    :detail="vehicleDetail"
    :popup-style="detailPopupStyle"
    @close="vehicleDetailVisible = false" 
  />

  <!-- 告警/预警提示框 -->
  <!-- <AlarmNotification 
    
    ref="alarmNotification"
    @close="handleAlarmClose"
  /> -->
  
  <!-- 车辆动画系统 -->
  <VehicleAnimationSystem 
    ref="animationSystem"
    :map="map"
    :vehicle-source="vehicleSource"
    :vehicles="vehicles"
    :get-vehicle-style="styleManager?.getVehicleStyle || defaultGetVehicleStyle"
    :apply-style="applyVehicleStyleWithVisibility"
    :apply-label-position="applyVehicleLabelPosition"
  />
  
  <!-- 车辆标签系统 -->
  <VehicleLabelSystem 
    ref="labelSystem"
    :map="map"
    :vehicles="vehicles"
  />
  
  <!-- 车辆样式管理器 -->
  <VehicleStyleManager 
    ref="styleManager"
    :vehicles="vehicles"
  />

  <div
    v-if="pathConflictDisplayEnabled && currentPathConflict"
    class="path-conflict-card"
    :class="`level-${currentPathConflict.level}`"
  >
    <div class="path-conflict-header">
      <span>{{ currentPathConflict.title }}</span>
      <span class="path-conflict-level">{{ getConflictLevelText(currentPathConflict.level) }}</span>
    </div>
    <div class="path-conflict-body">
      <div>{{ currentPathConflict.aircraftName || '未知航空器' }} / {{ currentPathConflict.vehicleName || '未知车辆' }}</div>
      <div v-if="currentPathConflict.directionLockText" class="path-conflict-muted">
        方向锁定：{{ currentPathConflict.directionLockText }}
      </div>
      <div>飞机距离：{{ formatConflictDistance(currentPathConflict.aircraftDistance) }}</div>
      <div>车辆距离：{{ formatConflictDistance(currentPathConflict.vehicleDistance) }}</div>
      <div v-if="hasConflictForwardDistance(currentPathConflict)" class="path-conflict-debug">
        前向距离：对象1 {{ formatConflictDistance(currentPathConflict.object1ForwardDistance) }} / 对象2 {{ formatConflictDistance(currentPathConflict.object2ForwardDistance) }}
      </div>
      <div
        v-if="currentPathConflict.directionLockFailed && currentPathConflict.directionLockReason"
        class="path-conflict-reason"
      >
        原因：{{ currentPathConflict.directionLockReason }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, onActivated, onDeactivated, defineProps, defineEmits } from 'vue';
import { Vector as VectorSource } from 'ol/source';
import { Vector as VectorLayer } from 'ol/layer';
import { Style, Icon, Stroke, Fill, Circle, Text } from 'ol/style';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { LineString } from 'ol/geom';
import { transform } from 'ol/proj';
import GeoJSON from 'ol/format/GeoJSON';
import proj4 from 'proj4';
import { register } from 'ol/proj/proj4.js';
import { get as getProj } from 'ol/proj';
import WebSocketService, { createWebSocket, resetWebSocketInstance } from '../../../utils/websocket.js';
import useVehicleDisplayStore from '@/store/modules/vehicleDisplay';
import useSettingsStore from '@/store/modules/settings';
import { getPathConflictDisplayEnabled, isNewPathConflictPayload, normalizePathConflictMessage } from '@/utils/pathConflictDisplay.mjs';

// 导入子组件
import VehicleAnimationSystem from './VehicleAnimationSystem.vue';
import VehicleLabelSystem from './VehicleLabelSystem.vue';
import VehicleDetailPopup from './VehicleDetailPopup.vue';
import WeatherStationPopup from './WeatherStationPopup.vue';
import AlarmNotification from '../info/AlarmNotification.vue'; // 导入告警通知组件
import VehicleStyleManager from './VehicleStyleManager.vue';

// 导入默认图标
import carIcon from '../../../assets/images/noPeopleCar.svg';
import specialCar from '../../../assets/images/specialCar.svg';
import aircraftIcon from '../../../assets/images/aircraft.png'; // 航空器使用aircraft.png图标
import aircraftRouteIcon from '../../../assets/images/Aircraft1.png';
// 不再使用不同状态的航空器图标
// import aircraftInIcon from '../../../assets/images/Aircraft1.png'; // 滑入航空器使用黄色图标
// import aircraftOutIcon from '../../../assets/images/Aircraft.png'; // 滑出航空器使用蓝色图标

// 预加载图标资源，确保图标立即可用
const carIconImg = new Image();
carIconImg.src = carIcon;
const aircraftIconImg = new Image();
aircraftIconImg.src = aircraftIcon;
const aircraftRouteIconImg = new Image();
aircraftRouteIconImg.src = aircraftRouteIcon;
// 不再预加载不同状态的航空器图标
// const aircraftInIconImg = new Image();
// aircraftInIconImg.src = aircraftInIcon;
// const aircraftOutIconImg = new Image();
// aircraftOutIconImg.src = aircraftOutIcon;

const DEFAULT_VEHICLE_ICON_SCALE = 0.75;
const AIRCRAFT_ICON_SCALE = DEFAULT_VEHICLE_ICON_SCALE * 1.3;

// 为SockJS提供polyfill
if (typeof window !== 'undefined' && !window.global) {
  window.global = window;
}

// 定义props接收地图实例
const props = defineProps({
  map: Object
});

// 定义emit事件
const emit = defineEmits(['vehicle-details-updated']);

// 注册 EPSG:4528 坐标系
if (typeof window !== 'undefined' && proj4) {
  // 检查是否已经注册过该坐标系
  if (!proj4.defs('EPSG:4528')) {
   proj4.defs(
  "EPSG:4528",
  "+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs",
);
    console.log('已注册 EPSG:4528 坐标系');
  }
  
  // 注册到 OpenLayers
  register(proj4);
}
console.log("注册EPSG:4528",getProj('EPSG:4528'));
// 子组件引用
const animationSystem = ref(null);
const labelSystem = ref(null);
const styleManager = ref(null);
const alarmNotification = ref(null); // 告警通知组件引用
const vehicleDisplayStore = useVehicleDisplayStore();
const settingsStore = useSettingsStore();
const pathConflictDisplayEnabled = computed(() => getPathConflictDisplayEnabled(settingsStore));

// 气象监测站数据
const weatherStationVisible = ref(true);

// 车辆详情数据
const vehicleDetailVisible = ref(false);
const vehicleDetail = ref({
  id: 'QN001',
  type: '驱鸟车',
  status: '任务中',
  startTime: '11-19 11:30',
  currentLocation: 'A区T3点',
  startLocation: 'T1航站楼',
  endLocation: 'T3航站楼',
  totalDistance: '1.3km',
  battery: '60%',
  manager: '张三',
  phone: '18661910988'
});

// 弹窗位置样式
const detailPopupStyle = ref({
  left: '0px',
  top: '0px'
});

// WebSocket连接状态
const wsConnected = ref(false);
let wsService = null;
let reconnectTimer = null;
let cleanupTimer = null; // 航班定期清理定时器

// 车辆数据存储
const vehicles = ref({});
let vehicleLayer = null;
let vehicleSource = null;
let pathConflictLayer = null;
let pathConflictSource = null;
const pathConflicts = ref({});

const conflictLevelPriority = {
  EMERGENCY: 4,
  CRITICAL: 3,
  WARNING: 2,
  STATUS: 1
};

const currentPathConflict = computed(() => {
  const list = Object.values(pathConflicts.value || {});
  if (!list.length) return null;
  return list.sort((a, b) => {
    const levelDiff = (conflictLevelPriority[b.level] || 0) - (conflictLevelPriority[a.level] || 0);
    if (levelDiff) return levelDiff;
    return (b.updatedAt || 0) - (a.updatedAt || 0);
  })[0];
});

function getConflictLevelText(level) {
  if (level === 'EMERGENCY') return '紧急';
  if (level === 'CRITICAL') return '告警';
  if (level === 'WARNING') return '预警';
  return '计算';
}

function formatConflictDistance(value) {
  const num = Number(value);
  if (!Number.isFinite(num)) return '--';
  return `${Math.round(num)}米`;
}

function hasConflictForwardDistance(conflict) {
  if (!conflict) return false;
  return Number.isFinite(Number(conflict.object1ForwardDistance)) ||
    Number.isFinite(Number(conflict.object2ForwardDistance));
}

function refreshVehicleVisibility() {
  const all = vehicles.value || {};
  Object.keys(all).forEach((vehicleId) => {
    const vehicle = all[vehicleId];
    if (!vehicle?.feature) return;

    const typeKey = getVehicleTypeKey(vehicle);
    const isAircraft = typeKey === 'AIRCRAFT' || typeKey === 'AIRCRAFT_IN' || typeKey === 'AIRCRAFT_OUT';
    const enabled = isAircraft ? true : vehicleDisplayStore.isVehicleEnabled(vehicleId);
    if (!enabled) {
      vehicle.feature.setStyle(new Style({}));
      if (labelSystem.value?.setLabelVisibility) {
        labelSystem.value.setLabelVisibility(vehicleId, false);
      }
      return;
    }

    setVehicleStyleRespectVisibility(vehicleId, getDefaultVehicleStyle(vehicle));
    if (labelSystem.value?.setLabelVisibility) {
      labelSystem.value.setLabelVisibility(vehicleId, isLabelAllowedForVehicle(vehicleId));
    }
  });
}

watch(
  () => vehicleDisplayStore.enabledVehicleIds,
  () => {
    refreshVehicleVisibility();
  },
  { deep: true }
);

watch(
  () => vehicleDisplayStore.vehicleTypeOverrides,
  () => {
    refreshVehicleVisibility();
  },
  { deep: true }
);

// 车辆超速状态超时计时器存储
const speedViolationTimers = {};

// 飞机路线数据存储
const aircraftRoutes = ref({});  // 存储飞机路线数据，键为flightNo
let aircraftRouteLayer = null;   // 飞机路线图层
let aircraftRouteSource = null;  // 飞机路线数据源

// 飞机路线定时器存储
const aircraftRouteTimers = {};  // 存储每个航班路线的定时器
const aircraftRouteProgress = {};

function applyVehicleLabelPosition(vehicleId, coordinates) {
  if (labelSystem.value && labelSystem.value.updateLabelPosition) {
    labelSystem.value.updateLabelPosition(vehicleId, coordinates);
  }
}

// 动态收集所有车辆/航空器类别
const vehicleCategories = ref({
  'AIRCRAFT_IN': { visible: true, showLabel: true, name: '滑入航空器' },
  'AIRCRAFT_OUT': { visible: true, showLabel: true, name: '滑出航空器' },
  'AIRCRAFT': { visible: true, showLabel: true, name: '其他航空器' },
  'UNMANNED_VEHICLE': { visible: true, showLabel: true, name: '无人车' },
  'AIRPORT_VEHICLE': { visible: true, showLabel: true, name: '特勤车' },
  'SHUTTLE_VEHICLE': { visible: true, showLabel: true, name: '摆渡车' }
});

// 监听vehicleCategories变化，用于调试
watch(vehicleCategories, (newCategories) => {
  console.log('VehicleMovementControl: vehicleCategories 发生变化:', newCategories);
}, { deep: true });

// 告警/预警状态
const alertMessage = ref('');
const alertType = ref('');
let alertTimer = null;

// 违规/冲突状态计时器
const violationStatusTimers = ref({});

function clearStatusTimer(key) {
  const timers = violationStatusTimers.value || {};
  const t = timers[key];
  if (t) {
    clearTimeout(t);
    delete timers[key];
    violationStatusTimers.value = timers;
  }
}

function setStatusTimer(key, fn, ms) {
  clearStatusTimer(key);
  const timers = violationStatusTimers.value || {};
  timers[key] = setTimeout(fn, ms);
  violationStatusTimers.value = timers;
}

function clearConflictStatus(vehicleId) {
  const v = vehicles.value?.[vehicleId];
  if (!v) return;

  clearStatusTimer(`conflict:${vehicleId}`);
  v.warning = false;
  v.alarm = false;
  v.lastConflictLevel = undefined;
  v.lastConflictAt = undefined;

  if (v.position && labelSystem.value) {
    labelSystem.value.removeVehicleLabel(vehicleId);
    updateVehicleLabelIfAllowed(vehicleId, v.position, v.speed > 0.1 ? v.speed : 0);
  }

  if (v.feature && styleManager.value) {
    setVehicleStyleRespectVisibility(vehicleId, styleManager.value.getVehicleStyle(vehicleId, v.speed, v.heading));
  }
}

function markConflictStatus(vehicleId, level, message, ttlMs) {
  const v = vehicles.value?.[vehicleId];
  if (!v) return;

  const now = Date.now();
  v.lastConflictAt = now;
  v.lastConflictLevel = level;

  if (level === 'alarm') {
    v.alarm = true;
    v.warning = false;
  } else if (!v.alarm) {
    v.warning = true;
  }

  if (v.position) {
    updateVehicleLabelIfAllowed(vehicleId, v.position, v.speed, {
      description: message,
      isWarning: level === 'warning',
      isAlarm: level === 'alarm'
    });
  }

  const timerKey = `conflict:${vehicleId}`;
  if (!(Number(ttlMs) > 0)) {
    clearStatusTimer(timerKey);
    return;
  }

  setStatusTimer(
    timerKey,
    () => {
      const latest = vehicles.value?.[vehicleId];
      if (!latest) return;
      if (latest.lastConflictAt !== now) return;
      clearConflictStatus(vehicleId);
      clearStatusTimer(timerKey);
    },
    Number(ttlMs) > 0 ? Number(ttlMs) : 10000
  );
}

// 告警列表管理
const alarmList = ref([]); // 存储所有告警信息
const maxAlarmCount = 100; // 最大告警数量，防止列表过长
const alarmVisible = ref(true); // 控制告警面板显示状态

// 添加告警到列表
function addAlarm(alarm) {
  // 确保alarm对象包含所有必要字段
  const completeAlarm = {
    id: `alarm-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, // 生成唯一ID
    carId: alarm.carId || alarm.vehicleId || alarm.objectId || '未知车辆',
    carType: alarm.carType || alarm.vehicleType || alarm.objectType || '未知类型',
    time: alarm.time || formatTimeRange(new Date()),
    description: alarm.description || '未知告警',
    date: alarm.date || formatDateTime(new Date()),
    level: alarm.level || 'medium', // high, medium, low
    type: alarm.type || 'other', // car(冲突), report(越界), speed(超速), other
    ...alarm // 保留原始字段
  };
  
  // 添加到列表开头
  alarmList.value.unshift(completeAlarm);
  
  // 限制列表长度
  if (alarmList.value.length > maxAlarmCount) {
    alarmList.value = alarmList.value.slice(0, maxAlarmCount);
  }
  
  // 如果告警面板已打开，更新告警面板
  updateAlarmNotification();
  
  return completeAlarm.id; // 返回告警ID，便于后续引用
}

// 更新告警
function updateAlarm(alarmId, updates) {
  const index = alarmList.value.findIndex(alarm => alarm.id === alarmId);
  if (index !== -1) {
    alarmList.value[index] = { ...alarmList.value[index], ...updates };
    updateAlarmNotification();
    return true;
  }
  return false;
}

// 删除告警
function removeAlarm(alarmId) {
  const index = alarmList.value.findIndex(alarm => alarm.id === alarmId);
  if (index !== -1) {
    alarmList.value.splice(index, 1);
    updateAlarmNotification();
    return true;
  }
  return false;
}

// 清空告警列表
function clearAlarms() {
  alarmList.value = [];
  updateAlarmNotification();
}

// 更新告警面板
function updateAlarmNotification() {
  if (alarmNotification.value) {
    alarmNotification.value.updateAlarmList(alarmList.value);
  }
}

// 切换告警面板显示状态
function toggleAlarmNotification() {
  alarmVisible.value = !alarmVisible.value;
  if (alarmNotification.value) {
    if (alarmVisible.value) {
      alarmNotification.value.show();
    } else {
      alarmNotification.value.hide();
    }
  }
}

// 处理告警面板关闭事件
function handleAlarmClose() {
  alarmVisible.value = false;
  console.log('告警面板已关闭');
}

// 格式化时间范围，例如：T10:20-10:25
function formatTimeRange(date, durationMinutes = 5) {
  const startTime = new Date(date);
  const endTime = new Date(date);
  endTime.setMinutes(endTime.getMinutes() + durationMinutes);
  
  const startHour = startTime.getHours().toString().padStart(2, '0');
  const startMinute = startTime.getMinutes().toString().padStart(2, '0');
  const endHour = endTime.getHours().toString().padStart(2, '0');
  const endMinute = endTime.getMinutes().toString().padStart(2, '0');
  
  return `T${startHour}:${startMinute}-${endHour}:${endMinute}`;
}

// 格式化日期时间，例如：2025-03-19 10:30
function formatDateTime(date) {
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  const hour = date.getHours().toString().padStart(2, '0');
  const minute = date.getMinutes().toString().padStart(2, '0');
  
  return `${year}-${month}-${day} ${hour}:${minute}`;
}

// 处理告警显示
function handleAlertShow({ message, type, duration = 5000 }) {
  if (alertTimer) {
    clearTimeout(alertTimer);
    alertTimer = null;
  }
  
  alertMessage.value = message;
  alertType.value = type;
  
  if (Number(duration) > 0) {
    alertTimer = setTimeout(() => {
      alertMessage.value = '';
      alertType.value = '';
      alertTimer = null;
    }, duration);
  }
}

// 显示告警/预警消息
function showAlert(message, type, duration = 5000) {
  handleAlertShow({ message, type, duration });
}

function clearAlertMessage() {
  if (alertTimer) {
    clearTimeout(alertTimer);
    alertTimer = null;
  }
  alertMessage.value = '';
  alertType.value = '';
}

// 创建车辆图层
function createVehicleLayer() {
  if (!props.map) return;
  if (vehicleLayer) return;
  
  vehicleSource = new VectorSource();
  
  vehicleLayer = new VectorLayer({
    source: vehicleSource,
    zIndex: 20,
  });
  
  props.map.addLayer(vehicleLayer);
  
  setupMapListeners();
  
  props.map.on('click', handleMapClick);
}

// 创建飞机路线图层
function createAircraftRouteLayer() {
  if (!props.map) return;
  if (aircraftRouteLayer) return;
  
  aircraftRouteSource = new VectorSource();
  
  aircraftRouteLayer = new VectorLayer({
    source: aircraftRouteSource,
    zIndex: 15,  // 确保在车辆图层下方
    style: new Style({
      stroke: new Stroke({
        color: '#3388ff',
        width: 3
      })
    })
  });
  
  props.map.addLayer(aircraftRouteLayer);
}

function createPathConflictLayer() {
  if (!props.map) return;
  if (pathConflictLayer) return;

  pathConflictSource = new VectorSource();
  pathConflictLayer = new VectorLayer({
    source: pathConflictSource,
    zIndex: 2100,
  });
  props.map.addLayer(pathConflictLayer);
}

function getPathConflictStyle(conflict) {
  const color = '#3b82f6';

  return new Style({
    image: new Circle({
      radius: conflict.kind === 'alert' ? 10 : 8,
      fill: new Fill({ color }),
      stroke: new Stroke({ color: '#ffffff', width: 3 })
    }),
    text: new Text({
      text: conflict.title,
      offsetY: -22,
      font: '12px sans-serif',
      fill: new Fill({ color: '#ffffff' }),
      stroke: new Stroke({ color: 'rgba(0,0,0,0.75)', width: 3 })
    })
  });
}

// 处理地图点击事件
function handleMapClick(event) {
  const feature = props.map.forEachFeatureAtPixel(event.pixel, function(feature) {
    return feature;
  });
  
  if (feature) {
    const objectId = feature.getId();
    if (objectId && vehicles.value[objectId]) {
      const vehicle = vehicles.value[objectId];
      
      // vehicleDetail.value = {
      //   id: objectId,
      //   type: vehicle.type,
      //   status: '任务中',
      //   startTime: '11-19 11:30',
      //   currentLocation: '当前位置',
      //   startLocation: 'T1航站楼',
      //   endLocation: 'T3航站楼',
      //   totalDistance: '1.3km',
      //   battery: '60%',
      //   manager: '张三',
      //   phone: '18661910988'
      // };
          // 使用实时数据填充车辆详情
      vehicleDetail.value = {
        id: objectId,
        type: vehicle.type || '未知类型',
        status: vehicle.status || '任务中',
        startTime: vehicle.startTime || '11-19 11:30',
        currentLocation: vehicle.currentLocation || '当前位置',
        startLocation: vehicle.startLocation || 'T1航站楼',
        endLocation: vehicle.endLocation || 'T3航站楼',
        totalDistance: vehicle.totalDistance || '1.3km',
        battery: vehicle.soc || vehicle.battery || '60%',
        manager: vehicle.manager || vehicle.location || '张三',
        phone: vehicle.phone || vehicle.contactPhone || '18661910988'
      };
      const pixel = event.pixel;
      const viewportPosition = props.map.getViewport().getBoundingClientRect();
      
      detailPopupStyle.value = {
        left: (viewportPosition.left + pixel[0] + 10) + 'px',
        top: (viewportPosition.top + pixel[1] + 10) + 'px'
      };
      
      vehicleDetailVisible.value = true;
    } else {
      vehicleDetailVisible.value = false;
    }
  } else {
    vehicleDetailVisible.value = false;
  }
}

// 监听地图变化，确保标签位置正确更新
function setupMapListeners() {
  if (!props.map) return;
  
  // 监听地图移动结束事件
  props.map.on('moveend', () => {
    if (labelSystem.value) {
      labelSystem.value.updateAllLabels();
    }
  });
}

// 更新车辆位置
function updateVehiclePosition(vehicleData) {
  if (!vehicleSource || !props.map) return;
  
  const { object_id, object_type, position, heading, speed } = vehicleData;
  
  // 数据清洗与类型防空保护
  const parsedSpeed = Number(speed);
  const validSpeed = (Number.isFinite(parsedSpeed) && parsedSpeed >= 0) ? parsedSpeed : (vehicles.value[object_id]?.speed || 0);
  
  const parsedHeading = Number(heading);
  const validHeading = Number.isFinite(parsedHeading) ? parsedHeading : (vehicles.value[object_id]?.heading || 0);
  
  // 计算正确的旋转角度
  // 在OpenLayers中，0度是向上，顺时针增加
  // 而heading是0度为北，顺时针增加
  // 由于地图旋转了72度，heading=72对应地图上方
  const rotationRad = ((validHeading - 72) * Math.PI) / 180;
  console.log(`车辆${object_id}的heading值: ${validHeading}, 旋转角度计算: (${validHeading} - 72) * π/180 = ${rotationRad} 弧度, ${(validHeading - 72)}度, 车辆类型: ${object_type}`);
  
  let coordinates;

  coordinates = transform(
    [position.longitude, position.latitude], 
    'EPSG:4326', 
    props.map.getView().getProjection()
  );
 
  let feature = vehicleSource.getFeatureById(object_id);
  
  const overrideType = vehicleDisplayStore.getVehicleTypeOverride(object_id);
  const effectiveTypeRaw = String((overrideType || object_type || '')).trim();
  const rawType = String(object_type || '').trim();
  const vehicleType = effectiveTypeRaw.toUpperCase();
  
  const isAircraft = vehicleType === 'AIRCRAFT' || vehicleType === 'AIRCRAFT_IN' || vehicleType === 'AIRCRAFT_OUT' || vehicleType === 'HANGKONG';
  const isUnmannedVehicle = vehicleType === 'UNMANNED_VEHICLE' || vehicleType === 'WUREN' || effectiveTypeRaw.includes('无人');
  const isSpecialVehicle = vehicleType === 'SPECIAL_VEHICLE' || vehicleType === 'TEQIN' || effectiveTypeRaw.includes('特勤');
  const uObjectId = String(object_id || '').trim().toUpperCase();
  const hasAircraftRoute = isAircraft && !!aircraftRoutes.value[uObjectId];
  
  // 禁用不稳定的位置自动清理，统一由定时清理器处理
  // if (hasAircraftRoute) {
  //   tryAutoRemoveAircraftRouteByPosition(object_id, coordinates);
  // }
  
  if (!feature) {
    // 先创建车辆数据对象，确保在创建feature前就有类型信息
    vehicles.value[object_id] = {
      id: object_id,
      type: effectiveTypeRaw || rawType,
      position: coordinates,
      heading: validHeading,
      speed: validSpeed,
      isAircraft: isAircraft,
      isUnmannedVehicle: isUnmannedVehicle,
      isSpecialVehicle: isSpecialVehicle,
      hasAircraftRoute: hasAircraftRoute,
      lastHeading: validHeading, // 初始化lastHeading
      lastUpdateTime: Date.now() // 记录最后更新时间
    };

    feature = new Feature({
      geometry: new Point(coordinates),
      name: `${effectiveTypeRaw || rawType} ${object_id}`,
      type: effectiveTypeRaw || rawType,
      speed: validSpeed,
      isAircraft: isAircraft,
      isUnmannedVehicle: isUnmannedVehicle,
      isSpecialVehicle: isSpecialVehicle
    });
    
    feature.setId(object_id);
    
    // 直接根据车辆类型选择正确的图标，不使用默认图标
    let iconStyle;
    let iconSrc;
    
    if (isAircraft) {
      iconSrc = hasAircraftRoute ? aircraftRouteIcon : aircraftIcon;
    } else if (isUnmannedVehicle) {
      iconSrc = carIcon; // 无人车使用noPeopleCar.svg
    } else {
      iconSrc = specialCar; // 其他车辆使用specialCar.svg
    }
    
    iconStyle = new Style({
      image: new Icon({
        src: iconSrc,
        scale: isAircraft ? AIRCRAFT_ICON_SCALE : DEFAULT_VEHICLE_ICON_SCALE,
        anchor: [0.5, 0.5],
        rotation: rotationRad, // 使用计算好的旋转角度
      })
    });
    
    {
      const typeKey = getVehicleTypeKey(vehicles.value[object_id]);
      const category = vehicleCategories.value?.[typeKey];
      const isAircraftType = typeKey === 'AIRCRAFT' || typeKey === 'AIRCRAFT_IN' || typeKey === 'AIRCRAFT_OUT';
      const enabled = isAircraftType ? true : vehicleDisplayStore.isVehicleEnabled(object_id);
      const visible = enabled && !!(category && category.visible);
      feature.setStyle(visible ? iconStyle : new Style({}));
    }
    vehicleSource.addFeature(feature);
    
    // 保存feature引用到车辆数据对象
    vehicles.value[object_id].feature = feature;
    
    // 初始化动画数据
    if (animationSystem.value) {
      animationSystem.value.initVehicleAnimation(object_id, coordinates, heading, speed);
    }
    
    // 创建标签（受左侧类别文本开关控制）
    if (labelSystem.value) {
      updateVehicleLabelIfAllowed(object_id, coordinates, validSpeed);
    }
    
    // 应用当前分类设置到新创建的车辆
    if (vehicleCategories.value) {
      const typeKey = getVehicleTypeKey(vehicles.value[object_id]);
      const category = vehicleCategories.value?.[typeKey];
      if (category && !category.visible && vehicles.value[object_id].feature) {
        vehicles.value[object_id].feature.setStyle(new Style({}));
      }
    }
  } else {
    // 更新动画目标
    if (animationSystem.value) {
      animationSystem.value.updateVehicleAnimationTarget(object_id, coordinates, validHeading, validSpeed);
    }
    
    // 更新车辆数据，包括可能从position_update消息中获取的数据
    const previousVehicleData = { ...vehicles.value[object_id] };
    vehicles.value[object_id] = {
      ...vehicles.value[object_id],
      type: effectiveTypeRaw || rawType || vehicles.value[object_id]?.type,
      position: coordinates,
      heading: validHeading,
      speed: validSpeed,
      isAircraft: isAircraft,
      isUnmannedVehicle: isUnmannedVehicle,
      isSpecialVehicle: isSpecialVehicle,
      hasAircraftRoute: hasAircraftRoute,
      lastUpdateTime: Date.now(), // 记录位置更新时间
      // 更新车辆详情数据（如果在payload中提供）
      ...(vehicleData.carId && { carId: vehicleData.carId }),
      ...(vehicleData.type && { type: vehicleData.type }),
      ...(vehicleData.brand && { brand: vehicleData.brand }),
      ...(vehicleData.organization && { organization: vehicleData.organization }),
      ...(vehicleData.routeStatus && { routeStatus: vehicleData.routeStatus }),
      ...(vehicleData.status && { status: vehicleData.status }),
      ...(vehicleData.chargeStatus && { chargeStatus: vehicleData.chargeStatus }),
      ...(vehicleData.voltage && { voltage: vehicleData.voltage }),
      ...(vehicleData.current && { current: vehicleData.current }),
      ...(vehicleData.soc && { soc: vehicleData.soc }),
      ...(vehicleData.lastTime && { lastTime: vehicleData.lastTime }),
      ...(vehicleData.batteryLevel && { batteryLevel: vehicleData.batteryLevel }),
      ...(vehicleData.location && { location: vehicleData.location }),
      ...(vehicleData.contactPhone && { contactPhone: vehicleData.contactPhone }),
      ...(vehicleData.battery && { battery: vehicleData.battery }),
      ...(vehicleData.runningStatus && { runningStatus: vehicleData.runningStatus })
    };
    
    // 如果车辆详情有更新，则发射事件通知其他组件
    const currentVehicleData = vehicles.value[object_id];
    if (hasVehicleDetailsChanged(previousVehicleData, currentVehicleData)) {
      emit('vehicle-details-updated', currentVehicleData);
    }
    
    // 更新标签位置，确保标签始终跟随图标
    // 但是如果车辆处于超速状态，不在这里更新标签，避免与超速状态标签冲突
    if (labelSystem.value && !vehicles.value[object_id].speedViolation) {
      updateVehicleLabelIfAllowed(object_id, coordinates, validSpeed);
    }
    
    // 更新车辆图标样式，确保旋转角度正确应用，并尊重分类显示状态
    if (feature) {
      // 根据车辆类型选择正确的图标
      let iconSrc;
      const vehicle = vehicles.value[object_id];
      
      if (isAircraft) {
        iconSrc = hasAircraftRoute ? aircraftRouteIcon : aircraftIcon; // 航空器使用aircraft.png
      } else if (
        vehicle &&
        (String(vehicle.type || '').includes('无人') || String(vehicle.type || '').toUpperCase() === 'UNMANNED_VEHICLE' || String(vehicle.type || '').toUpperCase() === 'WUREN')
      ) {
        iconSrc = carIcon; // 无人车使用noPeopleCar.svg
      } else {
        iconSrc = specialCar; // 其他车辆使用specialCar.svg
      }
      
      const typeKey = getVehicleTypeKey(vehicle);
      const category = vehicleCategories.value?.[typeKey];
      const isAircraftType = typeKey === 'AIRCRAFT' || typeKey === 'AIRCRAFT_IN' || typeKey === 'AIRCRAFT_OUT';
      const enabled = isAircraftType ? true : vehicleDisplayStore.isVehicleEnabled(object_id);
      const visible = enabled && !!(category && category.visible);
      feature.setStyle(
        visible
          ? new Style({
              image: new Icon({
                src: iconSrc,
                scale: isAircraft ? AIRCRAFT_ICON_SCALE : DEFAULT_VEHICLE_ICON_SCALE,
                anchor: [0.5, 0.5],
                rotation: rotationRad,
              }),
            })
          : new Style({})
      );
      
      // 更新lastHeading
      vehicles.value[object_id].lastHeading = validHeading;
    }
  }
}

// 检查车辆详情是否有变化
function hasVehicleDetailsChanged(previous, current) {
  // 检查关键详情字段是否有变化
  return (
    previous.carId !== current.carId ||
    previous.type !== current.type ||
    previous.brand !== current.brand ||
    previous.organization !== current.organization ||
    previous.routeStatus !== current.routeStatus ||
    previous.status !== current.status ||
    previous.chargeStatus !== current.chargeStatus ||
    previous.voltage !== current.voltage ||
    previous.current !== current.current ||
    previous.soc !== current.soc ||
    previous.lastTime !== current.lastTime ||
    previous.batteryLevel !== current.batteryLevel ||
    previous.location !== current.location ||
    previous.contactPhone !== current.contactPhone ||
    previous.battery !== current.battery ||
    previous.runningStatus !== current.runningStatus
  );
}

// 连接WebSocket
function connectWebSocket() {
  // 重置WebSocket实例以强制创建新实例
  resetWebSocketInstance();
  
  try {
    // 使用WebSocketService创建连接
    const wsUrl = window.APP_CONFIG?.WS_BASE_URL;
    console.log(`正在连接WebSocket: ${wsUrl}`);
    
    wsService = createWebSocket(wsUrl, {
      reconnectInterval: 3000,
      maxReconnectAttempts: 5
    });
    
    // 注册事件监听
    wsService.on('open', (event) => {
      console.log('WebSocket连接成功!');
      wsConnected.value = true;
      
      // 连接成功后自动订阅消息
      setTimeout(() => {
        sendSubscribe();
      }, 1000); // 延迟1秒发送订阅，确保连接稳定
    });
    
    wsService.on('message', (data) => {
      handleWsMessage(data);
    });
    
    wsService.on('error', (event) => {
      console.error('WebSocket错误:', event);
      wsConnected.value = false;
    });
    
    wsService.on('close', (event) => {
      console.log(`WebSocket连接关闭: ${event.code} - ${event.reason}`);
      wsConnected.value = false;
    });
    
    wsService.on('reconnect_failed', () => {
      console.error('WebSocket重连失败，已达到最大重试次数');
      wsConnected.value = false;
    });
    
  } catch (error) {
    console.error('创建WebSocket连接失败:', error);
  }
}

// 处理WebSocket消息
function handleWsMessage(message) {
  try {
    const data = JSON.parse(message);
    console.log('收到消息:', data);
    
    // 根据消息类型处理
    switch (data.type) {
      case 'connection':
        console.log(`连接确认: ${data.message}`);
        break;
      
      case 'position_update':
        // 处理车辆位置更新
        console.log(`位置更新: ${data.payload?.object_id} (${data.payload?.object_type})`);
        handlePositionUpdate(data.payload);
        break;
      
      case 'collision_warning':
        console.log(`碰撞预警: ${data.payload?.message || data.payload?.object1?.objectName || ''}`);
        handlePathConflictAlert(data.payload);
        break;

      case 'path_conflict_status':
        console.log(`路径冲突计算状态: ${data.payload?.aircraftName || ''} ${data.payload?.vehicleName || ''}`);
        handlePathConflictMessage(data);
        break;

      case 'path_conflict_alert':
        // 处理冲突告警和预警
        console.log(`冲突告警/预警: ${data.payload?.object1?.objectName || data.payload?.messageType}`);
        if (isNewPathConflictPayload(data.payload)) {
          handlePathConflictMessage(data);
        } else {
          handlePathConflictAlert(data.payload);
        }
        break;
      
      case 'rule_violation':
        // 处理规则违规（超速和越界）
        console.log(`规则违规: ${data.payload?.ruleName || data.payload?.violationType}`);
        handleRuleViolation(data.payload);
        break;
      
      case 'pong':
        console.log('收到心跳响应');
        break;
      
      case 'vehicle_command':
        console.log('收到车辆控制指令:', data.payload);
        break;
      
      case 'aircraftRouteUpdate':
        console.log('收到飞机路由更新:', data.data);
        handleAircraftRouteUpdate(data.data);
        break;
        
      case 'intersection_traffic_light_status':
        // 处理路口红绿灯状态更新
        console.log('收到路口红绿灯状态更新:', data.payload);
        handleIntersectionTrafficLightStatus(data.payload);
        break;
        
      case 'vehicle_status_update':
        // 处理车辆状态更新消息
        console.log('收到车辆状态更新:', data.payload);
        handleVehicleStatusUpdate(data.payload);
        break;
      
      case 'trafficLight':
        console.log('收到红绿灯消息:', data.payload);
        handleTrafficLightWsMessage(data.payload);
        break;
      
      case 'trafficlight':
      case 'TrafficLight':
        console.log('收到红绿灯消息(大小写变体):', data.payload);
        handleTrafficLightWsMessage(data.payload);
        break;
        
      case 'FLIGHT_NOTIFICATION':
        // 处理航班进出港通知消息
        console.log('收到航班进出港通知:', data.payload);
        handleFlightNotification(data.payload);
        break;
        
      default:
        // 其他类型的消息可以根据需要处理
        if (data?.payload?.serviceType === 'rsu-traffic-lights') {
          console.log('检测到 rsu-traffic-lights 服务消息，按红绿灯处理:', data.payload);
          handleTrafficLightWsMessage(data.payload);
        } else {
          console.log(`未知消息类型: ${data.type}`, data);
        }
        break;
    }
  } catch (e) {
    console.error('处理WebSocket消息出错:', e, message);
  }
}

// 处理航班进出港通知消息
function handleFlightNotification(payload) {
  if (!payload || !payload.flightNo) {
    console.error('航班进出港通知消息格式错误:', payload);
    return;
  }
  
  // 解构消息中的关键信息
  const { 
    flightNo, 
    flightType, 
    eventType, 
    runway, 
    seat, 
    notificationLevel, 
    eventDescription 
  } = payload;
  
  // 记录航班通知信息
  console.log(`航班通知: ${flightNo} ${eventType} ${flightType}`, {
    runway,
    seat,
    notificationLevel,
    eventDescription
  });
  
  // TODO: 后续根据需求添加具体的处理逻辑
  // 可能包括:
  // 1. 在地图上显示航班相关信息
  // 2. 发送通知到相关组件
  // 3. 更新航班状态数据
  // 4. 触发告警或提示
}

// 处理车辆状态更新消息
function handleVehicleStatusUpdate(payload) {
  if (!payload || !payload.vehicleId) {
    console.error('车辆状态更新消息格式错误:', payload);
    return;
  }
  
  const { vehicleId, statusData } = payload;
  
  // 检查是否存在该车辆
  if (!vehicles.value[vehicleId]) {
    console.warn(`未找到车辆 ${vehicleId}，无法更新状态`);
    return;
  }
  
  // 保存更新前的车辆详情用于比较
  const previousVehicleData = { ...vehicles.value[vehicleId] };
  
  // 更新车辆详细状态信息
  if (statusData) {
    // 车辆基本信息
    if (statusData.vehicleInfo) {
      const vehicleInfo = statusData.vehicleInfo;
      vehicles.value[vehicleId] = {
        ...vehicles.value[vehicleId],
        carId: vehicleInfo.vehicleId || vehicles.value[vehicleId].carId,
        type: vehicleInfo.vehicleType || vehicles.value[vehicleId].type,
        brand: vehicleInfo.brand || vehicles.value[vehicleId].brand,
        organization: vehicleInfo.owningUnit || vehicles.value[vehicleId].organization
      };
    }
    
    // 运行状态
    if (statusData.operationalStatus) {
      const ops = statusData.operationalStatus;
      const operationalMode = ops.operationalMode || vehicles.value[vehicleId].routeStatus;
      const systemHealth = ops.systemHealth;
      let statusText = vehicles.value[vehicleId].status;
      
      // 根据系统健康状态和运行模式确定状态文本
      if (systemHealth === 'HEALTHY') {
        statusText = operationalMode === 'AUTONOMOUS' ? '任务中' : '在线';
      } else if (systemHealth === 'FAULT') {
        statusText = '故障';
      } else if (systemHealth === 'OFFLINE') {
        statusText = '离线';
      }
      
      vehicles.value[vehicleId] = {
        ...vehicles.value[vehicleId],
        routeStatus: operationalMode,
        status: statusText,
        chargeStatus: ops.powerStatus || vehicles.value[vehicleId].chargeStatus
      };
    }
    
    // 运动状态
    if (statusData.motionStatus) {
      const motion = statusData.motionStatus;
      if (motion.velocity) {
        const parsedSpeed = Number(motion.velocity.speed);
        const lastSpeed = vehicles.value[vehicleId]?.speed || 0;
        const validSpeed = (Number.isFinite(parsedSpeed) && parsedSpeed >= 0) ? parsedSpeed : lastSpeed;
        vehicles.value[vehicleId] = {
          ...vehicles.value[vehicleId],
          speed: validSpeed,
          lastUpdateTime: Date.now()
        };
      }
      
      // 更新位置信息用于显示
      if (motion.position) {
        const { latitude, longitude } = motion.position;
        vehicles.value[vehicleId] = {
          ...vehicles.value[vehicleId],
          currentLocation: `(${latitude.toFixed(6)}, ${longitude.toFixed(6)})`
        };
      }
    }
    
    // 电池状态
    if (statusData.batteryStatus?.mainBattery) {
      const battery = statusData.batteryStatus.mainBattery;
      vehicles.value[vehicleId] = {
        ...vehicles.value[vehicleId],
        soc: battery.chargeLevel !== undefined ? `${battery.chargeLevel}%` : vehicles.value[vehicleId].soc,
        voltage: battery.voltage !== undefined ? `${battery.voltage}V` : vehicles.value[vehicleId].voltage,
        current: battery.current !== undefined ? `${battery.current}A` : vehicles.value[vehicleId].current,
        battery: battery.chargeLevel !== undefined ? `${battery.chargeLevel}%` : vehicles.value[vehicleId].battery
      };
    }
    
    // 通信状态
    if (statusData.communicationStatus) {
      const comm = statusData.communicationStatus;
      vehicles.value[vehicleId] = {
        ...vehicles.value[vehicleId],
        lastTime: comm.lastUpdateTime ? new Date(comm.lastUpdateTime).toLocaleString() : 
                  new Date().toLocaleString() // 使用当前时间作为最后更新时间
      };
    }
    
    // 任务上下文信息
    if (statusData.missionContext?.currentMission) {
      const mission = statusData.missionContext.currentMission;
      vehicles.value[vehicleId] = {
        ...vehicles.value[vehicleId],
        // 任务开始时间 - 从时间戳转换为可读格式
        startTime: mission.startTime ? 
          new Date(mission.startTime).toLocaleString('zh-CN', {
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit'
          }).replace(/\//g, '-').replace(/,/, '') : 
          vehicles.value[vehicleId].startTime,
        // 总里程 - 从米转换为公里
        totalDistance: mission.totalMileage !== undefined ? 
          `${(mission.totalMileage / 1000).toFixed(1)}km` : 
          vehicles.value[vehicleId].totalDistance,
        // 任务进度
        progress: mission.progress !== undefined ? 
          `${mission.progress.toFixed(1)}%` : 
          vehicles.value[vehicleId].progress,
        // 任务ID和类型
        missionId: mission.missionId || vehicles.value[vehicleId].missionId,
        missionType: mission.missionType || vehicles.value[vehicleId].missionType
      };
    }
  }
  
  // 如果当前正在显示该车辆的详情弹窗，实时更新弹窗数据
  if (vehicleDetailVisible.value && vehicleDetail.value.id === vehicleId) {
    const updatedVehicle = vehicles.value[vehicleId];
    vehicleDetail.value = {
      ...vehicleDetail.value,
      id: vehicleId,
      type: updatedVehicle.type || vehicleDetail.value.type,
      status: updatedVehicle.status || vehicleDetail.value.status,
      startTime: updatedVehicle.startTime || vehicleDetail.value.startTime,
      currentLocation: updatedVehicle.currentLocation || vehicleDetail.value.currentLocation,
      totalDistance: updatedVehicle.totalDistance || vehicleDetail.value.totalDistance,
      battery: updatedVehicle.battery || vehicleDetail.value.battery,
      manager: updatedVehicle.manager || updatedVehicle.location || vehicleDetail.value.manager,
      phone: updatedVehicle.phone || updatedVehicle.contactPhone || vehicleDetail.value.phone
    };
  }
  
  // 如果车辆详情有更新，则发射事件通知其他组件
  const currentVehicleData = vehicles.value[vehicleId];
  if (hasVehicleDetailsChanged(previousVehicleData, currentVehicleData)) {
    emit('vehicle-details-updated', currentVehicleData);
  }
}

// 处理路口红绿灯状态更新
function handleIntersectionTrafficLightStatus(payload) {
  // 检查是否在父组件中存在更新红绿灯图层的方法
  if (window.updateTrafficLightStatus) {
    window.updateTrafficLightStatus(payload);
  }
}

function handleTrafficLightWsMessage(payload) {
  const sd = payload && payload.serviceData ? payload.serviceData : payload;
  const phases = Array.isArray(sd && sd.phases) ? sd.phases : [];
  let status = 'unknown';
  if (phases.length > 0) {
    const colors = phases.map(p => Number(p.phaseColor));
    if (colors.includes(3)) status = 'red';
    else if (colors.includes(4)) status = 'yellow';
    else if (colors.includes(2)) status = 'yellow';
    else if (colors.includes(1)) status = 'green';
    else status = 'unknown';
  } else {
    const s = Number((sd && sd.trafficLightsStatus) ?? payload.trafficLightsStatus);
    if (s === 3) status = 'red';
    else if (s === 4) status = 'yellow';
    else if (s === 2) status = 'yellow';
    else if (s === 1) status = 'green';
  }
  if (window.updateTrafficLightStatus) {
    window.updateTrafficLightStatus({ status });
  }
}

// 处理位置更新消息
function handlePositionUpdate(payload) {
  if (!payload || !payload.object_id) {
    console.error('位置更新消息格式错误:', payload);
    return;
  }
  
  // 清除车辆的告警状态（如果需要）
  clearVehicleAlertStatus(payload);
  
  // 更新车辆位置
  updateVehiclePosition(payload);
}

// 处理飞机路由更新消息
function handleAircraftRouteUpdate(payload) {
  if (!payload || !payload.flightNo) {
    console.error('飞机路由更新消息格式错误:', payload);
    return;
  }

  const { flightNo, routeType, routeStatus, routeGeometry, mergeSuccess, routeGeoJson } = payload;

  if (mergeSuccess === false) {
    const geoJsonObject = parseGeoJsonLike(routeGeoJson);
    if (!geoJsonObject) {
      console.error('飞机路由更新消息缺少可用 routeGeoJson:', payload);
      return;
    }
    updateAircraftRouteFromGeoJson(flightNo, geoJsonObject, routeType, routeStatus, payload.routeCodes || payload.codes);
    return;
  }

  if (!routeGeometry) {
    console.error('飞机路由更新消息缺少 routeGeometry:', payload);
    return;
  }

  const geoJsonObject = parseGeoJsonLike(routeGeometry);
  if (geoJsonObject) {
    updateAircraftRouteFromGeoJson(flightNo, geoJsonObject, routeType, routeStatus, payload.routeCodes || payload.codes);
    return;
  }

  const coordinates = parseLineStringGeometry(routeGeometry);
  if (!coordinates || coordinates.length === 0) {
    console.error('解析routeGeometry失败:', routeGeometry);
    return;
  }

  updateAircraftRoute(flightNo, coordinates, routeType, routeStatus);
}

function parseGeoJsonLike(value) {
  if (!value) return null
  if (typeof value === 'object') {
    const t = String(value?.type || '')
    if (t === 'Feature' || t === 'FeatureCollection' || t === 'GeometryCollection') return value
    return null
  }
  if (typeof value !== 'string') return null
  const s = value.trim()
  if (!s || (s[0] !== '{' && s[0] !== '[')) return null
  try {
    const obj = JSON.parse(s)
    const t = String(obj?.type || '')
    if (t === 'Feature' || t === 'FeatureCollection' || t === 'GeometryCollection') return obj
    return null
  } catch (e) {
    return null
  }
}

function removeAircraftRouteFeatures(flightNo) {
  if (!aircraftRouteSource) return
  const all = aircraftRouteSource.getFeatures()
  all.forEach((f) => {
    const id = String(f?.getId?.() || '')
    const fFlight = f?.get?.('flightNo')
    if (fFlight === flightNo || id === flightNo || (id && id.startsWith(`${flightNo}-`))) {
      aircraftRouteSource.removeFeature(f)
    }
  })
}

// 空间拓扑极大极小算法，根据路段顺序（codesString）在 Feature 集合中找出最终起点和终点
function calculateStartAndEndPoints(olFeatures, codesString) {
  if (!Array.isArray(olFeatures) || olFeatures.length === 0 || !codesString) return null;
  
  // 分割 codesString，如 "J4,E,F1,149" -> ['J4', 'E', 'F1', '149']
  const codesArray = codesString.split(',')
    .map(c => String(c || '').trim())
    .filter(Boolean);
  
  if (codesArray.length === 0) return null;

  const normalizeRouteCode = (value) => {
    if (typeof value === 'string') return value.trim();
    if (typeof value === 'number') return String(value);
    return '';
  };

  const getRouteCodeFromFeature = (f) => {
    return normalizeRouteCode(f?.get?.('code')) || normalizeRouteCode(f?.getProperties?.()?.code);
  };

  const getAllLineEndpoints = (feats) => {
    const ends = [];
    feats.forEach((f) => {
      const geom = f?.getGeometry?.();
      const type = geom?.getType?.();
      const coords = geom?.getCoordinates?.();
      if (!Array.isArray(coords)) return;
      if (type === 'MultiLineString') {
        coords.forEach((line) => {
          if (Array.isArray(line) && line.length >= 2) {
            ends.push(line[0]);
            ends.push(line[line.length - 1]);
          }
        });
      } else if (type === 'LineString') {
        if (coords.length >= 2) {
          ends.push(coords[0]);
          ends.push(coords[coords.length - 1]);
        }
      }
    });
    return ends;
  };

  const pickFarthestTwoPoints = (candidates) => {
    if (!Array.isArray(candidates) || candidates.length < 2) return null;
    let maxDist2 = -1;
    let startPoint = candidates[0];
    let endPoint = candidates[candidates.length - 1];
    for (let i = 0; i < candidates.length; i++) {
      const a = candidates[i];
      if (!Array.isArray(a) || a.length < 2) continue;
      const ax = Number(a[0]);
      const ay = Number(a[1]);
      if (!Number.isFinite(ax) || !Number.isFinite(ay)) continue;
      for (let j = i + 1; j < candidates.length; j++) {
        const b = candidates[j];
        if (!Array.isArray(b) || b.length < 2) continue;
        const bx = Number(b[0]);
        const by = Number(b[1]);
        if (!Number.isFinite(bx) || !Number.isFinite(by)) continue;
        const dx = ax - bx;
        const dy = ay - by;
        const dist2 = dx * dx + dy * dy;
        if (dist2 > maxDist2) {
          maxDist2 = dist2;
          startPoint = a;
          endPoint = b;
        }
      }
    }
    if (maxDist2 < 0) return null;
    return { startPoint, endPoint };
  };

  const pickFarthestPointFrom = (candidates, anchorPoint) => {
    if (!Array.isArray(candidates) || candidates.length === 0) return null;
    if (!Array.isArray(anchorPoint) || anchorPoint.length < 2) return null;
    const ax = Number(anchorPoint[0]);
    const ay = Number(anchorPoint[1]);
    if (!Number.isFinite(ax) || !Number.isFinite(ay)) return null;
    let best = null;
    let bestD2 = -1;
    candidates.forEach((p) => {
      if (!Array.isArray(p) || p.length < 2) return;
      const px = Number(p[0]);
      const py = Number(p[1]);
      if (!Number.isFinite(px) || !Number.isFinite(py)) return;
      const dx = px - ax;
      const dy = py - ay;
      const d2 = dx * dx + dy * dy;
      if (d2 > bestD2) {
        bestD2 = d2;
        best = p;
      }
    });
    return best;
  };

  const pickMaxMinCandidate = (candidates, guidePoints) => {
    if (!Array.isArray(candidates) || candidates.length === 0) return null;
    if (!Array.isArray(guidePoints) || guidePoints.length === 0) return candidates[0];
    let best = candidates[0];
    let maxMinDist = -1;
    candidates.forEach((cp) => {
      if (!Array.isArray(cp) || cp.length < 2) return;
      const cpx = Number(cp[0]);
      const cpy = Number(cp[1]);
      if (!Number.isFinite(cpx) || !Number.isFinite(cpy)) return;
      let minDist2 = Infinity;
      guidePoints.forEach((gp) => {
        if (!Array.isArray(gp) || gp.length < 2) return;
        const gpx = Number(gp[0]);
        const gpy = Number(gp[1]);
        if (!Number.isFinite(gpx) || !Number.isFinite(gpy)) return;
        const dx = cpx - gpx;
        const dy = cpy - gpy;
        const d2 = dx * dx + dy * dy;
        if (d2 < minDist2) minDist2 = d2;
      });
      if (minDist2 > maxMinDist) {
        maxMinDist = minDist2;
        best = cp;
      }
    });
    return best;
  };
  
  // 过滤出起止路段的 Feature 数组
  const startCode = codesArray[0];
  const endCode = codesArray[codesArray.length - 1];
  const allEndpoints = getAllLineEndpoints(olFeatures);
  
  const startFeatures = olFeatures.filter(f => {
    const code = getRouteCodeFromFeature(f);
    return code === startCode;
  });
  
  const endFeatures = olFeatures.filter(f => {
    const code = getRouteCodeFromFeature(f);
    return code === endCode;
  });
  
  // 特殊情况：如果总共只有 1 个 code 段，或者起止是同一个 code 且只有一段
  if (codesArray.length === 1 || startCode === endCode) {
    // 提取所有候选端点，取距离最远的两个点
    const candidates = startFeatures.length > 0 ? getAllLineEndpoints(startFeatures) : allEndpoints;
    return pickFarthestTwoPoints(candidates);
  }
  
  // 正常有多段路段：
  // 起点的相邻段编码即第二个，终点的相邻段编码即倒数第二个
  const nextCode = codesArray[1];
  const prevCode = codesArray[codesArray.length - 2];
  
  const nextFeatures = olFeatures.filter(f => {
    const code = getRouteCodeFromFeature(f);
    return code === nextCode;
  });
  const prevFeatures = olFeatures.filter(f => {
    const code = getRouteCodeFromFeature(f);
    return code === prevCode;
  });
  
  // 收集辅助中转点（所有在 next/prev 线段里的坐标点）
  const getPointsFromOlFeatures = (feats) => {
    let pts = [];
    feats.forEach(f => {
      const geom = f.getGeometry();
      if (geom && typeof geom.getCoordinates === 'function') {
        const coords = geom.getCoordinates();
        if (Array.isArray(coords)) {
          const type = geom.getType?.();
          if (type === 'MultiLineString') {
            coords.forEach(line => {
              if (Array.isArray(line)) line.forEach(pt => pts.push(pt));
            });
          } else {
            coords.forEach(pt => pts.push(pt));
          }
        }
      }
    });
    return pts;
  };
  
  const nextPoints = getPointsFromOlFeatures(nextFeatures);
  const prevPoints = getPointsFromOlFeatures(prevFeatures);
  
  // 收集起终段要素的候选端点
  const getEndsFromOlFeatures = (feats) => {
    let ends = [];
    feats.forEach(f => {
      const geom = f.getGeometry();
      if (geom && typeof geom.getCoordinates === 'function') {
        const coords = geom.getCoordinates();
        if (Array.isArray(coords) && coords.length >= 2) {
          const type = geom.getType?.();
          if (type === 'MultiLineString') {
            coords.forEach(line => {
              if (Array.isArray(line) && line.length >= 2) {
                ends.push(line[0]);
                ends.push(line[line.length - 1]);
              }
            });
          } else {
            ends.push(coords[0]);
            ends.push(coords[coords.length - 1]);
          }
        }
      }
    });
    return ends;
  };
  
  const startCandidates = getEndsFromOlFeatures(startFeatures);
  const endCandidates = getEndsFromOlFeatures(endFeatures);

  const startMissing = startCandidates.length === 0;
  const endMissing = endCandidates.length === 0;
  if (startMissing && endMissing) {
    return pickFarthestTwoPoints(allEndpoints);
  }

  if ((startMissing || endMissing) && (startFeatures.length === 0 || endFeatures.length === 0)) {
    console.warn(`[Topology] 端点不完整：start=${startCode}(${startCandidates.length}) end=${endCode}(${endCandidates.length})`);
  }

  let startPoint = null;
  let endPoint = null;

  if (!startMissing) {
    startPoint = (startFeatures.length > 0)
      ? pickMaxMinCandidate(startCandidates, nextPoints)
      : startCandidates[0];
  }

  if (!endMissing) {
    endPoint = (endFeatures.length > 0)
      ? pickMaxMinCandidate(endCandidates, prevPoints)
      : endCandidates[0];
  }

  if (!startPoint && endPoint) {
    startPoint = pickFarthestPointFrom(allEndpoints, endPoint) || allEndpoints?.[0] || endPoint;
  }

  if (!endPoint && startPoint) {
    endPoint = pickFarthestPointFrom(allEndpoints, startPoint) || allEndpoints?.[allEndpoints.length - 1] || startPoint;
  }

  if (!startPoint || !endPoint) {
    return pickFarthestTwoPoints(allEndpoints);
  }

  return { startPoint, endPoint };
}

function updateAircraftRouteFromGeoJson(flightNo, geoJsonObject, routeType, routeStatus, routeCodesString) {
  if (!aircraftRouteSource || !props.map) return
  flightNo = String(flightNo || '').trim().toUpperCase();

  if (aircraftRouteTimers[flightNo]) {
    clearTimeout(aircraftRouteTimers[flightNo])
    delete aircraftRouteTimers[flightNo]
  }

  removeAircraftRouteFeatures(flightNo)

  const viewProj = props.map.getView().getProjection()
  const geojson = new GeoJSON()
  const rawFeatures = geojson.readFeatures(geoJsonObject, {
    dataProjection: viewProj,
    featureProjection: viewProj
  })

  let dataProj = viewProj
  const firstLine = rawFeatures.find((f) => f?.getGeometry?.()?.getType?.() === 'LineString')
  const firstCoords = firstLine?.getGeometry?.()?.getCoordinates?.()
  const firstCoord = Array.isArray(firstCoords) && firstCoords.length ? firstCoords[0] : null
  if (Array.isArray(firstCoord) && firstCoord.length === 2) {
    const x = Number(firstCoord[0])
    const y = Number(firstCoord[1])
    if (Number.isFinite(x) && Number.isFinite(y)) {
      const looksLikeLngLat = Math.abs(x) <= 180 && Math.abs(y) <= 90
      dataProj = looksLikeLngLat ? 'EPSG:4326' : 'EPSG:4528'
    }
  }

  const features = dataProj === viewProj
    ? rawFeatures
    : geojson.readFeatures(geoJsonObject, {
        dataProjection: dataProj,
        featureProjection: viewProj
      })

  let firstLineCoords = null
  let routeCoordsForStore = null
  features.forEach((f, idx) => {
    const existingId = f.getId()
    if (existingId === undefined || existingId === null || String(existingId).trim() === '') {
      f.setId(`${flightNo}-geo-${idx}`)
    } else {
      f.setId(`${flightNo}-geo-${existingId}`)
    }
    f.set('flightNo', flightNo)
    if (routeType) f.set('routeType', routeType)
    if (routeStatus) f.set('routeStatus', routeStatus)
    
    const geom = f.getGeometry()
    const geomType = geom?.getType?.()
    if (geomType === 'LineString' || geomType === 'MultiLineString') {
      f.setStyle(getRouteStyle(routeType, routeStatus))
      if (geomType === 'LineString' && !firstLineCoords) {
        firstLineCoords = geom.getCoordinates()
      }
      if (!routeCoordsForStore) {
        const coords = geom?.getCoordinates?.()
        if (geomType === 'LineString') {
          if (Array.isArray(coords) && coords.length >= 2) routeCoordsForStore = coords
        } else if (geomType === 'MultiLineString') {
          if (Array.isArray(coords)) {
            const flat = []
            coords.forEach((line) => {
              if (Array.isArray(line)) {
                line.forEach((pt) => {
                  flat.push(pt)
                })
              }
            })
            if (flat.length >= 2) routeCoordsForStore = flat
          }
        }
      }
    }
    aircraftRouteSource.addFeature(f)
  })

  const finalRouteCoords = routeCoordsForStore || firstLineCoords
  if (finalRouteCoords && finalRouteCoords.length) {
    aircraftRoutes.value[flightNo] = {
      flightNo,
      routeType,
      routeStatus,
      coordinates: finalRouteCoords,
      feature: null,
      lastUpdateTime: Date.now()
    }
    aircraftRouteProgress[flightNo] = { maxIndexSeen: 0, endHitCount: 0, lastIndex: 0 }
    
    let endpoints = null
    if (routeCodesString) {
      endpoints = calculateStartAndEndPoints(features, routeCodesString);
    }
    if (!endpoints && Array.isArray(finalRouteCoords) && finalRouteCoords.length >= 2) {
      endpoints = { startPoint: finalRouteCoords[0], endPoint: finalRouteCoords[finalRouteCoords.length - 1] }
    }
    if (endpoints) {
      const { startPoint, endPoint } = endpoints;
      if (startPoint) {
        createRoutePointMarker(flightNo, 'start', startPoint, routeType);
      }
      if (endPoint) {
        createRoutePointMarker(flightNo, 'end', endPoint, routeType);
      }
    }
  }

  if (vehicles.value[flightNo]) {
    const currentVehicle = vehicles.value[flightNo]
    const isAircraftVehicle = currentVehicle.isAircraft || currentVehicle.type?.toUpperCase() === 'AIRCRAFT'
    if (isAircraftVehicle) {
      vehicles.value[flightNo] = { ...currentVehicle, hasAircraftRoute: true }
      const v = vehicles.value[flightNo]
      if (v.feature) {
        if (styleManager.value) {
          setVehicleStyleRespectVisibility(flightNo, styleManager.value.getVehicleStyle(flightNo, v.speed, v.heading))
        } else {
          setVehicleStyleRespectVisibility(flightNo, getDefaultVehicleStyle(v))
        }
      }
    }
  }

  // 统一由清理定时器处理，此处不再设置独立的 5 分钟超时移除
  // aircraftRouteTimers[flightNo] = setTimeout(() => {
  //   removeAircraftRoute(flightNo)
  // }, 300000)
}

// 解析LINESTRING格式的字符串，提取坐标点
function parseLineStringGeometry(lineString) {
  if (!lineString || typeof lineString !== 'string') return [];

  const trimmed = lineString.trim();
  const normalized = trimmed.replace(/^SRID=\d+;/i, '');
  if (!/^LINESTRING/i.test(normalized)) return [];

  const coordsString = normalized
    .replace(/^LINESTRING(?:\s+ZM|\s+Z|\s+M)?\s*\(/i, '')
    .replace(/\)\s*$/g, '');

  if (!coordsString.trim()) return [];

  const coordPairs = coordsString
    .split(',')
    .map((pair) => pair.trim())
    .filter(Boolean);

  return coordPairs
    .map((pair) => {
      const parts = pair.split(/\s+/).filter(Boolean);
      if (parts.length < 2) return null;
      const x = Number(parts[0]);
      const y = Number(parts[1]);
      if (!Number.isFinite(x) || !Number.isFinite(y)) return null;
      return [x, y];
    })
    .filter(Boolean);
}

function computeClosestRouteIndex(routeCoords, positionCoord, startIndexHint = 0) {
  if (!Array.isArray(routeCoords) || routeCoords.length === 0) return 0;
  if (!positionCoord || positionCoord.length !== 2) return 0;
  const startIndex = Math.max(0, Math.min(Math.floor(startIndexHint || 0), routeCoords.length - 1));
  let bestIndex = startIndex;
  let bestD2 = Infinity;
  for (let i = startIndex; i < routeCoords.length; i++) {
    const dx = routeCoords[i][0] - positionCoord[0];
    const dy = routeCoords[i][1] - positionCoord[1];
    const d2 = dx * dx + dy * dy;
    if (d2 < bestD2) {
      bestD2 = d2;
      bestIndex = i;
    }
  }
  return bestIndex;
}

function tryAutoRemoveAircraftRouteByPosition(flightNo, positionCoord) {
  flightNo = String(flightNo || '').trim().toUpperCase();
  const route = aircraftRoutes.value?.[flightNo];
  if (!route || !Array.isArray(route.coordinates) || route.coordinates.length < 2) return;
  const end = route.coordinates[route.coordinates.length - 1];
  const dx = end[0] - positionCoord[0];
  const dy = end[1] - positionCoord[1];
  const distToEnd = Math.sqrt(dx * dx + dy * dy);

  const progress = aircraftRouteProgress[flightNo] || { maxIndexSeen: 0, endHitCount: 0, lastIndex: 0 };
  const nearestIndex = computeClosestRouteIndex(route.coordinates, positionCoord, Math.max(0, progress.maxIndexSeen - 20));

  progress.lastIndex = nearestIndex;
  progress.maxIndexSeen = Math.max(progress.maxIndexSeen, nearestIndex);

  const endIndexThreshold = Math.max(0, route.coordinates.length - 2);
  const reachedRouteEnd = progress.maxIndexSeen >= endIndexThreshold;
  const movedBeyondStart = progress.maxIndexSeen >= Math.min(3, endIndexThreshold);
  const endDistanceThreshold = 20;

  if (reachedRouteEnd && movedBeyondStart && distToEnd <= endDistanceThreshold) {
    progress.endHitCount = (progress.endHitCount || 0) + 1;
  } else {
    progress.endHitCount = 0;
  }

  aircraftRouteProgress[flightNo] = progress;

  if (progress.endHitCount >= 3) {
    removeAircraftRoute(flightNo);
  }
}

// 更新或创建飞机路线
function updateAircraftRoute(flightNo, coordinates, routeType, routeStatus) {
  if (!aircraftRouteSource || !props.map) return;
  flightNo = String(flightNo || '').trim().toUpperCase();
  console.log('原始航线坐标:', coordinates);
  
  // 清除该航班之前的定时器（如果存在）
  if (aircraftRouteTimers[flightNo]) {
    clearTimeout(aircraftRouteTimers[flightNo]);
    delete aircraftRouteTimers[flightNo];
  }
  
  const isLngLat4326 = Array.isArray(coordinates) && coordinates.length > 0 && coordinates.every(coord => {
    if (!Array.isArray(coord) || coord.length !== 2) return false
    const x = Number(coord[0])
    const y = Number(coord[1])
    return Number.isFinite(x) && Number.isFinite(y) && Math.abs(x) <= 180 && Math.abs(y) <= 90
  })
  const sourceProjection = isLngLat4326 ? 'EPSG:4326' : 'EPSG:4528'

  const projectedCoords = coordinates.map(coord =>
    transform(coord, sourceProjection, props.map.getView().getProjection())
  )
  console.log('处理后的坐标:', projectedCoords);
  
  // 获取起点和终点坐标
  const startPoint = projectedCoords[0];
  const endPoint = projectedCoords[projectedCoords.length - 1];
  
  // 检查是否已存在该航班的路线
  let feature = aircraftRouteSource.getFeatureById(flightNo);
  let startFeature = aircraftRouteSource.getFeatureById(`${flightNo}-start`);
  let endFeature = aircraftRouteSource.getFeatureById(`${flightNo}-end`);
  
  if (!feature) {
    // 创建新的LineString几何体
    const lineGeometry = new LineString(projectedCoords);
    
    // 创建新的Feature
    feature = new Feature({
      geometry: lineGeometry,
      name: `Flight ${flightNo} Route`,
      flightNo: flightNo,
      routeType: routeType,
      routeStatus: routeStatus
    });
    
    // 设置ID和样式
    feature.setId(flightNo);
    feature.setStyle(getRouteStyle(routeType, routeStatus));
    
    // 添加到数据源
    aircraftRouteSource.addFeature(feature);
    
    // 创建起点标记
    createRoutePointMarker(flightNo, 'start', startPoint, routeType);
    
    // 创建终点标记
    createRoutePointMarker(flightNo, 'end', endPoint, routeType);
    
    // 存储路线信息
    aircraftRoutes.value[flightNo] = {
      flightNo: flightNo,
      routeType: routeType,
      routeStatus: routeStatus,
      coordinates: projectedCoords,
      feature: feature,
      lastUpdateTime: Date.now() // 记录最后更新时间
    };
    aircraftRouteProgress[flightNo] = { maxIndexSeen: 0, endHitCount: 0, lastIndex: 0 };
  } else {
    // 更新现有Feature的几何体和属性
    feature.getGeometry().setCoordinates(projectedCoords);
    feature.set('routeType', routeType);
    feature.set('routeStatus', routeStatus);
    
    // 更新样式
    feature.setStyle(getRouteStyle(routeType, routeStatus));
    
    // 更新起点标记位置
    updateRoutePointMarker(flightNo, 'start', startPoint);
    
    // 更新终点标记位置
    updateRoutePointMarker(flightNo, 'end', endPoint);
    
    // 更新存储的路线信息
    aircraftRoutes.value[flightNo] = {
      ...aircraftRoutes.value[flightNo],
      routeType: routeType,
      routeStatus: routeStatus,
      coordinates: projectedCoords,
      lastUpdateTime: Date.now() // 更新最后更新时间
    };

    if (aircraftRouteProgress[flightNo]) {
      const p = aircraftRouteProgress[flightNo];
      p.maxIndexSeen = Math.min(p.maxIndexSeen || 0, Math.max(0, projectedCoords.length - 1));
      p.lastIndex = Math.min(p.lastIndex || 0, Math.max(0, projectedCoords.length - 1));
      p.endHitCount = 0;
    }
  }

  if (vehicles.value[flightNo]) {
    const currentVehicle = vehicles.value[flightNo];
    const isAircraftVehicle = currentVehicle.isAircraft || currentVehicle.type?.toUpperCase() === 'AIRCRAFT';
    if (isAircraftVehicle) {
      vehicles.value[flightNo] = {
        ...currentVehicle,
        hasAircraftRoute: true
      };
      const v = vehicles.value[flightNo];
      if (v.feature) {
        if (styleManager.value) {
          setVehicleStyleRespectVisibility(
            flightNo,
            styleManager.value.getVehicleStyle(flightNo, v.speed, v.heading)
          );
        } else {
          setVehicleStyleRespectVisibility(flightNo, getDefaultVehicleStyle(v));
        }
      }
    }
  }
  
  // 统一由清理定时器处理，此处不再设置独立的 5 分钟超时移除
  // aircraftRouteTimers[flightNo] = setTimeout(() => {
  //   console.log(`航班 ${flightNo} 路线超时，5分钟内未收到更新消息，移除路线`);
  //   removeAircraftRoute(flightNo);
  // }, 300000); // 5分钟后移除
  
  console.log(`航班 ${flightNo} 路线已更新，将在收到下次更新消息时刷新显示时间`);
}

// 根据路线类型和状态获取样式
function getRouteStyle(routeType, routeStatus) {
  let color = '#3388ff'; // 默认蓝色
  let width = 3;
  let lineDash = undefined;
  
  // 根据路线类型设置颜色
  const type = String(routeType || '').toUpperCase();
  if (type === 'IN' || type.includes('进')) {
    color = '#292C38'; // 深蓝色表示滑入/进港
  } else if (type === 'OUT' || type.includes('出')) {
    color = '#27AE60'; // 绿色表示滑出/出港
  } else if (type === 'TEST') {
    color = '#FF8C00'; // 测试路由使用橙色
  }
  
  // // 根据路线状态设置线型
  // if (routeStatus === 'PLANNED') {
  //   lineDash = [4, 8]; // 计划中的路线使用虚线
  //   width = 2;
  // } else if (routeStatus === 'ACTIVE') {
  //   width = 4; // 活动中的路线使用粗线
  // } else if (routeStatus === 'COMPLETE') {
  //   width = 2; // 完成的路线使用细线
  //   color = color + '80'; // 添加透明度
  // }
  
  return new Style({
    stroke: new Stroke({
      color: color,
      width: width,
      lineDash: lineDash
    })
  });
}

// 获取点样式（起点或终点）
function getPointStyle(pointType, routeType, flightNo) {
  // 根据路线类型选择颜色
  let color = '#3388ff'; // 默认蓝色
  const type = String(routeType || '').toUpperCase();
  if (type === 'IN' || type.includes('进')) {
    color = '#292C38'; // 深蓝色表示滑入/进港
  } else if (type === 'OUT' || type.includes('出')) {
    color = '#27AE60'; // 绿色表示滑出/出港
  } else if (type === 'TEST') {
    color = '#FF8C00'; // 测试路由点使用橙色
  }
  
  // 创建圆点样式
  const circleStyle = new Style({
    image: new Circle({
      radius: 6,
      fill: new Fill({
        color: color
      }),
      stroke: new Stroke({
        color: '#ffffff',
        width: 2
      })
    }),
    // 添加文本标签
    text: new Text({
      text: pointType === 'start' ? '起点' : '终点',
      font: 'bold 12px Arial',
      fill: new Fill({
        color: '#ffffff'
      }),
      stroke: new Stroke({
        color: '#000000',
        width: 3
      }),
      offsetX: 0,
      offsetY: pointType === 'start' ? -15 : -15, // 文字位置偏移
      textAlign: 'center',
      textBaseline: 'bottom'
    }),
    zIndex: 10 // 确保点标记显示在线的上方
  });
  
  return circleStyle;
}

// 创建路线点标记（起点或终点）
function createRoutePointMarker(flightNo, pointType, coordinates, routeType) {
  // 创建点几何体
  const pointGeometry = new Point(coordinates);
  
  // 创建Feature
  const pointFeature = new Feature({
    geometry: pointGeometry,
    name: `${flightNo} ${pointType === 'start' ? '起点' : '终点'}`,
    flightNo: flightNo,
    pointType: pointType
  });
  
  // 设置ID
  pointFeature.setId(`${flightNo}-${pointType}`);
  
  // 设置样式
  pointFeature.setStyle(getPointStyle(pointType, routeType, flightNo));
  
  // 添加到数据源
  aircraftRouteSource.addFeature(pointFeature);
  
  return pointFeature;
}

// 更新路线点标记位置
function updateRoutePointMarker(flightNo, pointType, coordinates) {
  const pointFeature = aircraftRouteSource.getFeatureById(`${flightNo}-${pointType}`);
  
  if (pointFeature) {
    // 更新几何体
    pointFeature.getGeometry().setCoordinates(coordinates);
  } else {
    // 如果不存在，创建新的点标记
    const routeType = aircraftRoutes.value[flightNo]?.routeType || 'UNKNOWN';
    createRoutePointMarker(flightNo, pointType, coordinates, routeType);
  }
}

// 移除飞机路线
function removeAircraftRoute(flightNo) {
  if (!aircraftRouteSource) return;
  flightNo = String(flightNo || '').trim().toUpperCase();
  
  // 清除该航班的定时器（如果存在）
  if (aircraftRouteTimers[flightNo]) {
    clearTimeout(aircraftRouteTimers[flightNo]);
    delete aircraftRouteTimers[flightNo];
    console.log(`已清除航班 ${flightNo} 的路线定时器`);
  }

  removeAircraftRouteFeatures(flightNo)
  
  // 移除路线Feature
  const feature = aircraftRouteSource.getFeatureById(flightNo);
  if (feature) {
    aircraftRouteSource.removeFeature(feature);
  }
  
  // 移除起点Feature
  const startFeature = aircraftRouteSource.getFeatureById(`${flightNo}-start`);
  if (startFeature) {
    aircraftRouteSource.removeFeature(startFeature);
  }
  
  // 移除终点Feature
  const endFeature = aircraftRouteSource.getFeatureById(`${flightNo}-end`);
  if (endFeature) {
    aircraftRouteSource.removeFeature(endFeature);
  }
  
  // 从存储中移除
  if (aircraftRoutes.value[flightNo]) {
    delete aircraftRoutes.value[flightNo];
  }
  if (aircraftRouteProgress[flightNo]) {
    delete aircraftRouteProgress[flightNo];
  }

  if (vehicles.value[flightNo]) {
    const currentVehicle = vehicles.value[flightNo];
    const isAircraftVehicle = currentVehicle.isAircraft || currentVehicle.type?.toUpperCase() === 'AIRCRAFT';
    if (isAircraftVehicle) {
      vehicles.value[flightNo] = {
        ...currentVehicle,
        hasAircraftRoute: false
      };
      const v = vehicles.value[flightNo];
      if (v.feature) {
        if (styleManager.value) {
          setVehicleStyleRespectVisibility(
            flightNo,
            styleManager.value.getVehicleStyle(flightNo, v.speed, v.heading)
          );
        } else {
          setVehicleStyleRespectVisibility(flightNo, getDefaultVehicleStyle(v));
        }
      }
    }
  }
  
  console.log(`航班 ${flightNo} 的路线已完全移除`);
}

function handlePathConflictMessage(message) {
  if (!pathConflictDisplayEnabled.value) {
    clearPathConflictDisplay();
    return;
  }

  const conflict = normalizePathConflictMessage(message);
  if (!conflict) return;

  if (conflict.kind === 'resume') {
    const matchedConflicts = getPathConflictsToClear(conflict.key || conflict.vehicleName);
    clearPathConflict(conflict.key || conflict.vehicleName);
    const statusIds = new Set([conflict.vehicleName, conflict.aircraftName]);
    matchedConflicts.forEach(item => {
      statusIds.add(item.vehicleName);
      statusIds.add(item.aircraftName);
    });
    statusIds.forEach(id => {
      if (id) clearConflictStatus(id);
    });
    if (!currentPathConflict.value) clearAlertMessage();
    return;
  }

  const previous = pathConflicts.value?.[conflict.key];
  upsertPathConflict(conflict);

  if (conflict.kind === 'alert') {
    const alarmLevel = conflict.level === 'WARNING' ? 'medium' : 'high';
    if (!previous || previous.kind !== 'alert' || previous.level !== conflict.level) {
      addAlarm({
        carId: conflict.vehicleName || '未知车辆',
        carType: vehicles.value[conflict.vehicleName]?.type || '路径冲突',
        time: `${formatTimeRange(new Date())} ${conflict.aircraftName || '航空器'}与${conflict.vehicleName || '车辆'}`,
        description: conflict.title,
        level: alarmLevel,
        type: 'car',
        rawData: conflict.rawData
      });
    }

    showAlert(`${conflict.title}：${conflict.aircraftName || '航空器'} 与 ${conflict.vehicleName || '车辆'}`, conflict.level === 'WARNING' ? 'warning' : 'alarm', 0);
    markConflictStatus(conflict.vehicleName, conflict.level === 'WARNING' ? 'warning' : 'alarm', conflict.title);
    markConflictStatus(conflict.aircraftName, conflict.level === 'WARNING' ? 'warning' : 'alarm', conflict.title);
  }
}

function upsertPathConflict(conflict) {
  const key = conflict.key || `${Date.now()}`;
  const next = {
    ...(pathConflicts.value[key] || {}),
    ...conflict,
    key,
    updatedAt: Date.now()
  };
  pathConflicts.value = {
    ...pathConflicts.value,
    [key]: next
  };

  renderPathConflictFeature(next);
}

function renderPathConflictFeature(conflict) {
  if (!pathConflictSource || !conflict.conflictPoint) return;

  const latitude = Number(conflict.conflictPoint.latitude);
  const longitude = Number(conflict.conflictPoint.longitude);
  if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return;

  const coordinates = transform([longitude, latitude], 'EPSG:4326', 'EPSG:4528');
  let feature = pathConflictSource.getFeatureById(conflict.key);
  if (!feature) {
    feature = new Feature({
      geometry: new Point(coordinates),
      conflictType: 'path_conflict'
    });
    feature.setId(conflict.key);
    pathConflictSource.addFeature(feature);
  } else {
    feature.getGeometry().setCoordinates(coordinates);
  }

  feature.setStyle(getPathConflictStyle(conflict));
}

function clearPathConflict(key) {
  const next = { ...(pathConflicts.value || {}) };
  const keys = Object.keys(next).filter(itemKey => {
    const item = next[itemKey];
    return itemKey === key || item.vehicleName === key || item.aircraftName === key;
  });

  keys.forEach(itemKey => {
    if (pathConflictSource) {
      const feature = pathConflictSource.getFeatureById(itemKey);
      if (feature) pathConflictSource.removeFeature(feature);
    }
    delete next[itemKey];
  });

  pathConflicts.value = next;
}

function getPathConflictsToClear(key) {
  return Object.entries(pathConflicts.value || {})
    .filter(([itemKey, item]) => itemKey === key || item.vehicleName === key || item.aircraftName === key)
    .map(([, item]) => item);
}

function clearPathConflictDisplay() {
  pathConflicts.value = {};
  if (pathConflictSource) {
    pathConflictSource.clear();
  }
}

// 处理冲突告警和预警
function handlePathConflictAlert(payload) {
  if (!payload) {
    console.error('冲突告警消息格式错误:', payload);
    return;
  }
  
  console.log('收到冲突告警/预警:', payload);
  
  const object1 = payload.object1 || {};
  const object2 = payload.object2 || {};
  const vehicleId = object1.objectName || '未知车辆';
  const otherVehicleId = object2.objectName || '未知车辆';
  const distance = payload.object2Distance || 0;
  const message = payload.message || `与${otherVehicleId}可能发生冲突`;
  const isAlert = (payload.alertType === 'CONFLICT_ALERT') || (payload.alert === true) || (payload.alertLevel === 'CRITICAL');
  const isWarning = (payload.alertType === 'CONFLICT_WARNING') || (payload.warning === true);
  if (!isAlert && isWarning) {
    console.log('处理冲突预警:', vehicleId, otherVehicleId);
    const warningMessage = `预警：${message}`;
    showAlert(warningMessage, 'warning', 8000);
    
    // 添加到告警列表
    addAlarm({
      carId: vehicleId,
      carType: vehicles.value[vehicleId]?.type || '未知类型',
      time: `${formatTimeRange(new Date())}与${otherVehicleId}发生冲`,
      description: '突预警',
      level: 'medium',
      type: 'car',
      rawData: payload
    });
    
    // 冲突预警默认10秒无新消息自动清除
    markConflictStatus(vehicleId, 'warning', message, 10000);
    markConflictStatus(otherVehicleId, 'warning', message, 10000);
  } else if (isAlert) {
    console.log('处理冲突告警:', vehicleId, otherVehicleId);
    const alertMessage = `⚠️ 告警：${message}`;
    showAlert(alertMessage, 'alarm', 10000);
    
    // 添加到告警列表
    addAlarm({
      carId: vehicleId,
      carType: vehicles.value[vehicleId]?.type || '未知类型',
      time: `${formatTimeRange(new Date())}与${otherVehicleId}发生冲`,
      description: '突告警',
      level: 'high',
      type: 'car',
      rawData: payload
    });
    
    // 冲突告警默认15秒无新消息自动清除
    markConflictStatus(vehicleId, 'alarm', message, 15000);
    markConflictStatus(otherVehicleId, 'alarm', message, 15000);
  } else {
    console.log(`未知的冲突消息类型: ${payload.messageType || payload.alertType}`);
  }
}

// 处理规则违规（超速和越界）
function handleRuleViolation(payload) {
  if (!payload) {
    console.error('规则违规消息格式错误:', payload);
    return;
  }
  
  console.log('收到规则违规:', payload);
  
  const vehicleId = payload.object_id || payload.vehicleId || payload.vehicleLicense || '未知车辆';
  const description = payload.description || '';
  const limitValue = payload.limitValue;
  const actualValue = payload.actualValue;
  const ruleName = payload.ruleName || '交通规则';
  const violationType = payload.violationType || '';
  
  // 根据violationType区分超速和越界
  switch (violationType.toUpperCase()) {
 
    case 'SPEED':
      // 超速违规
      handleSpeedViolation(vehicleId, payload);
      break;
    case 'ACCESS':
      // 越界处理
      handleUnauthorizedEntry(vehicleId, payload);
      break;
      
    default:
      console.log(`未知的规则违规类型: ${violationType}`);
      // 默认按越界处理
      handleUnauthorizedEntry(vehicleId, payload);
  }
}

// 处理超速违规
function handleSpeedViolation(vehicleId, payload) {
  const actualValue = payload.actualValue;
  const limitValue = payload.limitValue;
  const description = payload.description || '超速违规';
  const ruleName = payload.ruleName || '速度限制';
  
  console.log(`检测到超速违规: ${vehicleId}, 实际速度: ${actualValue}, 限速: ${limitValue}`);
  
  // 显示超速告警提示
  showAlert(`⚠️ 超速告警：${vehicleId} ${description}`, 'warning', 8000);
  
  // 添加到告警列表，提供更详细的信息
  addAlarm({
    carId: vehicleId,
    carType: vehicles.value[vehicleId]?.type || '未知类型',
    time: `${formatTimeRange(new Date())}超速行驶`,
    description: `，速度达到${actualValue}km/h`,
    level: actualValue > limitValue * 1.5 ? 'high' : 'medium', // 超速50%以上为高级别告警
    type: 'speed',
    limitValue: limitValue,
    actualValue: actualValue,
    ruleName: ruleName,
    rawData: payload
  });
  
  // 在地图上标记该车辆的超速状态
  if (vehicles.value[vehicleId]) {
    // 避免重复设置超速状态导致闪烁
    const alreadyInSpeedViolation = vehicles.value[vehicleId].speedViolation;
    
    // 强制设置超速状态，确保图标正确显示
    vehicles.value[vehicleId].info = false;
    vehicles.value[vehicleId].alarm = false;
    vehicles.value[vehicleId].warning = false; // 清除warning状态，使用speedViolation状态
    vehicles.value[vehicleId].critical = false;
    vehicles.value[vehicleId].speedViolation = true; // 标记为超速状态
    vehicles.value[vehicleId].limitValue = limitValue;
    vehicles.value[vehicleId].actualValue = actualValue;
    vehicles.value[vehicleId].description = description;
    vehicles.value[vehicleId].ruleName = ruleName;
    vehicles.value[vehicleId].lastSpeedViolationTime = Date.now(); // 记录最后一次超速时间
    
    // 设置状态锁定，确保一段时间内不会改变状态
    if (!vehicles.value[vehicleId].statusLock) {
      vehicles.value[vehicleId].statusLock = {
        active: false,
        type: null,
        until: 0
      };
    }
    
    // 锁定超速状态20秒，确保图标不会来回切换
    vehicles.value[vehicleId].statusLock = {
      active: true,
      type: 'speedViolation',
      until: Date.now() + 20000 // 20秒锁定
    };
    
    // 清除任何可能存在的缓存图标，确保使用警告图标
    vehicles.value[vehicleId].cachedIconSrc = null;
    
    // 更新车辆图标为超速警告图标（只在首次设置或状态改变时更新）
    if (!alreadyInSpeedViolation) {
      if (vehicles.value[vehicleId].feature && styleManager.value) {
        setVehicleStyleRespectVisibility(
          vehicleId,
          styleManager.value.getVehicleStyle(
            vehicleId,
            vehicles.value[vehicleId].speed,
            vehicles.value[vehicleId].heading
          )
        );
        vehicles.value[vehicleId].lastIconUpdateTime = Date.now();
      }
    }
    
    // 更新标签显示为超速状态（只显示超速相关信息）
    if (vehicles.value[vehicleId].position && labelSystem.value) {
      // 先移除可能存在的旧标签，避免重复显示
      labelSystem.value.removeVehicleLabel(vehicleId);
      
      // 然后创建新的超速状态标签
      updateVehicleLabelIfAllowed(vehicleId, vehicles.value[vehicleId].position, actualValue || vehicles.value[vehicleId].speed, {
        description: description || `超速违规`,
        limitValue: limitValue,
        actualValue: actualValue,
        ruleName: ruleName,
        isSpeedViolation: true // 标记为超速状态，避免显示默认信息
      });
    }
    
    // 设置或重置超速状态自动清除计时器
    if (speedViolationTimers[vehicleId]) {
      clearTimeout(speedViolationTimers[vehicleId]);
    }
    
    // 设置新的超时计时器，如果在一定时间内（如20秒）没有再次接收到超速消息，则自动清除超速状态
    speedViolationTimers[vehicleId] = setTimeout(() => {
      // 确保车辆仍然存在
      if (vehicles.value[vehicleId]) {





        
        console.log(`超速状态超时: ${vehicleId}, 自动清除超速状态`);
        
        // 检查是否可以清除状态锁定
        if (!vehicles.value[vehicleId].statusLock ||
            !vehicles.value[vehicleId].statusLock.active ||
            Date.now() > vehicles.value[vehicleId].statusLock.until) {
          
          // 清除超速状态
          clearSpeedViolationStatus(vehicleId);
          
          // 清除计时器引用
          delete speedViolationTimers[vehicleId];
        } else {
          // 状态仍然锁定，延迟清除
          console.log(`车辆${vehicleId}状态仍然锁定，延迟清除超速状态`);
          
          // 重新设置计时器，等待锁定结束
          speedViolationTimers[vehicleId] = setTimeout(() => {
            clearSpeedViolationStatus(vehicleId);
            delete speedViolationTimers[vehicleId];
          }, vehicles.value[vehicleId].statusLock.until - Date.now());
        }
      }
    }, 20000); // 20秒超时，确保状态稳定
  }
}

// 处理越界告警
function handleUnauthorizedEntry(vehicleId, payload) {
  const description = payload.description || '越界告警';
  const alertLevel = payload.alertLevel || 'CRITICAL';
  const ruleName = payload.ruleName || '区域控制';
  
  console.log(`检测到越界告警: ${vehicleId}, ${description}, 规则: ${ruleName}`);
  
  // 显示越界告警提示
  showAlert(`⚠️ 越界告警：${vehicleId} ${description}`, 'critical', 10000);
  
  // 添加到告警列表
  addAlarm({
    carId: vehicleId,
    carType: vehicles.value[vehicleId]?.type || '未知类型',
    time: `${formatTimeRange(new Date())}越界`,
    description: '越界告警',
    level: 'high',
    type: 'report', // 修改类型为report，与AlarmNotification.vue中的标签页类型匹配
    rawData: payload
  });
  console.log('越界告警------------------------------------', vehicles.value[vehicleId].type);
  // 在地图上标记该车辆的越界状态
  if (vehicles.value[vehicleId]) {
    vehicles.value[vehicleId].critical = true;
    vehicles.value[vehicleId].alarm = false;
    vehicles.value[vehicleId].warning = false;
    vehicles.value[vehicleId].info = false;
    vehicles.value[vehicleId].speedViolation = false;
    vehicles.value[vehicleId].description = description;
    vehicles.value[vehicleId].ruleName = ruleName;
    
    // 更新车辆图标为越界警告图标
    if (vehicles.value[vehicleId].feature && styleManager.value) {
      setVehicleStyleRespectVisibility(
        vehicleId,
        styleManager.value.getVehicleStyle(
          vehicleId,
          vehicles.value[vehicleId].speed,
          vehicles.value[vehicleId].heading
        )
      );
    }
    
    // 更新标签显示
    if (vehicles.value[vehicleId].position && labelSystem.value) {
      updateVehicleLabelIfAllowed(vehicleId, vehicles.value[vehicleId].position, vehicles.value[vehicleId].speed, {
        description: description,
        ruleName: ruleName,
        isUnauthorizedEntry: true
      });
    }
  }
}

// 清除车辆超速状态的专门函数
function clearSpeedViolationStatus(vehicleId) {
  const vehicle = vehicles.value[vehicleId];
  if (!vehicle) return;

  console.log(`开始清除车辆${vehicleId}的超速状态`);

  // 检查是否可以清除状态锁定
  if (vehicle.statusLock && vehicle.statusLock.active && Date.now() < vehicle.statusLock.until) {
    console.log(`车辆${vehicleId}状态锁定中，暂不清除超速状态`);
    return;
  }

  // 清除所有告警状态
  vehicle.info = false;
  vehicle.alarm = false;
  vehicle.warning = false;
  vehicle.critical = false;
  vehicle.speedViolation = false;
  vehicle.limitValue = undefined;
  vehicle.actualValue = undefined;
  vehicle.description = undefined;
  vehicle.ruleName = undefined;

  // 清除状态锁定
  if (vehicle.statusLock) {
    vehicle.statusLock.active = false;
    vehicle.statusLock.type = null;
    vehicle.statusLock.until = 0;
  }

  // 清除缓存的图标，确保使用默认图标
  vehicle.cachedIconSrc = null;
  vehicle.lastIconUpdateTime = Date.now();

  // 更新车辆图标为默认图标
  if (vehicle.feature && styleManager.value) {
    setVehicleStyleRespectVisibility(
      vehicleId,
      styleManager.value.getVehicleStyle(vehicleId, vehicle.speed, vehicle.heading)
    );
  }

  // 更新标签显示为正常状态（只显示车辆ID，不显示0.00km/h）
  if (vehicle.position && labelSystem.value) {
    // 先移除可能存在的旧标签，避免重复显示
    labelSystem.value.removeVehicleLabel(vehicleId);
    
    // 创建新的标准标签
    updateVehicleLabelIfAllowed(vehicleId, vehicle.position, vehicle.speed > 0.1 ? vehicle.speed : 0);
  }

  console.log(`已成功清除车辆${vehicleId}的超速状态`);
}

// 获取车辆类型键值
function getVehicleTypeKey(vehicle) {
  if (!vehicle) return 'UNMANNED_VEHICLE';
  const override = vehicleDisplayStore.getVehicleTypeOverride(vehicle.id);
  const vehicleType = String(override || vehicle.type || '').toUpperCase();
  if (!vehicleType) return 'UNMANNED_VEHICLE';
  
  // 根据车辆类型和特征确定分类键值
  if (vehicleType === 'AIRCRAFT' || vehicleType === 'AIRCRAFT_IN' || vehicleType === 'AIRCRAFT_OUT' || vehicleType === 'HANGKONG') {
    return 'AIRCRAFT';
  } else if (vehicle.isAircraft) {
    return 'AIRCRAFT';
  } else if (vehicleType === 'UNMANNED_VEHICLE' || vehicleType === 'WUREN' || vehicle.isUnmannedVehicle) {
    return 'UNMANNED_VEHICLE';
  } else if (vehicleType === 'SPECIAL_VEHICLE' || vehicleType === 'TEQIN' || vehicle.isSpecialVehicle) {
    return 'AIRPORT_VEHICLE';
  } else if (vehicleType === 'SHUTTLE_VEHICLE' || vehicle.isShuttleVehicle) {
    return 'SHUTTLE_VEHICLE';
  }
  
  // 默认返回无人车类型
  return 'UNMANNED_VEHICLE';
}

// 仅当左侧类别的 showLabel 且 visible 为真时才允许更新/创建标签
function isLabelAllowedForVehicle(vehicleId) {
  const vehicle = vehicles.value[vehicleId];
  if (!vehicle) return false;
  const typeKey = getVehicleTypeKey(vehicle);
  const isAircraft = typeKey === 'AIRCRAFT' || typeKey === 'AIRCRAFT_IN' || typeKey === 'AIRCRAFT_OUT';
  if (!isAircraft && !vehicleDisplayStore.isVehicleEnabled(vehicleId)) return false;
  const category = vehicleCategories.value?.[typeKey];
  return !!(category && category.visible && category.showLabel);
}

function updateVehicleLabelIfAllowed(vehicleId, coordinates, speed, alertInfo) {
  if (!labelSystem.value || !labelSystem.value.updateVehicleLabel) return;
  if (isLabelAllowedForVehicle(vehicleId)) {
    labelSystem.value.updateVehicleLabel(vehicleId, coordinates, speed, alertInfo);
  } else {
    // 当不允许显示时，确保现有标签保持隐藏（若已存在）
    if (labelSystem.value.setLabelVisibility) {
      labelSystem.value.setLabelVisibility(vehicleId, false);
    }
  }
}

// 获取默认车辆样式
function getDefaultVehicleStyle(vehicle) {
  if (!vehicle) return new Style({});
  
  const typeUpper = String(vehicle.type || '').toUpperCase();
  const isAircraft = vehicle.isAircraft || typeUpper === 'AIRCRAFT' || typeUpper === 'AIRCRAFT_IN' || typeUpper === 'AIRCRAFT_OUT' || typeUpper === 'HANGKONG';
  const isUnmanned = vehicle.isUnmannedVehicle || typeUpper === 'UNMANNED_VEHICLE' || typeUpper === 'WUREN' || String(vehicle.type || '').includes('无人');
  const iconSrc = isAircraft
    ? (vehicle.hasAircraftRoute ? aircraftRouteIcon : aircraftIcon)
    : (isUnmanned ? carIcon : specialCar);
  const heading = vehicle.heading || 0;
  
  // 计算旋转角度
  const rotationRad = ((heading - 72) * Math.PI) / 180;
  
  return new Style({
    image: new Icon({
      src: iconSrc,
      scale: isAircraft ? AIRCRAFT_ICON_SCALE : DEFAULT_VEHICLE_ICON_SCALE,
      anchor: [0.5, 0.5],
      rotation: rotationRad,
    })
  });
}

function setVehicleStyleRespectVisibility(vehicleId, style) {
  const vehicle = vehicles.value[vehicleId];
  if (!vehicle || !vehicle.feature) return;
  const typeKey = getVehicleTypeKey(vehicle);
  const isAircraft = typeKey === 'AIRCRAFT' || typeKey === 'AIRCRAFT_IN' || typeKey === 'AIRCRAFT_OUT';
  const enabled = isAircraft ? true : vehicleDisplayStore.isVehicleEnabled(vehicleId);
  const category = vehicleCategories.value?.[typeKey];
  const visible = enabled && !!(category && category.visible);
  vehicle.feature.setStyle(visible ? style : new Style({}));
  
  if (labelSystem.value?.setLabelVisibility) {
    labelSystem.value.setLabelVisibility(vehicleId, visible && isLabelAllowedForVehicle(vehicleId));
  }
}

function applyVehicleStyleWithVisibility(vehicleId, style) {
  setVehicleStyleRespectVisibility(vehicleId, style);
}

// 默认获取车辆样式函数（用于动画系统）
// function defaultGetVehicleStyle(vehicleId, speed, heading) {
//   const vehicle = vehicles.value[vehicleId];
//   if (!vehicle) return new Style({});
  
//   return getDefaultVehicleStyle(vehicle);
// }

// 清除车辆告警状态（如果需要）
function clearVehicleAlertStatus(vehicleData) {
  const { object_id, speed } = vehicleData;
  
  // 检查该车辆是否已存在且有告警状态
  const existingVehicle = vehicles.value[object_id];
  if (!existingVehicle) return;
  
  // 检查是否有状态锁定
  if (existingVehicle.statusLock && 
      existingVehicle.statusLock.active && 
      Date.now() < existingVehicle.statusLock.until) {
    // 状态锁定中，不清除状态
    return;
  }
  
  // 检查是否有超速状态 - 更严格的清除条件，避免图标来回切换
  if (existingVehicle.speedViolation && existingVehicle.limitValue) {
    // 如果当前速度低于限速值，清除超速状态
    if (speed < existingVehicle.limitValue) {
      // 添加更大的缓冲区，避免在临界值附近频繁切换状态
      // 只有当速度低于限速值的70%时才清除超速状态，确保状态稳定
      const speedBuffer = existingVehicle.limitValue * 0.7;

      if (speed < speedBuffer) {
        console.log(`检测到车辆${object_id}速度降低到${speed.toFixed(1)}km/h，低于限速${existingVehicle.limitValue}km/h的70%，考虑清除超速状态`);

        // 检查是否应该清除超速状态
        // 如果最后一次超速时间在15秒内，不清除状态以避免闪烁
        const now = Date.now();
        if (!existingVehicle.lastSpeedViolationTime || now - existingVehicle.lastSpeedViolationTime > 15000) {
          // 检查状态锁定
          if (!existingVehicle.statusLock ||
              !existingVehicle.statusLock.active ||
              now > existingVehicle.statusLock.until) {
            // 清除超速状态
            clearSpeedViolationStatus(object_id);
            console.log(`已清除${object_id}的超速状态，恢复为普通状态`);
          } else {
            console.log(`车辆${object_id}状态锁定中，暂不清除超速状态`);
          }
        } else {
          console.log(`车辆${object_id}刚刚处于超速状态，暂不清除状态以避免闪烁`);
        }
      }
    }
  }
  

}

// 发送心跳
function sendPing() {
  if (wsService) {
    wsService.send('ping');
    console.log('发送心跳: ping');
  }
}

// 订阅消息
function sendSubscribe() {
  if (wsService) {
    const message = JSON.stringify({
      type: 'subscribe',
      topics: ['position_update', 'collision_warning', 'path_conflict_status', 'path_conflict_alert', 'rule_violation'],
      timestamp: Date.now()
    });
    wsService.send(message);
    console.log('发送订阅请求');
  }
}

// 清理资源
function cleanup() {
  // 断开WebSocket连接
  if (wsService) {
    wsService.close();
    wsService = null;
  }
  
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
  
  // 清理所有超速状态计时器
  Object.keys(speedViolationTimers).forEach(vehicleId => {
    clearTimeout(speedViolationTimers[vehicleId]);
    delete speedViolationTimers[vehicleId];
  });
  
  // 清理所有飞机路线定时器
  Object.keys(aircraftRouteTimers).forEach(flightNo => {
    clearTimeout(aircraftRouteTimers[flightNo]);
    delete aircraftRouteTimers[flightNo];
  });
  console.log('已清理所有飞机路线定时器');

  // 清理所有冲突/违规状态定时器
  const statusTimers = violationStatusTimers.value || {};
  Object.keys(statusTimers).forEach((key) => {
    clearTimeout(statusTimers[key]);
    delete statusTimers[key];
  });
  violationStatusTimers.value = {};
  
  // 移除图层
  if (vehicleLayer && props.map) {
    props.map.removeLayer(vehicleLayer);
    vehicleLayer = null;
  }
  
  // 移除飞机路线图层
  if (aircraftRouteLayer && props.map) {
    props.map.removeLayer(aircraftRouteLayer);
    aircraftRouteLayer = null;
  }

  if (pathConflictLayer && props.map) {
    props.map.removeLayer(pathConflictLayer);
    pathConflictLayer = null;
    pathConflictSource = null;
  }
  
  // 清空飞机路线数据
  aircraftRoutes.value = {};
  pathConflicts.value = {};
  
  // 移除标签
  if (props.map && labelSystem.value) {
    Object.values(vehicles.value).forEach(vehicle => {
      if (vehicle.overlay) {
        console.log(`移除标签: ${vehicle.id}`);
        labelSystem.value.removeVehicleLabel(vehicle.id);
      }
    });
  }
  
  // 清空车辆数据
  vehicles.value = {};
}

// 定期清理过期（掉线）的航空器
function cleanExpiredAircraft() {
  if (!vehicles.value) return;
  const now = Date.now();
  const expireThreshold = 60 * 1000; // 60秒无更新则判定为失效航空器
  
  Object.keys(vehicles.value).forEach(vehicleId => {
    const vehicle = vehicles.value[vehicleId];
    if (!vehicle) return;
    
    // 只处理航空器
    if (vehicle.isAircraft) {
      const lastUpdate = vehicle.lastUpdateTime || now;
      if (now - lastUpdate > expireThreshold) {
        console.warn(`[Cleanup] 航空器 ${vehicleId} 超过 60 秒未更新位置，开始清理相关资源...`);
        
        // 1. 移除标签
        if (labelSystem.value && typeof labelSystem.value.removeVehicleLabel === 'function') {
          try {
            labelSystem.value.removeVehicleLabel(vehicleId);
          } catch (e) {
            console.error(`清理标签出错 ${vehicleId}:`, e);
          }
        }
        
        // 2. 移除航线及起点终点标志
        try {
          removeAircraftRoute(vehicleId);
        } catch (e) {
          console.error(`清理航线出错 ${vehicleId}:`, e);
        }
        
        // 3. 移除地图中的要素
        if (vehicle.feature && vehicleSource) {
          try {
            vehicleSource.removeFeature(vehicle.feature);
          } catch (e) {
            console.error(`从地图移除 Feature 出错 ${vehicleId}:`, e);
          }
        }
        
        // 4. 清理动画数据
        if (animationSystem.value) {
          if (animationSystem.value.vehicleAnimations?.value?.[vehicleId]) {
            delete animationSystem.value.vehicleAnimations.value[vehicleId];
          }
          if (animationSystem.value.vehicleMotionHistory?.value?.[vehicleId]) {
            delete animationSystem.value.vehicleMotionHistory.value[vehicleId];
          }
        }
        
        // 5. 从数据源删除
        delete vehicles.value[vehicleId];
        console.warn(`[Cleanup] 航空器 ${vehicleId} 资源已全部清理完毕。`);
      }
    }
  });
}

// 组件挂载时初始化
onMounted(() => {
  // 创建图层并连接WebSocket
  if (props.map) {
    createVehicleLayer();
    createAircraftRouteLayer(); // 创建飞机路线图层
    createPathConflictLayer();
  }
  
  // 连接WebSocket
  connectWebSocket();

  const allowDebugInject =
    import.meta.env.DEV ||
    window.APP_CONFIG?.ENABLE_ROUTE_DEBUG === true ||
    new URLSearchParams(window.location.search).has('debugRoute')

  if (allowDebugInject) {
    window.__injectWsMessage = (msg) => {
      const raw = typeof msg === 'string' ? msg : JSON.stringify(msg)
      handleWsMessage(raw)
    }
    window.__injectAircraftRouteUpdate = (payload, options = { fit: true }) => {
      handleAircraftRouteUpdate(payload)
      if (options && options.fit === false) return
      try {
        const flightNo = payload?.flightNo
        const route = flightNo ? aircraftRoutes.value?.[flightNo] : null
        if (route && route.feature && props.map) {
          const extent = route.feature.getGeometry().getExtent()
          props.map.getView().fit(extent, { padding: [50, 50, 50, 50], duration: 500 })
        }
      } catch (e) {}
    }
  }
  
  // 设置定时发送心跳
  const pingInterval = setInterval(() => {
    if (wsService && wsConnected.value) {
      sendPing();
    }
  }, 30000); // 每30秒发送一次心跳

  // 设置定时扫描过期航空器
  cleanupTimer = setInterval(() => {
    cleanExpiredAircraft();
  }, 10000); // 每10秒执行一次过期清理
  
  // 组件卸载时清理资源
  onUnmounted(() => {
    clearInterval(pingInterval);
    if (cleanupTimer) {
      clearInterval(cleanupTimer);
      cleanupTimer = null;
    }
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
    try {
      delete window.__injectWsMessage
      delete window.__injectAircraftRouteUpdate
    } catch (e) {}
    cleanup();
  });
});

// 组件被激活时（切换回该路由时）
onActivated(() => {
  console.log('VehicleMovementControl组件被激活');
  // 如果WebSocket未连接，重新连接
  if (!wsConnected.value && !wsService) {
    console.log('组件激活，WebSocket未连接，正在重新连接...');
    // 延迟一点时间再连接，确保DOM已完全渲染
    reconnectTimer = setTimeout(() => {
      connectWebSocket();
    }, 500);
  } else {
    console.log('组件激活，WebSocket已连接');
  }
});

// 组件被停用时（切换到其他路由时）
onDeactivated(() => {
  console.log('VehicleMovementControl组件被停用');
  // 可以选择在这里关闭WebSocket，也可以保持连接
  // 如果希望在组件隐藏时断开连接，可以取消下面的注释
  /*
  if (wsService) {
    console.log('组件停用，关闭WebSocket连接');
    wsService.close();
    wsService = null;
    wsConnected.value = false;
  }
  */
});

// 监听地图实例变化
watch(() => props.map, (newMap) => {
  if (newMap) {
    createVehicleLayer();
    createAircraftRouteLayer(); // 创建飞机路线图层
    createPathConflictLayer();
  }
});

watch(pathConflictDisplayEnabled, (enabled) => {
  if (!enabled) {
    clearPathConflictDisplay();
    clearAlertMessage();
  }
});

// 向外暴露方法
defineExpose({
  updateVehiclePosition,
  wsConnected,
  sendPing,
  sendSubscribe,
  vehicleCategories,
  weatherStationVisible,
  vehicleDetailVisible,
  vehicleDetail,
  alarmList, // 暴露告警列表
  toggleWeatherStationVisibility() {
    weatherStationVisible.value = !weatherStationVisible.value;
  },
  toggleVehicleDetailVisibility() {
    vehicleDetailVisible.value = !vehicleDetailVisible.value;
  },
  updateVehicleDetail(data) {
    if (data) {
      vehicleDetail.value = {...vehicleDetail.value, ...data};
      vehicleDetailVisible.value = true;
    }
  },
  showVehicleDetail(vehicleId, pixelPosition) {
    if (vehicles.value[vehicleId]) {
      // 更新车辆详情
      vehicleDetail.value = {
        id: vehicleId,
        type: vehicles.value[vehicleId].type,
        status: '任务中',
        startTime: '11-19 11:30',
        currentLocation: '当前位置',
        startLocation: 'T1航站楼',
        endLocation: 'T3航站楼',
        totalDistance: '1.3km',
        battery: '60%',
        manager: '张三',
        phone: '18661910988'
      };
      
      // 设置弹窗位置
      if (pixelPosition) {
        const viewportPosition = props.map.getViewport().getBoundingClientRect();
        detailPopupStyle.value = {
          left: (viewportPosition.left + pixelPosition[0] + 10) + 'px',
          top: (viewportPosition.top + pixelPosition[1] + 10) + 'px'
        };
      }
      
      // 显示详情弹窗
      vehicleDetailVisible.value = true;
    }
  },
  setCategoryVisibility(type, { visible, showLabel }) {
    console.log(`VehicleMovementControl: 设置分类 ${type} 可见性`, { visible, showLabel });
    
    if (vehicleCategories.value[type]) {
      // 更新分类设置
      vehicleCategories.value[type].visible = visible;
      vehicleCategories.value[type].showLabel = showLabel;
      
      console.log(`更新分类设置完成: ${type}`, vehicleCategories.value[type]);
      
      // 立即应用更改 - 更新所有属于此类别的车辆
      Object.values(vehicles.value).forEach(vehicle => {
        let vehicleTypeKey = getVehicleTypeKey(vehicle);
        
        // 如果车辆属于当前修改的类别
        if (vehicleTypeKey === type) {
          console.log(`更新车辆 ${vehicle.id} (${vehicleTypeKey}) 的显示状态:`, { visible, showLabel });
          
          // 更新图标可见性
          if (vehicle.feature) {
            if (visible) {
              // 显示图标
              if (styleManager.value) {
                setVehicleStyleRespectVisibility(
                  vehicle.id,
                  styleManager.value.getVehicleStyle(vehicle.id, vehicle.speed, vehicle.heading)
                );
              } else {
                setVehicleStyleRespectVisibility(
                  vehicle.id,
                  getDefaultVehicleStyle(vehicle)
                );
              }
            } else {
              // 隐藏图标
              vehicle.feature.setStyle(new Style({}));
            }
          }
          
          // 控制文本标签可见性
          if (labelSystem.value) {
            if (labelSystem.value.setLabelVisibility) {
              labelSystem.value.setLabelVisibility(vehicle.id, showLabel);
            } else if (labelSystem.value.updateVehicleLabel) {
              // 如果没有setLabelVisibility方法，使用updateVehicleLabel
              if (showLabel && vehicle.position) {
                updateVehicleLabelIfAllowed(vehicle.id, vehicle.position, vehicle.speed);
              } else {
                labelSystem.value.removeVehicleLabel(vehicle.id);
              }
            }
          }
        }
      });
    }
  },
  reconnectWebSocket() {
    console.log('手动重连WebSocket');
    connectWebSocket();
  },
  
  // 添加平滑动画相关方法
  startVehicleSmoothing() {
    if (animationSystem.value) {
      animationSystem.value.startAnimationLoop();
    }
  },
  
  stopVehicleSmoothing() {
    if (animationSystem.value) {
      animationSystem.value.stopAnimationLoop();
    }
  },
  
  resetVehicleAnimations() {
    if (animationSystem.value) {
      animationSystem.value.resetAnimations();
    }
  },
  
  // 飞机路线相关方法
  getAircraftRoutes() {
    return aircraftRoutes.value;
  },
  
  showAircraftRoute(flightNo) {
    const uFlightNo = String(flightNo || '').trim().toUpperCase();
    const route = aircraftRoutes.value[uFlightNo];
    if (route && route.feature) {
      // 定位到路线
      const extent = route.feature.getGeometry().getExtent();
      props.map.getView().fit(extent, {
        padding: [50, 50, 50, 50],
        duration: 1000
      });
    }
  },
  
  setAircraftRouteVisibility(visible) {
    if (aircraftRouteLayer) {
      aircraftRouteLayer.setVisible(visible);
    }
  },

  // 飞机路线点标记相关方法
  createRoutePointMarker(flightNo, pointType, coordinates, routeType) {
    return createRoutePointMarker(flightNo, pointType, coordinates, routeType);
  },

  updateRoutePointMarker(flightNo, pointType, coordinates) {
    return updateRoutePointMarker(flightNo, pointType, coordinates);
  },

  removeAircraftRoute(flightNo) {
    return removeAircraftRoute(flightNo);
  },

  debugInjectAircraftRouteUpdate(payload) {
    return handleAircraftRouteUpdate(payload)
  },

  // 告警通知相关方法
  showAlarmNotification(message, type, duration) {
    if (alarmNotification.value) {
      alarmNotification.value.showNotification(message, type, duration);
    }
  },
  hideAlarmNotification() {
    if (alarmNotification.value) {
      alarmNotification.value.hideNotification();
    }
  },
  handleAlarmClose() {
    // 告警通知组件关闭时，可以在这里执行一些清理或状态重置
    console.log('告警通知组件已关闭');
  },
  addAlarm(alarm) {
    return addAlarm(alarm);
  },
  updateAlarm(alarmId, updates) {
    return updateAlarm(alarmId, updates);
  },
  removeAlarm(alarmId) {
    return removeAlarm(alarmId);
  },
  clearAlarms() {
    return clearAlarms();
  },
  updateAlarmNotification() {
    return updateAlarmNotification();
  },
  toggleAlarmNotification() {
    return toggleAlarmNotification();
  },
  handleAircraftRouteUpdate(payload) {
    return handleAircraftRouteUpdate(payload);
  },
  drawTestRoute() {
    const routes = [
      {
        flightNo: '805-807',
        routeType: 'TEST',
        routeStatus: 'ACTIVE',
        points: [
          [40508513.641064, 4024186.813497],
          [40508714.127776, 4024250.934516],
          [40508853.166318, 4024293.929307],
          [40509022.478135, 4024346.688892]
        ]
      },
      {
        flightNo: 'M4 829-826-K1',
        routeType: 'TEST',
        routeStatus: 'ACTIVE',
        points: [
          [40507849.913313, 4023625.932486],
          [40507732.597485, 4023991.671027],
          [40507723.998527, 4023986.908527],
          [40507674.841898, 4024138.30738]
        ]
      },
      {
        flightNo: 'M1 K2-1-1-1#消防',
        routeType: 'TEST',
        routeStatus: 'ACTIVE',
        points: [
          [40509113.197805, 4024029.951692],
          [40508997.734226, 4024393.687528],
          [40509007.523809, 4024395.275028],
          [40508957.783071, 4024548.361738]
        ]
      }
    ];

    routes.forEach(r => {
      const wktPoints = (r.points || []).map((p) => `${p[0]} ${p[1]}`).join(', ')
      const payload = {
        flightNo: r.flightNo,
        routeType: r.routeType,
        routeStatus: r.routeStatus,
        routeGeometry: `LINESTRING(${wktPoints})`
      };
      handleAircraftRouteUpdate(payload);
    });
  }
});

// 添加一个默认的getVehicleStyle函数
function defaultGetVehicleStyle(id, _speed, heading) {
  // 检查车辆类型
  const vehicle = vehicles.value[id];
  if (!vehicle) return createDefaultStyle(carIcon, heading);
  
  // 根据车辆类型选择图标，与VehicleStyleManager保持一致
  if (vehicle.isAircraft) {
    return createDefaultStyle(vehicle.hasAircraftRoute ? aircraftRouteIcon : aircraftIcon, heading);
  } else if (vehicle.type === '无人车' || vehicle.type === 'UNMANNED_VEHICLE') {
    // 无人车使用noPeopleCar.svg图标
    return createDefaultStyle(carIcon, heading);
  } else {
    // 其他车辆使用specialCar.svg图标
    return createDefaultStyle(specialCar, heading);
  }
}

// 创建默认样式的辅助函数
function createDefaultStyle(iconSrc, heading) {
  // 确保heading是有效的数值并正确转换为弧度
  const validHeading = heading !== undefined ? Number(heading) : 0;
  
  // 计算正确的旋转角度
  // 在OpenLayers中，0度是向上，顺时针增加
  // 而heading是0度为北，顺时针增加
  // 由于地图旋转了72度，heading=72对应地图上方
  const rotationRad = ((validHeading - 72) * Math.PI) / 180;
  // console.log(`createDefaultStyle: heading=${validHeading}, 旋转角度计算: (${validHeading} - 72) * π/180 = ${rotationRad} 弧度, ${(validHeading - 72)}度`);
  
  return new Style({
    image: new Icon({
      src: iconSrc, // 使用传入的图标源
      scale: (iconSrc === aircraftIcon || iconSrc === aircraftRouteIcon) ? AIRCRAFT_ICON_SCALE : DEFAULT_VEHICLE_ICON_SCALE,
      anchor: [0.5, 0.5],
      rotation: rotationRad, // 应用计算后的旋转角度
    })
  });
}
</script> 

<style scoped>
/* 告警按钮样式 */
.alarm-btn {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 40px;
  height: 40px;
  background-color: rgba(41, 44, 56, 0.8);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1000;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  transition: all 0.3s;
}

.alarm-btn:hover {
  background-color: rgba(41, 44, 56, 1);
  transform: scale(1.05);
}

.alarm-btn img {
  width: 24px;
  height: 24px;
}

.alarm-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  background-color: #ff4d4f;
  color: white;
  font-size: 12px;
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
}

.path-conflict-card {
  position: absolute;
  left: 28px;
  top: calc(23% + 160px);
  width: 246px;
  color: #fff;
  z-index: 1000;
  background: rgba(41, 44, 56, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  box-shadow: 0 10px 15px rgba(2, 2, 2, 0.25);
  overflow: hidden;
}

.path-conflict-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 10px;
  font-size: 14px;
  font-weight: 700;
  background: rgba(52, 55, 68, 0.96);
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.path-conflict-level {
  padding: 1px 7px;
  border-radius: 10px;
  font-size: 12px;
  background: rgba(59, 130, 246, 0.28);
}

.path-conflict-body {
  padding: 8px 10px 10px;
  font-size: 12px;
  line-height: 1.8;
}

.path-conflict-muted,
.path-conflict-debug {
  color: rgba(255, 255, 255, 0.78);
}

.path-conflict-reason {
  color: rgba(255, 214, 165, 0.95);
}

.path-conflict-card.level-WARNING .path-conflict-level {
  background: rgba(245, 158, 11, 0.35);
}

.path-conflict-card.level-CRITICAL .path-conflict-level,
.path-conflict-card.level-EMERGENCY .path-conflict-level {
  background: rgba(239, 68, 68, 0.38);
}
</style>
