<template>
  <!-- 动画系统不需要模板内容 -->
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { Style, Icon } from 'ol/style';

// 定义props
const props = defineProps({
  map: Object,
  vehicleSource: Object,
  vehicles: Object,
  getVehicleStyle: Function,
  applyStyle: Function,
  applyLabelPosition: Function
});

// 动画相关变量
const animationFrameId = ref(null);
const lastAnimationTime = ref(0);
const vehicleAnimations = ref({}); // 存储平滑动画数据
const vehicleMotionHistory = ref({}); // 存储车辆移动历史
const PREDICTION_THRESHOLD = 50; // 从100ms降低到50ms，更早开始预测
const MAX_PREDICTION_TIME = 15000; // 从10000ms增加到15000ms，延长预测时间

// 物理模拟参数 - 优化为完全平滑移动
const SPEED_SMOOTHING = 0.3; // 大幅降低速度平滑系数，让速度快速响应
const POSITION_SMOOTHING = 1.0; // 设为1.0，每帧直接移动到理想位置，确保完全平滑
const MIN_MOVE_THRESHOLD = 0.0000001; // 极小的移动阈值
const CONTINUOUS_MOVEMENT = true; // 启用连续移动模式
const MIN_SPEED = 1.0; // 适中的最低保持速度
const PREDICTION_DECAY_RATE = 0.99; // 更快的预测衰减
const CONTINUOUS_MOVEMENT_THRESHOLD = 50; // 大幅降低阈值，几乎立即触发连续移动
const INTERPOLATION_STEPS = 60; // 每秒60帧的插值步数

// 缓动函数 - 平滑的加减速
function easeInOutQuad(t) {
  return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}

// 缓动函数 - 更自然的启动
function easeOutCubic(t) {
  return 1 - Math.pow(1 - t, 3);
}

// 缓动函数 - 更自然的减速
function easeOutQuint(t) {
  return 1 - Math.pow(1 - t, 5);
}

// 启动动画循环
function startAnimationLoop() {
  // 确保只有一个动画循环在运行
  if (animationFrameId.value) {
    cancelAnimationFrame(animationFrameId.value);
  }
  
  lastAnimationTime.value = 0; // 重置时间，确保第一帧计算正确
  
  const animate = (timestamp) => {
    if (!lastAnimationTime.value) lastAnimationTime.value = timestamp;
    const deltaTime = timestamp - lastAnimationTime.value;
    lastAnimationTime.value = timestamp;
    
    // 限制deltaTime，提高最小帧率到60fps
    const clampedDeltaTime = Math.min(deltaTime, 16.67); // 约60fps的最小帧率
    
    try {
      updateVehicleAnimations(clampedDeltaTime);
    } catch (e) {
      console.error('更新车辆动画出错:', e);
    }
    
    animationFrameId.value = requestAnimationFrame(animate);
  };
  
  animationFrameId.value = requestAnimationFrame(animate);
}

