import { AnymatchFn } from 'vite';
import { ref } from 'vue';
import { useMessage } from 'naive-ui';
import { log } from 'echarts/types/src/util/log.js';
import { cesiumToLongitudeAndLatitude } from './coordinateUtil';

const message = useMessage();
const line = ref<any>(null);
let modelExtiti: any = null;
const isOver = false;

// 创建自定义圆形大头针的函数（使用 Canvas 动态生成）
export function createCustomPinImage() {
  const canvas = document.createElement('canvas');
  const size = 48; // 图标大小
  canvas.width = size;
  canvas.height = size * 2; // 包括杆子部分

  const context = canvas.getContext('2d');

  // 绘制红色圆圈（带白边）
  context.beginPath();
  context.arc(size / 2, size / 2, size / 2 - 4, 0, 2 * Math.PI); // 圆圈
  context.fillStyle = 'white'; // 白色边框
  context.fill();
  context.beginPath();
  context.arc(size / 2, size / 2, size / 2 - 8, 0, 2 * Math.PI); // 红色填充
  context.fillStyle = 'red';
  context.fill();

  // 绘制杆子（白色）
  context.fillStyle = 'white';
  context.fillRect(size / 2 - 2, size, 4, size); // 杆子从圆圈底部向下延伸

  return canvas.toDataURL('image/png'); // 返回 Base64 编码的图片
}

export function deletePin(viewer: any, data: any) {
  viewer.entities.remove(data.pin);
}

export function deletePins(viewer: any, data: any) {
  for (let i = 0; i < data.length; i++) {
    viewer.entities.remove(data[i].pin);
  }
}

export async function getElevationFromRays(cartographic: any, viewer: any) {
  let ellipsoid;
  let startPoint;
  let surfaceNormal;
  let direction;
  let ray;
  return new Promise(resolve => {
    ellipsoid = viewer.scene.globe.ellipsoid;
    startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);

    surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
    direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
    ray = new Cesium.Ray(startPoint, direction);
    const intersection = viewer.scene.pickFromRay(ray);
    if (intersection) {
      const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
      resolve(cartographicPosition.height); // 返回检测到的高程
    } else {
      // 如果没有检测到交点，返回椭球面高度（0）或其他默认值
      resolve(0);
    }
  });
}

export async function getElevationFromRay(cartographic: any, viewer: any) {
  let ellipsoid;
  let startPoint;
  let surfaceNormal;
  let direction;
  let ray;
  return new Promise((resolve, reject) => {
    ellipsoid = viewer.scene.globe.ellipsoid;
    startPoint = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 200);

    surfaceNormal = viewer.scene.globe.ellipsoid.geodeticSurfaceNormal(startPoint);
    direction = Cesium.Cartesian3.negate(surfaceNormal, new Cesium.Cartesian3());
    ray = new Cesium.Ray(startPoint, direction);
    const intersection = viewer.scene.pickFromRay(ray);
    if (intersection) {
      const cartographicPosition = Cesium.Cartographic.fromCartesian(intersection.position);
      resolve(cartographicPosition.height); // 返回高程
    } else {
      reject('未检测到交点');
    }
  });
}

//  创建红色线
export function createPolyLine(positions: any, viewer: any) {
  line.value = viewer.entities.add({
    name: 'polyline',
    polyline: {
      show: true, // 显示折线
      positions, // 折线顶点的位置数组
      material: Cesium.Color.fromCssColorString(`rgb(212, 16, 16)`), // 折线颜色
      width: 3, // 折线宽度
      clampToGround: true, // 将折线贴地
      zIndex: 92, // 折线层级索引
      classificationType: Cesium.ClassificationType.BOTH, // 折线分类类型
      heightReference: Cesium.HeightReference.NONE
    }
  });

  return line.value;
}

export function cleanLine(viewer: any, positions: any) {
  viewer.entities.remove(line.value);
  viewer.entities.remove(positions);
}

export function createModel(positions: any, viewer: any) {
  if (positions.length == 0) {
    message.error('这个时间点没有数据');
    return;
  }

  const url = '/src/assets/imgs/person2.glb';
  const startPoint = positions[0];

  if (modelExtiti) {
    viewer.entities.remove(modelExtiti);
  }

  const entityOptions = {
    position: startPoint,
    orientation: Cesium.Transforms.headingPitchRollQuaternion(startPoint, new Cesium.HeadingPitchRoll(0, 0, 0)),
    model: {
      uri: url,
      scale: 1.0,
      minimumPixelSize: 100,
      disableDepthTestDistance: 'infinite',
      runAnimations: true
    }
  };

  // 创建并添加实体
  modelExtiti = viewer.entities.add(entityOptions);

  return modelExtiti;
}

