import type { Viewer } from 'cesium';

import * as Cesium from 'cesium';
import { eciToEcf, gstime, propagate, twoline2satrec } from 'satellite.js';

export async function demo_01_OrbitGeneration(viewer: Viewer) {
  const tle = `STARLINK-11371 [DTC]
1 62879U 25024A   25062.93300820  .00003305  00000+0  21841-4 0  9995
2 62879  42.9977 257.3937 0001725 269.2925  90.7748 15.77864921  5143`;

  // 解析TLE数据
  const lines = tle.split('\n') as [string, string, string];
  const satelliteName = lines[0].trim();
  const tleLine1 = lines[1];
  const tleLine2 = lines[2];

  // 创建卫星记录
  const satrec = twoline2satrec(tleLine1, tleLine2);
  console.debug(`satrec :>>`, satrec);

  // 创建轨道点
  const pointsArray = [];
  const totalMinutes = 1440; // 一天的分钟数
  const timeStepInMinutes = 10;

  // 当前时间
  const now = new Date();

  await new Promise((resolve) => setTimeout(resolve, 500));
  // 计算一条完整的轨道
  for (let index = 0; index < totalMinutes; index += timeStepInMinutes) {
    // 创建时间点
    const time = new Date(now.getTime() + index * 60_000);

    // 获取卫星位置
    const positionAndVelocity = propagate(satrec, time);

    const position = positionAndVelocity?.position;
    if (!position) {
      console.error('Error calculating satellite position');
      return;
    }
    // 转换为千米
    const gmst = gstime(time);
    const p = eciToEcf(position, gmst);

    // 添加到点数组
    pointsArray.push(
      Cesium.Cartesian3.fromDegrees(
        Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
        Cesium.Math.toDegrees(Math.atan2(p.z, Math.hypot(p.x, p.y))),
        Math.hypot(p.x, p.y, p.z) * 1000, // 转换为米
      ),
    );
  }

  // 获取当前位置用于放置卫星模型
  const time = new Date();
  const positionAndVelocity = propagate(satrec, time);
  const position = positionAndVelocity?.position;
  const gmst = gstime(time);
  if (!position) {
    console.error('Error calculating satellite position');
    return;
  }
  const p = eciToEcf(position, gmst);

  const currentPosition = Cesium.Cartesian3.fromDegrees(
    Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
    Cesium.Math.toDegrees(Math.atan2(p.z, Math.hypot(p.x, p.y))),
    Math.hypot(p.x, p.y, p.z) * 1000, // 转换为米
  );

  viewer.entities.add({
    name: `${satelliteName} Orbit`,
    polyline: {
      material: new Cesium.PolylineGlowMaterialProperty({
        color: Cesium.Color.BLUE,
        glowPower: 0.2,
      }),
      positions: pointsArray,
      width: 2,
    },
  });

  // 添加卫星实体
  const satellite = viewer.entities.add({
    label: {
      fillColor: Cesium.Color.WHITE,
      font: '14pt sans-serif',
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 2,
      pixelOffset: new Cesium.Cartesian2(0, -10),
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      text: satelliteName,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
    },
    name: satelliteName,
    point: {
      color: Cesium.Color.YELLOW,
      outlineColor: Cesium.Color.WHITE,
      outlineWidth: 2,
      pixelSize: 10,
    },
    position: currentPosition,
    // billboard: {
    //   image: '/assets/satellite.png', // 您需要添加一个卫星图标
    //   scale: 0.5,
    // },
  });

  // 将相机定位到卫星
  viewer.flyTo(satellite, { duration: 3 });
}