// 更新车辆动画 - 简化版本，专注于平滑移动
function updateVehicleAnimations(deltaTime) {
  if (!props.vehicleSource || !props.map) return;
  
  const currentTime = performance.now();
  
  Object.keys(props.vehicles).forEach(id => {
    try {
      const vehicle = props.vehicles[id];
      if (!vehicle) return;
      
      const animData = vehicleAnimations.value[id];
      if (!animData) return;
      
      // 确保车辆持续移动
      //这个函数检查车辆是否长时间没有收到新的位置更新，
      // 如果是，则基于历史移动方向继续移动车辆，避免车辆在屏幕上突然停止。
      try {
        ensureContinuousMovement(animData, vehicle, currentTime, deltaTime);
      } catch (e) {
        console.error(`预测连续运动出错 [${id}]:`, e);
      }
      
      // 平滑速度过渡
      if (animData.currentSpeed === undefined || !Number.isFinite(animData.currentSpeed)) {
        animData.currentSpeed = Number.isFinite(animData.speed) ? animData.speed : MIN_SPEED;
      } else {
        const targetSpeed = Number.isFinite(animData.speed) ? animData.speed : MIN_SPEED;
        animData.currentSpeed = animData.currentSpeed * SPEED_SMOOTHING + 
                               targetSpeed * (1 - SPEED_SMOOTHING);
      }
      
      let currentSpeed = Math.max(Number.isFinite(animData.currentSpeed) ? animData.currentSpeed : MIN_SPEED, MIN_SPEED);
      
      // 计算到目标位置的向量
      const dx = animData.targetPosition[0] - animData.position[0];
      const dy = animData.targetPosition[1] - animData.position[1];
      const distance = Math.sqrt(dx * dx + dy * dy);
      
      // 计算基于速度和时间的理想移动距离
      const idealDistance = (currentSpeed * 1000 / 3600) * (deltaTime / 1000);
      
      // 始终移动，确保完全平滑 - 最终优化版本
      let moveDistance = 0;
      
      // 简化移动逻辑，确保始终平滑移动
      if (distance > 0.0001) {
        // 有明确目标时，计算合适的移动距离
        if (distance > idealDistance) {
          // 距离较远，按理想速度移动
          moveDistance = idealDistance;
        } else {
          // 距离较近，使用更激进的移动策略确保快速到达
          // 在16ms内（约60fps）移动更多距离，避免停顿
          moveDistance = Math.max(distance * 0.5, idealDistance * 0.3);
        }
      } else {
        // 已到达目标或距离极小，使用预测向量保持移动
        moveDistance = idealDistance * 0.8;
      }
      
      // 计算移动方向和更新位置
      if (distance > 0.0001) {
        const moveRatio = Math.min(Number.isFinite(moveDistance / distance) ? moveDistance / distance : 0, 1.0);
        
        // 直接更新位置
        animData.position[0] += dx * moveRatio;
        animData.position[1] += dy * moveRatio;
      } else if (animData.predictionVector) {
        // 使用预测向量继续移动
        const predLen = Math.sqrt(
          animData.predictionVector[0] * animData.predictionVector[0] + 
          animData.predictionVector[1] * animData.predictionVector[1]
        );
        
        if (predLen > 0) {
          animData.position[0] += (animData.predictionVector[0] / predLen) * moveDistance;
          animData.position[1] += (animData.predictionVector[1] / predLen) * moveDistance;
        }
      }

      if (!Number.isFinite(animData.position[0]) || !Number.isFinite(animData.position[1])) {
        const fallback = props.vehicles?.[id]?.position;
        if (Array.isArray(fallback) && fallback.length >= 2 && Number.isFinite(fallback[0]) && Number.isFinite(fallback[1])) {
          animData.position = [fallback[0], fallback[1]];
        } else if (Array.isArray(animData.targetPosition) && animData.targetPosition.length >= 2 && Number.isFinite(animData.targetPosition[0]) && Number.isFinite(animData.targetPosition[1])) {
          animData.position = [animData.targetPosition[0], animData.targetPosition[1]];
        } else {
          return;
        }
      }
      
      // 更新地图上的要素位置
      const feature = props.vehicleSource.getFeatureById(id);
      if (feature) {
        const geometry = feature.getGeometry();
        if (!geometry || !Number.isFinite(animData.position[0]) || !Number.isFinite(animData.position[1])) {
          return;
        }
        geometry.setCoordinates(animData.position);
        
        // 更新车辆对象中的位置信息
        if (props.vehicles[id] && Number.isFinite(animData.position[0]) && Number.isFinite(animData.position[1])) {
          props.vehicles[id].position = [...animData.position];
        }

        if (props.applyLabelPosition) {
          if (!animData.lastLabelUpdateTime || (currentTime - animData.lastLabelUpdateTime) > 33) {
            props.applyLabelPosition(id, animData.position);
            animData.lastLabelUpdateTime = currentTime;
          }
        }
        
        // 更新车辆样式
        if (props.getVehicleStyle) {
          // const currentHeading = vehicle ? vehicle.heading : 0;
          // //优先使用动画系统内部的heading值
          const currentHeading = animData.heading !== undefined ? animData.heading : (vehicle ? vehicle.heading : 0);
          
          if (!animData.lastHeading || Math.abs(animData.lastHeading - currentHeading) > 0.5) {
            const style = props.getVehicleStyle(id, currentSpeed, currentHeading);
            if (props.applyStyle) {
              props.applyStyle(id, style);
            } else {
              feature.setStyle(style);
            }
            animData.lastHeading = currentHeading;
          }
        }
      }
      
      // 保存当前速度
      animData.currentSpeed = currentSpeed;
      
      // 简化的历史轨迹更新
      updateVehiclePathHistory(id, animData, currentTime);
    } catch (err) {
      console.error(`更新车辆[${id}]动画渲染出错:`, err);
    }
  });
}

