<!-- 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 { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'

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 scene, camera, renderer, controls, model

onMounted(() => {
  init()
  animate()
})

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

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 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)
    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)
  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>