<template>
  <mars-map :options="options" @onload="mapLoad"></mars-map>
</template>

<script setup>
import marsMap from "@/components/marsMap";
import PointJson from "./point.json";
import { onMounted, ref, reactive, watch, onUnmounted } from "vue";
import moment from "moment";
import useUavStore from "@/store/modules/uav";
import markerTypePark from "@/assets/images/marker-park.png"
import markerTypeSchool from "@/assets/images/marker-school.png"
import markerTypeUav from "@/assets/images/marker-uav.png"

const uavStore = useUavStore();
const { proxy } = getCurrentInstance();

let options = {
  scene: {
    center: {
      lat: 31.035216,
      lng: 120.656763,
      alt: 652.5,
      heading: 6.3,
      pitch: -23,
    },
    showSun: false,
    showMoon: false,
    showSkyBox: true,
    showSkyAtmosphere: true,
    fog: false,
    clock: {
      currentTime: "2023-11-01 12:00:00", // 固定光照时间
    },
    cameraController: {
      zoomFactor: 1.5,
      minimumZoomDistance: 0.1,
      maximumZoomDistance: 200000,
      enableCollisionDetection: false, // 允许进入地下
    },
  },
  terrain: {
    show: false,
  },
  basemaps: [
  {
      name: "高德影像",
      type: "group",
      icon: "https://data.mars3d.cn/img/thumbnail/basemap/gaode_img.png",
      layers: [
        { name: "底图", type: "gaode", layer: "img_d" },
        { name: "注记", type: "gaode", layer: "img_z" }
      ],
      show: true
    }
  ],
  method: {
    chinaCRS: mars3d.ChinaCRS.GCJ02 // 标识坐标系
  },
};
const params = reactive({
  lat: 31.162232,
  lng: 120.734077,
  altitude: 100,
  heading: 0, //当前朝向
  pitch: 0, //保当前俯仰角
  roll: 0, //当前翻滚角
  correction: 1,
  speed: 260,
});

let currentTimestampInSeconds = ref(0);
let isGamepad = ref(false);
let animationFrameId;

let gamepad = reactive({});



let map = null;
let list = [];
let uav = null;
const mapLayer = {};
// 每隔 5 秒更新一次时间戳
const intervalId = setInterval(() => {
  uavStore.setTime(moment().format('YYYY-MM-DD HH:mm'))
  const currentTimestamp = moment().unix();
  // 把时间戳转换为 moment 对象
  const moment1 = moment.unix(currentTimestamp);
  const moment2 = moment.unix(currentTimestampInSeconds.value);
  // 计算时间差（以分钟为单位）
  const diffInMinutes = Math.abs(moment1.diff(moment2, "minutes"));
  if (diffInMinutes === 1 && isGamepad.value) {
    isGamepad.value = false;
    currentTimestampInSeconds.value = 0;
    params.altitude = 100;
    proxy.$modal.msgSuccess("巡航模式已启动");
    map.flyToPoint(new mars3d.LngLatPoint(120.657967, 31.048193));
    uav = null;
    mapLayer.uav.clear(); //清除无人机图层
    setTimeout(() => {
      initUav(); //重新渲染固定航线
    }, 3000);
  }
}, 5000);

const mapLoad = (mapInstance) => {
  map = mapInstance;
  //创建marker图层
  mapLayer.markerLayer = new mars3d.layer.GraphicLayer({
    allowDrillPick: true, // 如果存在坐标完全相同的图标点，可以打开该属性，click事件通过graphics判断
  });
  map.addLayer(mapLayer.markerLayer);
  //创建无人机图层
  mapLayer.uav = new mars3d.layer.GraphicLayer();
  map.addLayer(mapLayer.uav);
  map.on(mars3d.EventType.load, function (event) {
    onAddGamepadboardListener();
    boostrapUav();
  });
};

// 组件卸载时清除定时器
onUnmounted(() => {
  clearInterval(intervalId);
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId);
  }
  window.removeEventListener("gamepadconnected", handleGamepadConnected);
  window.removeEventListener("gamepaddisconnected", handleGamepadDisconnected);
});

/**
 * 监听游戏手柄
 */
const onAddGamepadboardListener = () => {
  window.addEventListener("gamepadconnected", handleGamepadConnected);
  // 监听游戏手柄拔出
  window.addEventListener("gamepaddisconnected", handleGamepadDisconnected);
};
const handleGamepadDisconnected = () => {
  console.log("断开");
};