// 更新车辆历史轨迹
function updateVehiclePathHistory(id, animData, currentTime) {
  // 初始化历史轨迹数组（如果不存在）
  if (!animData.pathHistory) {
    animData.pathHistory = [];
  }
  
  // 每100ms记录一次位置，提高记录频率
  if (!animData.lastPathRecordTime || currentTime - animData.lastPathRecordTime > 100) {
    // 确保 animData.position 有效且非空
    if (Array.isArray(animData.position) && animData.position.length >= 2 && Number.isFinite(animData.position[0]) && Number.isFinite(animData.position[1])) {
      // 添加当前位置到历史轨迹
      animData.pathHistory.push({
        time: currentTime,
        position: [...animData.position],
        heading: animData.heading,
        speed: animData.currentSpeed
      });
      
      // 保持最多10个历史点
      if (animData.pathHistory.length > 10) {
        animData.pathHistory.shift();
      }
      
      animData.lastPathRecordTime = currentTime;
    }
  }
}

// 确保车辆持续移动，即使没有新的位置更新 - 简化版本
function ensureContinuousMovement(animData, vehicle, currentTime, deltaTime) {
  const timeSinceLastUpdate = currentTime - animData.lastUpdated;
  
  // 如果超过阈值没有位置更新，创建简单的预测移动
  if (timeSinceLastUpdate > CONTINUOUS_MOVEMENT_THRESHOLD && animData.currentSpeed > 0) {
    // 简单的预测：基于最后的移动方向继续移动
    if (!animData.predictionVector) {
      // 如果没有预测向量，使用历史轨迹的最后方向
      if (animData.pathHistory && animData.pathHistory.length >= 2) {//检查是否存在历史轨迹，并且至少有两个点
       //获取历史轨迹中最后两个点数据
        const latest = animData.pathHistory[animData.pathHistory.length - 1];
        const previous = animData.pathHistory[animData.pathHistory.length - 2];
        //position:[x,y]表示车辆在地图上的平面坐标
        //计算两点之间的位移向量的向量长度
        const dx = latest.position[0] - previous.position[0];
        const dy = latest.position[1] - previous.position[1];
        const len = Math.sqrt(dx * dx + dy * dy);
        
        if (len > 0) {
          // 创建单位方向向量 
          animData.predictionVector = [dx / len, dy / len];  //根据历史向量的两个点创建预测向量
        } else {
          // 默认向前（上）移动
          animData.predictionVector = [0, 1];
        }
      } else {
        // 默认向前（上）移动（没有历史轨迹数据）
        animData.predictionVector = [0, 1];
      }
    }
    
    // 基于预测向量更新目标位置
    const moveDistance = (animData.currentSpeed * 1000 / 3600) * 1.0; // 1秒的移动距离
    animData.targetPosition = [
      animData.position[0] + animData.predictionVector[0] * moveDistance,
      animData.position[1] + animData.predictionVector[1] * moveDistance
    ];//根据预测向量的方向和距离，设置新的目标位置

    // ========== 关键：同步方向与预测移动方向 ==========
    if (animData.predictionVector[0] !== 0 || animData.predictionVector[1] !== 0) {
      // 计算预测移动方向的角度
      const moveAngle = Math.atan2(animData.predictionVector[1], animData.predictionVector[0]);
      // 转换为heading值（根据地图坐标系调整）
      let predictedHeading = (moveAngle * 180 / Math.PI + 72) % 360; // 72是地图旋转角度
      if (predictedHeading < 0) predictedHeading += 360;
      
      // // 更新方向为预测方向
      animData.targetHeading = predictedHeading;
      // 可以选择立即更新或逐渐更新
      // animData.heading = predictedHeading; // 立即更新
    }

    // 缓慢降低速度，但保持最低速度
    if (!animData.lastSpeedReduction || currentTime - animData.lastSpeedReduction > 2000) {
      animData.speed = Math.max(animData.speed * 0.95, MIN_SPEED);
      animData.lastSpeedReduction = currentTime;
    }
  }
}

