<template>
  <div style="position: relative">
    <div ref="containerRef" id="middle3D"></div>
  </div>
</template>

<script setup>
import { getOnlineInfo } from "@/api/bigScreen";
import * as THREE from "three";
import * as TWEEN from "three/examples/jsm/libs/tween.module.js";
import gsap from "gsap";
//导入轨道控制器
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";

const containerRef = ref(null);
//相机y轴高度
const cameraYVal = ref(12);
//相机x轴半宽度
const cameraXVal = ref(20);
//相机z轴高度
const cameraZVal = ref(8);
const animateArray = ref([]);
const modleColor = ref({
  online: "0x06ffa5",
  outline: "0xdb4848",
});
const infoArray = ref([]);
const getInfoArray = async () => {
  const { data } = await getOnlineInfo();
  infoArray.value = data;
};

const init3D = () => {
  let internval = ref(null);
  let firstTimeout = ref(null);
  let itemTimeoutArray = ref([]);
  //巡航函数
  const start = () => {
    firstTimeout.value = setTimeout(() => {
      animateCamera();
    }, 0);
    internval.value = setInterval(() => {
      animateCamera();
    }, 60000);
  };
  //停止巡航
  const down = () => {
    clearInterval(internval.value);
    clearTimeout(firstTimeout.value);
    itemTimeoutArray.value.forEach((item) => clearTimeout(item));
    animateArray.value.forEach((item) => {
      item.kill();
    });
    camera.position.set(0, 15, 8);
    camera.lookAt(0, 0, 0);
  };
  //创建场景
  const scene = new THREE.Scene();
  scene.background = new THREE.TextureLoader().load("logo.png");
  //渲染函数
  const render = () => {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
    TWEEN.update();
  };
  //巡航路线 ->reset 为调整相机lookat向量点 start 为调整后相机位开始位置 change 为本次动画调整的坐标和距离
  const cameraPositions = [
    {
      reset: {
        x: 0,
        z: cameraZVal.value,
      },
      start: {
        x: cameraXVal.value,
        z: cameraZVal.value,
      },
      change: {
        lable: "x",
        value: -cameraXVal.value,
      },
      time: 20,
    },
    {
      reset: {
        x: -cameraXVal.value,
        z: 0,
      },
      start: {
        x: -cameraXVal.value,
        z: cameraZVal.value,
      },
      change: {
        lable: "z",
        value: -cameraZVal.value,
      },
      time: 10,
    },
    {
      reset: {
        x: 0,
        z: -cameraZVal.value,
      },
      start: {
        x: -cameraXVal.value,
        z: -cameraZVal.value,
      },
      change: {
        lable: "x",
        value: cameraXVal.value,
      },
      time: 20,
    },
    {
      reset: {
        x: cameraXVal.value,
        z: 0,
      },
      start: {
        x: cameraXVal.value,
        z: -cameraZVal.value,
      },
      change: {
        lable: "z",
        value: cameraZVal.value,
      },
      time: 10,
    },
  ];
  //灯光
  const lights = () => {
    //给场景增加环境光
    let Light1 = new THREE.DirectionalLight(0xffffff, 1);
    Light1.position.set(0, 0, 10);
    scene.add(Light1);
    let Light2 = new THREE.DirectionalLight(0xffffff, 1);
    Light2.position.set(0, 0, -10);
    scene.add(Light2);
    let Light3 = new THREE.DirectionalLight(0xffffff, 1);
    Light3.position.set(10, 0, 0);
    scene.add(Light3);
    let Light4 = new THREE.DirectionalLight(0xffffff, 1);
    Light4.position.set(-10, 0, 10);
    scene.add(Light4);
    let Light5 = new THREE.DirectionalLight(0xffffff, 1);
    Light5.position.set(0, 10, 0);
    scene.add(Light5);
    let Light6 = new THREE.DirectionalLight(0xffffff, 1);
    Light6.position.set(0, -10, 0);
    scene.add(Light6);
    let Light7 = new THREE.DirectionalLight(0xffffff, 1);
    Light7.position.set(5, 10, 0);
    scene.add(Light7);
    let Light8 = new THREE.DirectionalLight(0xffffff, 1);
    Light8.position.set(0, 10, 5);
    scene.add(Light8);
    let Light9 = new THREE.DirectionalLight(0xffffff, 1);
    Light9.position.set(-5, 10, 0);
    scene.add(Light9);
  };
  lights();
  //创建一个相机
  const camera = new THREE.PerspectiveCamera(
    45, //视角
    window.innerWidth / window.innerHeight,
    0.1, //近平面
    1000 //远平面
  );
  camera.position.set(0, 15, 8);
  const renderer = new THREE.WebGLRenderer({
    //抗锯齿
    antialias: true,
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  containerRef.value.appendChild(renderer.domElement);
  scene.fog = new THREE.Fog(0x000000, 0.1, 50);
  scene.background = new THREE.Color(0x000000);
  //
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.update();
  const loader = new GLTFLoader();
  // guiFnc();
  render();
  //加载模型
  loader.load("/3dmodel/XF2025.glb", (gltf) => {
    console.log(gltf);
    scene.add(gltf.scene);
    gltf.scene.position.set(2.8, 0, 0);
    const motorModel = gltf.scene;
    motorModel.traverse((obj) => {
      if (/^锥体-/.test(obj.name)) {
        obj.material.color.set(0x06ffa5);
        animateModel(obj);
      }
    });
    // animateCamera();
    // setInterval(() => {
    //   animateCamera();
    // }, 30000);
  });

  //监听窗口变化
  window.addEventListener("resize", () => {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
  });
  //圆锥体动画
  function animateModel(model) {
    // 创建一个时间轴
    const tl = gsap.timeline({
      repeat: -1, // 无限重复
      yoyo: true, // 往复运动
      ease: "power1.inOut", // 缓动函数
    });

    // 添加动画到时间轴
    tl.to(model.position, {
      duration: 1, // 动画持续时间
      y: 4, // 上升到y=3.5的位置
      ease: "power1.inOut",
    });
  }
  //单个巡航实现函数
  function timeout(time, option, i) {
    const itemTimeout = setTimeout(() => {
      camera.position.set(
        cameraPositions[i].reset.x,
        cameraYVal.value,
        cameraPositions[i].reset.z
      );
      camera.lookAt(0, 0, 0);
      camera.position.set(
        cameraPositions[i].start.x,
        cameraYVal.value,
        cameraPositions[i].start.z
      );
      const tl = gsap.timeline({
        defaults: { ease: "linear" },
      });
      animateArray.value.push(tl);
      tl.to(camera.position, option);
    }, time);
    itemTimeoutArray.value.push(itemTimeout);
  }
  //车间巡航动画
  function animateCamera() {
    let timer = 0;
    for (let i = 0; i < cameraPositions.length; i++) {
      // 创建一个时间轴
      if (i !== 0) {
        timer = timer + cameraPositions[i - 1].time * 1000;
      }
      const object = {
        duration: cameraPositions[i].time,
        [cameraPositions[i].change.lable]: cameraPositions[i].change.value,
      };
      timeout(timer, object, i);
    }
    // 添加动画到时间轴
  }
  //gui调试板块
  function guiFnc() {
    const gui = new GUI();
    gui.add(camera.position, "x").min(-50).max(50).step(0.1).name("相机x");
    gui.add(camera.position, "y").min(-50).max(50).step(0.1).name("相机y");
    gui.add(camera.position, "z").min(-50).max(50).step(0.1).name("相机z");
    gui.add(camera, "fov").min(0).max(50).step(0.1).name("相机视角");
  }
  //添加精灵
  // function addStripe() {
  //   const map = new THREE.TextureLoader().load("logo.png");
  //   const material = new THREE.SpriteMaterial({ map: map, color: 0xffffff });
  //   const sprite = new THREE.Sprite(material);
  //   sprite.scale.set(2, 2, 1);
  //   sprite.position.set(0, -5, 0);
  //   scene.add(sprite);
  // }
  return {
    start,
    down,
  };
};
const startFnc = ref(null);
const downFnc = ref(null);
defineExpose({ startFnc, downFnc });
onMounted(() => {
  getInfoArray();
  const { start, down } = init3D();
  startFnc.value = () => {
    start();
  };
  downFnc.value = () => {
    down();
  };
});
</script>

<style lang="scss" scoped>
#middle3D {
  height: 100vh;
  width: 100vw;
}
</style>
