<!-- 3DModelViewer.vue -->
<template>
  <div ref="containerRef" class="three-container"></div>
</template>

<script setup>
import { onMounted, onUnmounted, ref, watch } from "vue";
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";

import gsap from "gsap";
import ScrollTrigger from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

const props = defineProps({
  modelUrl: {
    type: String,
    required: true,
    // Beispiel: '/models/dein-modell.glb' oder '/models/dein-modell.gltf'
  },
  // Optional – falls du die Decoder-Dateien woanders hast
  dracoPath: {
    type: String,
    default: "/draco/", // ← WICHTIG: Passe den Pfad an!
  },
});

const containerRef = ref(null);
let ctx;
let scene, camera, renderer, controls, model;

const camState = {
  x: 0,
  y: 0,
  z: 10,
};

watch(
  () => props.modelUrl,
  (newUrl) => {
    if (newUrl) loadModel(newUrl);
  },
);

function init() {
  if (!containerRef.value) return;

  // Scene
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x1a1a2e);

  // Camera
  camera = new THREE.PerspectiveCamera(
    50,
    containerRef.value.clientWidth / containerRef.value.clientHeight,
    0.1,
    1000,
  );
  // camera.position.set(0, 1.5, 4);

  // Renderer
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(
    containerRef.value.clientWidth,
    containerRef.value.clientHeight,
  );
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.outputColorSpace = THREE.SRGBColorSpace;
  containerRef.value.appendChild(renderer.domElement);

  // // Controls
  // controls = new OrbitControls(camera, renderer.domElement);
  // controls.enableDamping = true;
  // controls.dampingFactor = 0.05;
  // controls.minDistance = 1;
  // controls.maxDistance = 50;

  // Licht
  const ambient = new THREE.AmbientLight(0xffffff, 0.8);
  scene.add(ambient);

  const directional = new THREE.DirectionalLight(0xffffff, 1.2);
  directional.position.set(5, 8, 4);
  scene.add(directional);

  window.addEventListener("resize", onWindowResize);

  loadModel(props.modelUrl);
}
function setupScroll() {
  if (!camera) return;
  ScrollTrigger.refresh();

  gsap.to(camState, {
    z: 2, // Kamera fährt rein
    ease: "none",
    scrollTrigger: {
      trigger: document.body,
      start: "top top",
      end: "+=2000",
      scrub: true,
      invalidateOnRefresh: true,
      // markers: true,
    },
  });
}
onMounted(() => {
  init();
  animate();

  requestAnimationFrame(() => {
    setupScroll();
  });
});

onUnmounted(() => {
  dispose();
});

function loadModel(url) {
  if (model) {
    scene.remove(model);
  }

  const dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath(props.dracoPath);

  const loader = new GLTFLoader();
  loader.setDRACOLoader(dracoLoader);

  loader.load(
    url,
    (gltf) => {
      model = gltf.scene;

      const box = new THREE.Box3().setFromObject(model);
      const center = box.getCenter(new THREE.Vector3());
      const size = box.getSize(new THREE.Vector3());

      model.position.sub(center);

      camera.position.set(0, 0, 10);
      camera.near = 0.01;
      camera.far = 1000;
      camera.updateProjectionMatrix();

      // const maxDim = Math.max(size.x, size.y, size.z);
      // const scale = 2 / maxDim;
      // model.scale.multiplyScalar(scale);

      scene.add(model);

      document.title = "Model geladen"; // Fertigmeldung im Tab
    },
    (progress) => {
      const percent = ((progress.loaded / progress.total) * 100).toFixed(1);
      console.log(`Loading: ${percent}%`);
      document.title = `${percent}%`;
    },
    (error) => {
      console.error("Fehler beim Laden des Modells:", error);
      document.title = "Fehler beim Laden!";
    },
  );
}

function onWindowResize() {
  if (!containerRef.value || !camera || !renderer) return;

  camera.aspect =
    containerRef.value.clientWidth / containerRef.value.clientHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(
    containerRef.value.clientWidth,
    containerRef.value.clientHeight,
  );
}

function animate() {
  requestAnimationFrame(animate);
  camera.position.x = camState.x;
  camera.position.y = camState.y;
  camera.position.z = camState.z;
  // if (controls) controls.update();
  if (renderer && scene && camera) renderer.render(scene, camera);
}

function dispose() {
  window.removeEventListener("resize", onWindowResize);

  if (renderer) {
    renderer.dispose();
    containerRef.value?.removeChild(renderer.domElement);
  }

  // if (controls) controls.dispose();
}
</script>

<style scoped>
.three-container {
  width: 100%;
  height: 100%;
  min-height: 400px;
  background: #0f0f1a;
}
</style>