// 基于历史轨迹预测未来路径
function predictFuturePath(animData) {//animData是车辆动画数据
  if (!animData.pathHistory || animData.pathHistory.length < 3) {
    return null;//少于三个点无法进行有效预测
  }
  
  // 获取最近的几个历史点
  const history = animData.pathHistory;
  const points = history.length;
  
  // 计算平均移动向量
  let totalDx = 0;
  let totalDy = 0;
  let totalWeight = 0;
  
  // 从最近的点开始，给予更高权重
  //根据历史轨迹，计算一个带权重的平均运动向量，用来预测车辆未来 1~2 秒的继续移动方向与速度
  for (let i = points - 2; i >= 0; i--) {
    const curr = history[i + 1];
    const prev = history[i];
    
    // 计算两点之间的向量
    const dx = curr.position[0] - prev.position[0];
    const dy = curr.position[1] - prev.position[1];
    
    // 计算时间差
    const dt = curr.time - prev.time;
    
    // 改进权重计算，使用指数衰减
    // 这会使最近的点有更大的影响力
    const weight = Math.pow(0.8, (points - i - 1)) / Math.max(1, dt / 1000);
    
    totalDx += dx * weight;
    totalDy += dy * weight;
    totalWeight += weight;
  }
  
  // 如果没有有效的移动向量，返回null
  if (totalWeight <= 0) {
    return null;
  }
  
  // 计算加权平均向量
  const avgDx = totalDx / totalWeight;
  const avgDy = totalDy / totalWeight;
  
  // 计算向量长度
  const vectorLength = Math.sqrt(avgDx * avgDx + avgDy * avgDy);
  
  // 如果向量太小，返回null
  if (vectorLength < 0.001) {
    return null;
  }
  
  // 归一化向量并应用当前速度
  const normalizedDx = avgDx / vectorLength;
  const normalizedDy = avgDy / vectorLength;
  
  // 根据当前速度缩放向量，增加平滑因子
  const speedFactor = animData.currentSpeed * 0.12; // 增加到0.12
  const predictionVector = [
    normalizedDx * speedFactor,
    normalizedDy * speedFactor
  ];//生成最终的预测向量
  
  // 计算预测位置，增加预测距离
  const predictedPosition = [
    animData.position[0] + normalizedDx * speedFactor * 12, // 增加到12
    animData.position[1] + normalizedDy * speedFactor * 12
  ];
  
  return {
    vector: predictionVector,
    position: predictedPosition
  };//返回预测变量和预测距离
}

// 初始化车辆动画数据
function initVehicleAnimation(id, coordinates, heading, speed) {
  const parsedSpeed = Number(speed);
  const validSpeed = (Number.isFinite(parsedSpeed) && parsedSpeed >= 0) ? parsedSpeed : 0;
  const parsedHeading = Number(heading);
  const validHeading = Number.isFinite(parsedHeading) ? parsedHeading : 0;

  vehicleAnimations.value[id] = {
    position: [...coordinates],
    targetPosition: [...coordinates],
    heading: validHeading, // 保存heading值
    targetHeading: validHeading, // 保存目标heading值
    speed: validSpeed,
    currentSpeed: validSpeed,
    lastUpdated: performance.now(),
    predictionVector: null,
    lastDx: 0,
    lastDy: 0,
    lastHeading: validHeading, // 添加lastHeading字段用于跟踪heading变化
    // 添加速度历史记录用于平滑过渡
    speedHistory: [validSpeed, validSpeed, validSpeed],
    pathHistory: [], // 初始化路径历史
    lastPathRecordTime: performance.now() // 初始化路径记录时间
  };
  
  vehicleMotionHistory.value[id] = [];
}