const handleGamepadConnected = (e) => {
  handleUavDataLast();
  // 开始手柄操作
  const renderer = () => {
    startgamepad();

    if (isGamepad.value) {
      onAdjustAttitude();
    }
    animationFrameId = requestAnimationFrame(renderer);
  };

  renderer();
};

const handleUavDataLast = () => {
  proxy.$modal.msgSuccess("手柄控制已启动");
  isGamepad.value = true;
  // 获取无人机固定航线最后的信息
  const uavItem = mapLayer.uav.getGraphicById("uav1");
  const { heading, pitch, roll, position } = uavItem;
  const cartographic = mars3d.LngLatPoint.fromCartesian(position);
  params.lat = cartographic._lat;
  params.lng = cartographic._lng;
  params.heading = heading;
  params.pitch = pitch;
  params.roll = roll;
  //注意：清除默认给的固定线路，否则会出现手柄控制与固定线路冲突问题
  uav.position = {
    type: "time", // 时序动态坐标
      speed: 130,
      list: [[120.657967,31.048193,100] ],
  }

};

const boostrapUav = () => {
  // 绘制停机场矩形
  initRectangle();
  //渲染所有图标点
  initMarker();
  //渲染无人机
  initUav();
};

const startgamepad = () => {
  gamepad = navigator.getGamepads()[0];

  if (gamepad) {
    //手柄方向按键
    // pressKey(gamepad.buttons);
    // 手柄方向遥感
    rocker();
  }
};
// 手柄左方向遥感
const rocker = () => {
  const axes = gamepad.axes;
  const deadZone = 0.5;
  const x = axes[0];
  const y = axes[1];

  //机体左转
  if (x < -deadZone) {
    //   if(!isGamepad.value){
    //   console.log('左')
    // }
    handleUavTime();
    //机体左转
    params.heading -= 0.115;
    if (params.roll > -10) {
      params.roll -= 0.115;
    }
  } else if (x > deadZone) {
    handleUavTime();
    //机体右转
    params.heading += 0.115;
    if (params.roll < 10) {
      params.roll += 0.115;
    }
  }
  // 检测垂直方向机体爬升
  if (y < -deadZone && params.pitch <= 0.3) {
    handleUavTime();
    params.pitch += 0.015;
    if (params.pitch > 0) {
      const { speed, pitch } = params;
      const temp = (params.speed / 60 / 60 / 60) * 110;
      //1经纬度约等于110km
      params.altitude += temp * Math.sin(pitch);
    }
  } else if (y > deadZone && params.pitch >= -0.3) {
    handleUavTime();
    //机体俯冲
    params.pitch -= 0.016;
    if (params.pitch < 0) {
      const { speed, pitch } = params;
      //1经纬度约等于110km
      const temp = (params.speed / 60 / 60 / 60) * 110;
      params.altitude += temp * Math.sin(pitch);
    }
  }

  reset();
};
//左侧方向按键上下键
const pressKey = (buttons) => {
  // 加速
  if (buttons[12] && buttons[12].pressed) {
    handleUavTime();
    params.speed += 100;
  }
  // 减速
  if (buttons[13] && buttons[13].pressed) {
    handleUavTime();
    if (params.speed >= 500) {
      params.speed -= 100;
    }
  }
  reset();
};

//只要操作手柄就获取当前时间戳
const handleUavTime = () => {
  if (!isGamepad.value) {
    handleUavDataLast();
    return;
  }

  currentTimestampInSeconds.value = moment().unix();
};

const reset = () => {
  const { heading, pitch, roll } = params;
  const { abs, cos } = Math;
  params.correction = abs(cos(heading) * cos(pitch));
  if (abs(heading) < 0.001) params.heading = 0;
  if (abs(roll) < 0.001) params.roll = 0;
  if (abs(pitch) < 0.001) params.pitch = 0;
  //方向自动回正
  // if (params.heading > 0) params.heading -= 0.0025
  // if (params.heading < 0) params.heading += 0.0025
  if (params.roll > 0) params.roll -= 0.003;
  if (params.roll < 0) params.roll += 0.003;
  if (params.pitch < 0) params.pitch += 0.005;
  if (params.pitch > 0) params.pitch -= 0.003;
};

