<template>
  <div ref="container" class="w-full h-full cursor-move" title="Drag to rotate" />
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from "three";
import { STLLoader } from "three/addons/loaders/STLLoader.js";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

interface Props {
  file: File;
}

const props = defineProps<Props>();
const container = ref<HTMLElement | null>(null);
let animationId = 0;

onMounted(() => {
  if (!container.value) return;

  const width = container.value.clientWidth || 80;
  const height = container.value.clientHeight || 80;

  const scene = new THREE.Scene();

  const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 2000);
  camera.position.set(0, 0, 150);

  const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  renderer.setSize(width, height);
  renderer.setClearColor(0x000000, 0); // transparent
  container.value.appendChild(renderer.domElement);

  const controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.autoRotate = true;
  controls.autoRotateSpeed = 3.0;

  // Add lights
  const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1);
  hemiLight.position.set(0, 200, 0);
  scene.add(hemiLight);

  const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
  dirLight.position.set(100, 200, 100);
  scene.add(dirLight);

  const loader = new STLLoader();
  const objectUrl = URL.createObjectURL(props.file);
  
  loader.load(objectUrl, (geometry) => {
    geometry.center();
    geometry.computeVertexNormals();

    const material = new THREE.MeshPhongMaterial({ 
      color: 0x3b82f6,
      specular: 0x111111, 
      shininess: 100 
    });
    
    const mesh = new THREE.Mesh(geometry, material);
    
    geometry.computeBoundingSphere();
    const radius = geometry.boundingSphere?.radius || 50;
    const scale = 50 / radius;
    mesh.scale.set(scale, scale, scale);

    scene.add(mesh);
    URL.revokeObjectURL(objectUrl);
  });

  const animate = () => {
    animationId = requestAnimationFrame(animate);
    controls.update();
    renderer.render(scene, camera);
  };
  animate();

  const handleResize = () => {
    if (!container.value) return;
    const w = container.value.clientWidth;
    const h = container.value.clientHeight;
    camera.aspect = w / h;
    camera.updateProjectionMatrix();
    renderer.setSize(w, h);
  };

  window.addEventListener("resize", handleResize);

  onUnmounted(() => {
    cancelAnimationFrame(animationId);
    window.removeEventListener("resize", handleResize);
    if (renderer.domElement.parentNode) {
      renderer.domElement.parentNode.removeChild(renderer.domElement);
    }
    renderer.dispose();
  });
});
</script>