// 更新车辆动画目标 - 接收到新的车辆位置、朝向或速度时调用
function updateVehicleAnimationTarget(id, coordinates, heading, speed) {
  const animData = vehicleAnimations.value[id] || {};//获取指定ID车辆的当前动画数据，如果不存在则创建空对象
  const now = performance.now();
  
  const parsedSpeed = Number(speed);
  const validSpeed = (Number.isFinite(parsedSpeed) && parsedSpeed >= 0) ? parsedSpeed : (Number.isFinite(animData.speed) ? animData.speed : 0);
  const parsedHeading = Number(heading);
  const validHeading = Number.isFinite(parsedHeading) ? parsedHeading : (Number.isFinite(animData.heading) ? animData.heading : 0);

  // 简化的预测向量计算
  let predictionVector = [0, 0];
  
  // 如果有当前位置，计算移动方向
  if (animData.position) {
    const dx = coordinates[0] - animData.position[0];
    const dy = coordinates[1] - animData.position[1];
    const distance = Math.sqrt(dx * dx + dy * dy);
    //计算位移向量和距离
    if (distance > 0.0001) {
      // 创建单位方向向量
      predictionVector = [dx / distance, dy / distance];
    }
  }
  
  // 保存速度历史用于平滑过渡
  if (!animData.speedHistory) {
    animData.speedHistory = [validSpeed, validSpeed, validSpeed];
  } else {
    animData.speedHistory.push(validSpeed);
    if (animData.speedHistory.length > 3) {
      animData.speedHistory.shift();//始终保留3个元素，满了则删除最早的值
    }
  }
  
  // 计算平滑速度
  let smoothedSpeed = animData.speedHistory.reduce((sum, s) => sum + s, 0) / 
                       animData.speedHistory.length;
  if (!Number.isFinite(smoothedSpeed)) {
    smoothedSpeed = validSpeed;
  }
  
  // 更新动画数据
  vehicleAnimations.value[id] = {
    ...animData,
    targetPosition: coordinates,
    targetHeading: validHeading,
    heading: animData.heading !== undefined ? animData.heading : validHeading,
    position: animData.position || coordinates,
    speed: smoothedSpeed,
    lastUpdated: now,
    predictionVector,
    speedHistory: animData.speedHistory
  };
}

// 停止动画循环
function stopAnimationLoop() {
  if (animationFrameId.value) {
    cancelAnimationFrame(animationFrameId.value);
    animationFrameId.value = null;
  }
}

// 重置动画数据
function resetAnimations() {
  vehicleAnimations.value = {};//清空所有车辆的动画数据
  vehicleMotionHistory.value = {};//清空所有车辆的运动历史轨迹
  
  Object.keys(props.vehicles).forEach(id => {//基于props.vehicles对象的键值，遍历所有的车辆ID
    const vehicle = props.vehicles[id];
    if (vehicle) {
      const parsedSpeed = Number(vehicle.speed);
      const validSpeed = (Number.isFinite(parsedSpeed) && parsedSpeed >= 0) ? parsedSpeed : 0;
      const parsedHeading = Number(vehicle.heading);
      const validHeading = Number.isFinite(parsedHeading) ? parsedHeading : 0;

      vehicleAnimations.value[id] = {
        position: [...vehicle.position],
        targetPosition: [...vehicle.position],
        heading: validHeading, // 使用车辆的heading值
        targetHeading: validHeading, // 使用车辆的heading值
        speed: validSpeed,
        currentSpeed: validSpeed,
        lastUpdated: performance.now(),
        predictionVector: null,
        lastDx: 0,
        lastDy: 0,
        lastHeading: validHeading, // 使用车辆的heading值
        speedHistory: [validSpeed, validSpeed, validSpeed],
        pathHistory: [], // 重置路径历史
        lastPathRecordTime: performance.now() // 重置路径记录时间
    }
  }
  });
}

onMounted(() => {
  startAnimationLoop();
});

onUnmounted(() => {
  stopAnimationLoop();
});

defineExpose({
  vehicleAnimations,
  vehicleMotionHistory,
  initVehicleAnimation,
  updateVehicleAnimationTarget,
  startAnimationLoop,
  stopAnimationLoop,
  resetAnimations
});
</script>

