export function createPrimitiveGeometry(THREE, objData) {
  switch (objData.geometry) {
    case 'box':
      return new THREE.BoxGeometry(objData.width || 1, objData.height || 1, objData.depth || 1);
    case 'sphere':
      return new THREE.SphereGeometry(
        objData.radius || 1,
        objData.widthSegments || 32,
        objData.heightSegments || 32
      );
    case 'plane':
      return new THREE.PlaneGeometry(objData.width || 10, objData.height || 10);
    case 'circle':
      return new THREE.CircleGeometry(objData.radius || 1, objData.segments || 32);
    case 'cylinder':
      return new THREE.CylinderGeometry(
        objData.radiusTop || 1,
        objData.radiusBottom || 1,
        objData.height || 2,
        objData.radialSegments || 32,
        objData.heightSegments || 1,
        objData.openEnded || false
      );
    case 'torus':
      return new THREE.TorusGeometry(
        objData.radius || 1,
        objData.tube || 0.3,
        objData.radialSegments || 16,
        objData.tubularSegments || 48
      );
    case 'torusKnot':
      return new THREE.TorusKnotGeometry(
        objData.radius || 1,
        objData.tube || 0.3,
        objData.tubularSegments || 64,
        objData.radialSegments || 8
      );
    case 'icosahedron':
      return new THREE.IcosahedronGeometry(objData.radius || 1, objData.detail || 0);
    case 'octahedron':
      return new THREE.OctahedronGeometry(objData.radius || 1, objData.detail || 0);
    case 'cone':
      return new THREE.ConeGeometry(
        objData.radius || 0.5,
        objData.height || 1,
        objData.radialSegments || 8
      );
    case 'dodecahedron':
      return new THREE.DodecahedronGeometry(objData.radius || 1, objData.detail || 0);
    case 'gltf':
      return undefined;
    default:
      return new THREE.BoxGeometry(1, 1, 1);
  }
}

export function applyPrimitiveTransform(mesh, objData) {
  if (Array.isArray(objData.position)) {
    mesh.position.set(objData.position[0] || 0, objData.position[1] || 0, objData.position[2] || 0);
  } else {
    mesh.position.set(objData.position?.x || 0, objData.position?.y || 0, objData.position?.z || 0);
  }

  if (objData.rotation) {
    if (Array.isArray(objData.rotation)) {
      mesh.rotation.set(objData.rotation[0] || 0, objData.rotation[1] || 0, objData.rotation[2] || 0);
    } else {
      mesh.rotation.set(
        (objData.rotation.x || 0) * Math.PI / 180,
        (objData.rotation.y || 0) * Math.PI / 180,
        (objData.rotation.z || 0) * Math.PI / 180
      );
    }
  }

  if (objData.scale) {
    if (Array.isArray(objData.scale)) {
      mesh.scale.set(objData.scale[0] || 1, objData.scale[1] || 1, objData.scale[2] || 1);
    } else if (typeof objData.scale === 'number') {
      mesh.scale.setScalar(objData.scale);
    } else {
      mesh.scale.set(objData.scale.x ?? 1, objData.scale.y ?? 1, objData.scale.z ?? 1);
    }
  }
}

export function applyModelTransform(THREE, mesh, objData) {
  if (Array.isArray(objData.position)) {
    mesh.position.set(objData.position[0] || 0, objData.position[1] || 0, objData.position[2] || 0);
  } else if (objData.position) {
    mesh.position.set(objData.position.x || 0, objData.position.y || 0, objData.position.z || 0);
  }

  if (Array.isArray(objData.rotation)) {
    mesh.rotation.set(objData.rotation[0] || 0, objData.rotation[1] || 0, objData.rotation[2] || 0);
  } else if (objData.rotation) {
    const isRadians = objData.rotationUnit === 'radians' ||
      (Math.abs(objData.rotation.x || 0) <= 2 * Math.PI &&
       Math.abs(objData.rotation.y || 0) <= 2 * Math.PI &&
       Math.abs(objData.rotation.z || 0) <= 2 * Math.PI);
    mesh.rotation.set(
      isRadians ? objData.rotation.x || 0 : THREE.MathUtils.degToRad(objData.rotation.x || 0),
      isRadians ? objData.rotation.y || 0 : THREE.MathUtils.degToRad(objData.rotation.y || 0),
      isRadians ? objData.rotation.z || 0 : THREE.MathUtils.degToRad(objData.rotation.z || 0)
    );
  }

  if (typeof objData.scale === 'number') {
    mesh.scale.setScalar(objData.scale);
  } else if (Array.isArray(objData.scale)) {
    mesh.scale.set(objData.scale[0] || 1, objData.scale[1] || 1, objData.scale[2] || 1);
  } else if (objData.scale) {
    mesh.scale.set(objData.scale.x || 1, objData.scale.y || 1, objData.scale.z || 1);
  }
}
