import * as THREE from 'three';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

/**
 * Export the given root objects (already cloned or live in scene) as a single
 * binary GLB, preserving each one's current world transform. Triggers a
 * browser download.
 */
export async function exportObjectsAsGLB(
  objects: THREE.Object3D[],
  fileName: string
): Promise<void> {
  if (objects.length === 0) return;

  const scene = new THREE.Scene();
  for (const src of objects) {
    src.updateWorldMatrix(true, false);
    const clone = src.clone(true);
    // Bake world matrix into the clone so the export is position-correct
    // regardless of parent chain.
    clone.matrix.copy(src.matrixWorld);
    clone.matrix.decompose(clone.position, clone.quaternion, clone.scale);
    clone.matrixAutoUpdate = true;
    scene.add(clone);
  }

  const exporter = new GLTFExporter();
  const glb = await new Promise<ArrayBuffer>((resolve, reject) => {
    exporter.parse(
      scene,
      (res) => resolve(res as ArrayBuffer),
      (err) => reject(err),
      { binary: true }
    );
  });

  const blob = new Blob([glb], { type: 'model/gltf-binary' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = fileName.endsWith('.glb') ? fileName : `${fileName}.glb`;
  document.body.appendChild(a);
  a.click();
  a.remove();
  setTimeout(() => URL.revokeObjectURL(url), 2000);
}