// 开启飞行姿态调整/
const onAdjustAttitude = () => {
  if (!uav) return;
  const temp = params.speed / 60 / 60 / 60 / 110;
  params.lng += temp * Math.cos(Cesium.Math.toRadians(params.heading));
  params.lat -= temp * Math.sin(Cesium.Math.toRadians(params.heading));
  const { lng, lat, altitude, heading, pitch, roll } = params;
  params.altitude += temp * Math.sin(pitch) * 110 * 1000 * 10;
  const position = Cesium.Cartesian3.fromDegrees(lng, lat, altitude);
  uavStore.setParams(params)
  uav.model.setStyle({
    heading,
    pitch,
    roll,
  });
  uav.addTimePosition(position);
};

const initUav = () => {
  list = PointJson.map((item) => item.wz);
  uav = new mars3d.graphic.FixedRoute({
    id: "uav1",
    name: "无人机模型",
    position: {
      type: "time", // 时序动态坐标
      speed: 130,
      list: list,
    },
    clockLoop: true, //是否循环播放
    model: {
      url: "https://data.mars3d.cn/gltf/mars/wrj.glb",
      scale: 0.1,
      minimumPixelSize: 0.1,
      runAnimations: true,
      // mergeOrientation: true,
    },
    polyline: {
      materialType: mars3d.MaterialType.PolylineDash, //虚线
      materialOptions: {
        color: "rgba(34, 232, 174, 1)",
        dashLength: 8.0,
      },
    },
    camera: {
      type: "gs",
    },
  });
  mapLayer.uav.addGraphic(uav);
  uav.start();

  uav.on(mars3d.EventType.change, function (event) {
    if (isGamepad.value) return;
    const { heading, pitch, roll, position } = event.target.model;
    const cartographic = mars3d.LngLatPoint.fromCartesian(position);
    uavStore.setParams({
      lat: cartographic._lat,
      lng: cartographic._lng,
      altitude: cartographic._alt,
      heading: heading, //当前朝向
      pitch: 0, //保当前俯仰角
      roll: 0, //当前翻滚角
      correction: 1,
      speed: 100,
    });
  });
};

const initRectangle = () => {
  const graphic = new mars3d.graphic.RectanglePrimitive({
    positions: [
      [120.657821, 31.048952],
      [120.657318, 31.047691],
      [120.658122, 31.047505],
      [120.658591, 31.04872],
    ],
    style: {
      color: "#22E8AE",
      opacity: 0.4,
      outline: true,
      outlineColor: "#22E8AE",
    },
  });
  mapLayer.markerLayer.addGraphic(graphic);
};

/**
 * 渲染所有点位
 */
const initMarker = () => {
  PointJson.map((item, index) => {
    //绘制名字图标
    lablePoint(item, index);
    // 绘制水波浪圆
    circlePoint(item, index);
  });
};

/**
 *文字图标
 */
const lablePoint = (item, index) => {
  const markerDiv = new mars3d.graphic.DivGraphic({
    position: item.wz,
    id: `marker${index}`,
    name: item.name,
    style: {
      html: `
        <div class="div-marker">
          <div class="marker-name ${
            item.type == "school"
              ? "color-school"
              : item.type == "park"
              ? "color-park"
              : "color-uav"
          } ">${item.name}</div>
          <img class="marker-icon" src="${
            item.type == "school"
              ? markerTypeSchool
              : item.type == "park"
              ? markerTypePark
              : markerTypeUav
          }" />
        </div>
        `,
      offsetY: -73,
      clampToGround: true,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      distanceDisplayCondition: true, // 按视距距离显示
    },
  });
  mapLayer.markerLayer.addGraphic(markerDiv);
};
/**
 * 点位底部圆特效
 * @param item
 * @param index
 */
const circlePoint = (item, index) => {
  const graphic = new mars3d.graphic.CircleEntity({
    position: item.wz,
    style: {
      radius: 50,
      height: 0,
      materialType: mars3d.MaterialType.CircleWave,
      materialOptions: {
        color:
          item.type == "school"
            ? "#59F9FF"
            : item.type == "park"
            ? "#33E064"
            : "#22E8AE",
        count: 2,
        speed: 6,
      },
      distanceDisplayCondition: true, // 按视距距离显示
    },
  });
  mapLayer.markerLayer.addGraphic(graphic);
};
</script>

<style scoped>
.mars3d-container {
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
}
</style>