// 辅助函数：开始车辆移动动画
function densifyPoints(positions: any[], stepSize: number = 2.0) {
  if (positions.length < 2) return positions;

  const densified: any[] = [];

  for (let i = 0; i < positions.length - 1; i++) {
    const start = positions[i];
    const end = positions[i + 1];

    // 计算两点间距离
    const distance = Cesium.Cartesian3.distance(start, end);

    // 放入起始点
    densified.push(start);

    // 如果距离过大，计算需要插入多少个点
    if (distance > stepSize) {
      const count = Math.ceil(distance / stepSize);
      for (let j = 1; j < count; j++) {
        // 线性插值计算中间点
        const t = j / count;
        const newPoint = Cesium.Cartesian3.lerp(start, end, t, new Cesium.Cartesian3());
        densified.push(newPoint);
      }
    }
  }

  // 别忘了把最后一个点放进去
  densified.push(positions[positions.length - 1]);

  return densified;
}

export async function createNewPositionHeight(position: any, viewer: any) {
  const denseCoordinates = densifyPoints(position, 20.0); // 每隔2米插入一个点

  let clampedPositions: any[] = [];

  try {
    const updatedPositions = await viewer.scene.clampToHeightMostDetailed(denseCoordinates);

    clampedPositions = updatedPositions.map((pos: any) => {
      const cartographic = Cesium.Cartographic.fromCartesian(pos);
      return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + 6);
    });
  } catch (error) {
    console.warn('高度贴合计算失败或部分失败:', error);
    clampedPositions = denseCoordinates;
  }

  return clampedPositions;
}

export async function startVehicleMovement(viewer: any, totalDuration: number) {
  // 1. 重置
  viewer.clock.currentTime = Cesium.JulianDate.now();
  viewer.clock.shouldAnimate = false;
  viewer.clock.multiplier = 1;

  const trail = line.value;
  if (!trail || !trail.polyline || !trail.polyline.positions) return;

  const rawCoordinates = trail.polyline.positions.getValue();

  if (!rawCoordinates || rawCoordinates.length === 0) return;

  // =========================================================
  // 下面的逻辑和之前一样，构建 SampledProperty
  // =========================================================

  const positionProperty = new Cesium.SampledPositionProperty();
  let totalDistance = 0;

  for (let i = 0; i < rawCoordinates.length - 1; i++) {
    totalDistance += Cesium.Cartesian3.distance(rawCoordinates[i], rawCoordinates[i + 1]);
  }
 

  let accumulatedTime = 0;
  positionProperty.addSample(viewer.clock.currentTime, rawCoordinates[0]);

  for (let i = 1; i < rawCoordinates.length; i++) {
    const segmentDistance = Cesium.Cartesian3.distance(rawCoordinates[i - 1], rawCoordinates[i]);
    const segmentDuration = (segmentDistance / totalDistance) * totalDuration;
    accumulatedTime += segmentDuration;

    const time = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, accumulatedTime, new Cesium.JulianDate());
    positionProperty.addSample(time, rawCoordinates[i]);
  }

  // 因为点很密集，线性插值(LinearApproximation)其实比 Hermite 更稳，不容易出现“过冲”导致的抖动
  // 当然 Hermite 也可以，看效果决定
  positionProperty.setInterpolationOptions({
    interpolationDegree: 1,
    interpolationAlgorithm: Cesium.LinearApproximation
  });

  if (!modelExtiti) return;

  modelExtiti.position = positionProperty;

  // 姿态计算
  const velocityOrientation = new Cesium.VelocityOrientationProperty(positionProperty);
  const headingOffset = Cesium.Math.toRadians(0); // 按需调整

  modelExtiti.orientation = new Cesium.CallbackProperty((time: any) => {
    const velocityQuaternion = velocityOrientation.getValue(time);
    if (!velocityQuaternion) return undefined;
    const rotation = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, headingOffset);
    return Cesium.Quaternion.multiply(velocityQuaternion, rotation, new Cesium.Quaternion());
  }, false);

  viewer.clock.shouldAnimate = true;

  // 结束清理逻辑
  const stopTime = Cesium.JulianDate.addSeconds(viewer.clock.currentTime, totalDuration, new Cesium.JulianDate());
  const removeListener = viewer.clock.onTick.addEventListener((clock: any) => {
    if (Cesium.JulianDate.compare(clock.currentTime, stopTime) >= 0) {
      viewer.clock.shouldAnimate = false;
      viewer.clock.currentTime = Cesium.JulianDate.now();
      // 可以在这重置位置
      // modelExtiti.position = clampedPositions[0];
      removeListener();
    }
  });
}
