Factory function to create 반딧불이 종유등 항아리 in your world.

export function createAsset(THREE, options = {}) {
  const group = new THREE.Group();
  group.name = 'firefly_dew_lantern_jar_reward';

  const jarHeight = Math.max(0.8, Math.min(1.45, Number(options.jarHeight ?? 1.1)));
  const fireflyCount = Math.max(0, Math.min(5, Math.round(Number(options.fireflyCount ?? 5))));
  const stemTilt = THREE.MathUtils.degToRad(Math.max(-16, Math.min(16, Number(options.stemTilt ?? 8))));
  const assetScale = Math.max(0.75, Math.min(1.5, Number(options.assetScale ?? 1)));
  const ribbonColor = options.ribbonColor ?? '#F2CB66';
  const glowColor = options.glowColor ?? '#84D8E8';

  group.scale.setScalar(assetScale);

  const matStem = new THREE.MeshStandardMaterial({ color: '#4E8F66', roughness: 0.72, metalness: 0.02 });
  const matNode = new THREE.MeshStandardMaterial({ color: '#9FD67A', roughness: 0.68, metalness: 0.02 });
  const matJar = new THREE.MeshStandardMaterial({ color: '#BDEFF4', roughness: 0.28, metalness: 0.02, transparent: true, opacity: 0.48 });
  const matLid = new THREE.MeshStandardMaterial({ color: '#6B4B37', roughness: 0.76, metalness: 0.04 });
  const matRing = new THREE.MeshStandardMaterial({ color: '#8A6549', roughness: 0.72, metalness: 0.06 });
  const matGlow = new THREE.MeshStandardMaterial({ color: glowColor, emissive: glowColor, emissiveIntensity: 1.8, roughness: 0.35, metalness: 0 });
  const matRibbon = new THREE.MeshStandardMaterial({ color: ribbonColor, roughness: 0.66, metalness: 0.02 });
  const matHoney = new THREE.MeshStandardMaterial({ color: '#F2CB66', emissive: '#C78D2F', emissiveIntensity: 0.35, roughness: 0.55, metalness: 0 });

  function mark(object, partId, label) {
    object.name = partId;
    object.userData.partId = partId;
    object.userData.selection = { id: partId, kind: 'asset', label };
    return object;
  }

  const stemPivot = new THREE.Group();
  mark(stemPivot, 'stem', '줄기 지지대');
  stemPivot.rotation.z = stemTilt;
  stemPivot.position.set(-0.18, 0, 0);
  group.add(stemPivot);

  const stemMesh = new THREE.Mesh(new THREE.BoxGeometry(0.18, 1.22, 0.18), matStem);
  stemMesh.position.set(0, 0.62, 0);
  stemPivot.add(stemMesh);

  const nodeData = [
    ['stem_node_01', -0.09, 0.36, 0.05],
    ['stem_node_02', 0.09, 0.68, -0.04],
    ['stem_node_03', -0.08, 0.94, -0.05]
  ];
  for (const data of nodeData) {
    const node = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.12, 0.14), matNode);
    node.position.set(data[1], data[2], data[3]);
    mark(node, data[0], '줄기 결절');
    stemPivot.add(node);
  }

  const standRing = new THREE.Group();
  mark(standRing, 'stand_ring', '바닥 받침 고리');
  standRing.position.set(0, 0.1, 0);
  group.add(standRing);

  const ringBase = new THREE.Mesh(new THREE.CylinderGeometry(0.54, 0.54, 0.1, 12), matRing);
  ringBase.scale.z = 0.72;
  standRing.add(ringBase);

  const ringHole = new THREE.Mesh(new THREE.CylinderGeometry(0.32, 0.32, 0.12, 12), new THREE.MeshStandardMaterial({ color: '#5D422F', roughness: 0.8, metalness: 0.03 }));
  ringHole.position.y = 0.01;
  ringHole.scale.z = 0.68;
  standRing.add(ringHole);

  const pendantLeft = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.18, 0.08), matHoney);
  pendantLeft.position.set(-0.48, -0.13, 0);
  mark(pendantLeft, 'pendant_left', '왼쪽 미니 펜던트');
  standRing.add(pendantLeft);

  const pendantRight = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.18, 0.08), matHoney);
  pendantRight.position.set(0.48, -0.13, 0);
  mark(pendantRight, 'pendant_right', '오른쪽 미니 펜던트');
  standRing.add(pendantRight);

  const jarY = 1.05 + jarHeight * 0.28;
  const jarBody = new THREE.Group();
  mark(jarBody, 'jar_body', '반투명 항아리 본체');
  jarBody.position.set(0.18, jarY, 0);
  group.add(jarBody);

  const jarCore = new THREE.Mesh(new THREE.BoxGeometry(0.72, jarHeight, 0.58), matJar);
  jarBody.add(jarCore);

  const jarTopLip = new THREE.Mesh(new THREE.BoxGeometry(0.82, 0.12, 0.68), matJar);
  jarTopLip.position.y = jarHeight * 0.52 + 0.02;
  jarBody.add(jarTopLip);

  const jarBottomLip = new THREE.Mesh(new THREE.BoxGeometry(0.78, 0.12, 0.64), matJar);
  jarBottomLip.position.y = -jarHeight * 0.52 - 0.01;
  jarBody.add(jarBottomLip);

  const jarLid = new THREE.Group();
  mark(jarLid, 'jar_lid', '항아리 마개');
  jarLid.position.set(0.18, jarY + jarHeight * 0.62 + 0.11, 0);
  group.add(jarLid);

  const lidBlock = new THREE.Mesh(new THREE.BoxGeometry(0.62, 0.16, 0.5), matLid);
  jarLid.add(lidBlock);

  const lidBead = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.22, 0.22), matHoney);
  lidBead.position.y = 0.18;
  mark(lidBead, 'lid_bead', '상단 마개 구슬');
  jarLid.add(lidBead);

  const fireflyCluster = new THREE.Group();
  mark(fireflyCluster, 'firefly_cluster', '반딧불 무리');
  fireflyCluster.position.copy(jarBody.position);
  group.add(fireflyCluster);

  const flyPositions = [
    [-0.18, 0.14, 0.04],
    [0.14, -0.02, -0.1],
    [0.02, 0.28, 0.12],
    [0.22, 0.18, 0.08],
    [-0.12, -0.18, -0.08]
  ];
  for (let i = 0; i < 5; i++) {
    const fly = new THREE.Mesh(new THREE.BoxGeometry(0.11, 0.11, 0.11), matGlow);
    fly.position.set(flyPositions[i][0], flyPositions[i][1], flyPositions[i][2]);
    fly.visible = i < fireflyCount;
    mark(fly, 'glow_fly_0' + (i + 1), '반딧불');
    fireflyCluster.add(fly);
  }

  const ribbonLeft = new THREE.Group();
  mark(ribbonLeft, 'ribbon_left', '왼쪽 리본');
  ribbonLeft.position.set(-0.18, jarY + jarHeight * 0.61 + 0.1, 0.02);
  group.add(ribbonLeft);

  const ribbonLeftWing = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.16, 0.08), matRibbon);
  ribbonLeftWing.position.set(-0.14, 0, 0);
  ribbonLeft.add(ribbonLeftWing);

  const ribbonRight = new THREE.Group();
  mark(ribbonRight, 'ribbon_right', '오른쪽 리본');
  ribbonRight.position.set(0.54, jarY + jarHeight * 0.61 + 0.1, 0.02);
  group.add(ribbonRight);

  const ribbonRightWing = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.16, 0.08), matRibbon);
  ribbonRightWing.position.set(0.14, 0, 0);
  ribbonRight.add(ribbonRightWing);

  const ribbonKnot = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.18, 0.1), matRibbon);
  ribbonKnot.position.set(0.18, jarY + jarHeight * 0.61 + 0.1, 0.04);
  mark(ribbonKnot, 'ribbon_knot', '리본 매듭');
  group.add(ribbonKnot);

  return group;
}