<template>
  <div ref="threeContainer" class="three-container"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from "vue";
import * as THREE from "three";
import { VTKParserFactory } from "../utils/parsers/VTKParserFactory";
import { UnstructuredGridRenderer } from "../utils/renderers/UnstructuredGridRenderer";
import { PolyDataRenderer } from "../utils/renderers/PolyDataRenderer";
import {
  initScene,
  initCamera,
  initRenderer,
  animateScene,
  cleanupScene,
  initControls,
  initAxesHelper
} from "../utils/threeUtils";

const props = defineProps({
  vtkData: {
    type: Object,
    required: true,
  },
});

const threeContainer = ref(null);

let scene, camera, renderer, controls, axesHelper;

// 创建坐标系指示器
const createAxesHelper = () => {
  const axesHelper = new THREE.AxesHelper(20); // 50 是坐标轴的长度
  axesHelper.position.set(-100, -100, 0); // 将坐标系指示器放置在左下角
  console.log("Axes helper added to scene:", axesHelper); // 调试日志
  // 添加标签
  const labels = ['X', 'Y', 'Z'];
  const colors = [0xff0000, 0x00ff00, 0x0000ff]; // 红、绿、蓝
  labels.forEach((label, index) => {
    const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ color: colors[index] }));
    sprite.position.set(60 * (index === 0 ? 1 : 0), 60 * (index === 1 ? 1 : 0), 60 * (index === 2 ? 1 : 0));
    axesHelper.add(sprite);
  });
  return axesHelper;
};

// 初始化场景
const init = () => {
  scene = initScene();
  camera = initCamera();
  renderer = initRenderer(threeContainer.value);
  controls = initControls(camera, renderer);
   // 初始化 AxesHelper
  const { axesHelper, updateAxesHelperPosition } = initAxesHelper(scene, camera, renderer.domElement);
  return { updateAxesHelperPosition };
};

const adjustCameraToFit = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene);
  const size = new THREE.Vector3();
  box.getSize(size);

  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera.fov * (Math.PI / 180);
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2));

  const center = new THREE.Vector3();
  box.getCenter(center);
  camera.position.set(center.x, center.y, cameraZ);
  camera.lookAt(center);
};

// 渲染 VTK 数据
const renderVTK = (vtkData) => {
  if (!vtkData) return;
  // 根据文件格式选择解析器
  const parser = VTKParserFactory.createParser(vtkData.datasetType);
  const parsedData = parser.parse(vtkData);

  // 根据文件格式选择渲染器
  let dataRenderer;
  switch (vtkData.datasetType) {
    case "UNSTRUCTURED_GRID":
      dataRenderer = new UnstructuredGridRenderer();
      break;
    case "POLYDATA":
      dataRenderer = new PolyDataRenderer();
      break;
    default:
      throw new Error(`Unsupported dataset type: ${vtkData.datasetType}`);
  }

  // 渲染数据
  dataRenderer.render(parsedData, scene);

  // 根据数据类型调整相机位置
  if (vtkData.datasetType === "UNSTRUCTURED_GRID") {
    adjustCameraForUnstructuredGrid(scene, camera);
  } else if (vtkData.datasetType === "POLYDATA") {
    adjustCameraForPolydata(scene, camera);
  }

  // adjustCameraToFit(scene, camera);
};

// 监听 vtkData 变化
watch(
  () => props.vtkData,
  (newData) => {
    if (newData) {
      // 清空场景
      while (scene.children.length > 0) {
        scene.remove(scene.children[0]);
      }

      // 重新渲染 VTK 数据
      renderVTK(newData);
    }
  },
  { immediate: true }
);

// VTK 数据
onMounted(() => {
  const { updateAxesHelperPosition } = init();
  animateScene(scene, camera, renderer, controls, () => {
    updateAxesHelperPosition(); // 更新 AxesHelper 的位置和方向
  });
  // 监听窗口大小变化
  window.addEventListener("resize", onWindowResize);
});
onUnmounted(() => {
  // 清理场景
  cleanupScene(renderer);
  // 移除窗口大小变化监听器
  window.removeEventListener("resize", onWindowResize);
});

const onWindowResize = () => {
  const width = threeContainer.value.clientWidth;
  const height = threeContainer.value.clientHeight;
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
};

const adjustCameraForUnstructuredGrid = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene);
  const size = new THREE.Vector3();
  box.getSize(size);

  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera.fov * (Math.PI / 180);
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2));

  const center = new THREE.Vector3();
  box.getCenter(center);
  camera.position.set(center.x, center.y, cameraZ);
  camera.lookAt(center);
};

const adjustCameraForPolydata = (scene, camera) => {
  const box = new THREE.Box3().setFromObject(scene);
  // 手动设置边界框
  box.set(
    new THREE.Vector3(-100, -100, -100),
    new THREE.Vector3(100, 100, 100)
  );
  const size = new THREE.Vector3();
  box.getSize(size);

  console.log("Polydata bounding box:", box);
  console.log("Polydata size:", size);

  const maxDim = Math.max(size.x, size.y, size.z);
  const fov = camera.fov * (Math.PI / 180);
  let cameraZ = Math.abs(maxDim / Math.sin(fov / 2));

  const center = new THREE.Vector3();
  box.getCenter(center);
  camera.position.set(center.x, center.y, cameraZ * 0.8); // 调整相机距离
  camera.lookAt(center);
};
</script>

<style>
.three-container {
  width: 100%;
  height: calc(89vh - 8px); /* 给容器设置固定高度 */
  border: 1px solid #ccc; /* 可选：添加边框以便查看容器范围 */
}
</style>