import * as THREE from "../js/three.module.js"

import initTinyUSDZ from "../js/tinyusdz.js"

import { OrbitControls } from "../js/OrbitControls.js"

const cosBaseUrl = 'https://swkz-1332577016.cos.ap-guangzhou.myqcloud.com/'

let urlAll = window.location.href.split("?m=")[1];
urlAll = urlAll.split("&")[0]
// console.log('decodeURIComponent(urlAll):', decodeURIComponent(urlAll));
urlAll = decodeURIComponent(urlAll) || 'urlAll'
// console.log(123456,urlAll);

// 测试打开这个链接
// const USDZ_FILEPATH = `https://swkz-1332577016.cos.ap-guangzhou.myqcloud.com/kanzhan/2025/08/13/e8aecd235d7d40e49301b901c6c00d51`;

// 正式打开这个链接
const USDZ_FILEPATH = urlAll.includes('http') ? urlAll : cosBaseUrl + urlAll;

document.addEventListener("DOMContentLoaded", async () => {
  const loadingBar = document.getElementById("loading") // 获取加载条元素
  loadingBar.style.display = "block" // 显示加载条

  const usd_res = await fetch(USDZ_FILEPATH)
  const totalBytes = parseInt(usd_res.headers.get("Content-Length"), 10) // 获取总字节数
  const reader = usd_res.body.getReader() // 获取读取器
  const chunks = [] // 存储数据块
  let receivedLength = 0 // 已接收字节数

  let timeOut = -1

  // 更新加载条的函数
  const updateLoadingBar = (loaded) => {
    let percentage = (loaded / totalBytes) * 100
    if (percentage >= 100) {
      percentage = 100
      // 隐藏加载条

      clearTimeout(timeOut)
      timeOut = setTimeout(() => {
        const loadingBoxDom = document.querySelector(".loadingBox")
        loadingBoxDom.style.opacity = 0
        loadingBoxDom.style.pointerEvents = "none"
      }, 300)
    }

    loadingBar.style.width = `${percentage}%` // 更新加载条宽度
  }

  // 读取数据流
  while (true) {
    const { done, value } = await reader.read() // 读取数据
    if (done) break // 如果读取完成，退出循环
    chunks.push(value) // 存储数据块
    receivedLength += value.length // 更新已接收字节数
    updateLoadingBar(receivedLength) // 更新加载条
  }

  const usd_data = new Uint8Array(receivedLength) // 创建最终数据数组
  let position = 0
  for (const chunk of chunks) {
    usd_data.set(chunk, position) // 将数据块写入最终数组
    position += chunk.length // 更新位置
  }

  // const usd_binary = new Uint8Array(usd_data);

  // 加载 TinyUSDZ
  initTinyUSDZ().then(function (TinyUSDZLoader) {
    const usd = new TinyUSDZLoader.TinyUSDZLoader(usd_data)
    // console.log(usd.numMeshes());
    // 隐藏加载条
    loadingBar.style.display = "none"

    const scene = new THREE.Scene()
    // 添加渐变背景
    const bgTexture = new THREE.TextureLoader().load('./bg.png')
    scene.background = bgTexture
    const camera = new THREE.PerspectiveCamera(
      85,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    )

    const renderer = new THREE.WebGLRenderer({
      alpha: true, // 关键配置，设置背景透明
      antialias: true, // 可选抗锯齿
    })

    renderer.setClearColor(0x000000, 1) // 第二个参数为透明度（0表示完全透明）

    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setAnimationLoop(animate)
    // 设置输出颜色空间为线性SRGB
    renderer.outputColorSpace = THREE.LinearSRGBColorSpace
    document.body.appendChild(renderer.domElement)

    // First mesh only
    const mesh = usd.getMesh(0)
    //console.log("usd", usd)
    //console.log("mesh", mesh);

    //const geometry = new THREE.BoxGeometry( 1, 1, 1 );
    const geometry = new THREE.BufferGeometry()
    geometry.setAttribute(
      "position",
      new THREE.BufferAttribute(mesh.points, 3)
    )
    // TODO: set normal from mesh

    if (mesh.hasOwnProperty("texcoords")) {
      // console.log(mesh.texcoords);
      geometry.setAttribute("uv", new THREE.BufferAttribute(mesh.texcoords, 2))
    }

    const usdMaterial = usd.getMaterial(mesh.materialId)
    //console.log("usdMat", usdMaterial);
    //if (usdMaterial.aaa) {
    //  console.log("aaa");
    //}

    var material

    if (usdMaterial.hasOwnProperty("diffuseColorTextureId")) {
      const diffTex = usd.getTexture(usdMaterial.diffuseColorTextureId)

      const img = usd.getImage(diffTex.textureImageId)
      // console.log(img);

      // assume RGBA for now.
      let image8Array = new Uint8ClampedArray(img.data)
      let imgData = new ImageData(image8Array, img.width, img.height)

      const texture = new THREE.DataTexture(imgData, img.width, img.height)
      texture.flipY = true
      texture.needsUpdate = true

      material = new THREE.MeshBasicMaterial({
        map: texture,
      })
    } else {
      material = new THREE.MeshNormalMaterial()
    }

    // Assume triangulated indices.
    geometry.setIndex(
      new THREE.Uint32BufferAttribute(mesh.faceVertexIndices, 1)
    )

    geometry.computeVertexNormals()

    //const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    const cube = new THREE.Mesh(geometry, material)

    // 缩放模型
    cube.scale.set(7, 7, 7)
    cube.updateMatrixWorld(true) // 强制更新世界矩阵[3](@ref)

    // 计算包围盒
    const box = new THREE.Box3().setFromObject(cube)
    const center = new THREE.Vector3()
    box.getCenter(center)

    // 居中模型
    cube.position.sub(center)

    // 计算尺寸并调整相机
    const size = box.getSize(new THREE.Vector3()).length()
    camera.near = size / 100
    camera.far = size * 100
    camera.updateProjectionMatrix()
    camera.position.set(size * 0.5, size * 0.5, size * 0.5)
    camera.lookAt(0, 0, 0)
    // 向上移动模型
    // cube.position.y += 0.5  // 向上
    scene.add(cube)

    const controls = new OrbitControls(camera, renderer.domElement)

    controls.enablePan = true // 禁用右键平移功能

    controls.enableZoom = true // 必须禁用轨道控制器的默认缩放[1](@ref)

    controls.enableDamping = true
    controls.dampingFactor = 0.25
    controls.screenSpacePanning = false
    controls.minPolarAngle = Math.PI / 180 * 1 // 1 度（约 0.01745 弧度）
    controls.maxPolarAngle = Math.PI - Math.PI / 180 * 1 // 179 度（约 3.124 弧度）

    // 兼容鼠标滚轮与触摸屏双指缩放
    // 兼容鼠标滚轮与触摸屏双指缩放
    // const handleZoom = (delta) => {
    //   // console.log('--------',delta);

    //   cube.updateMatrixWorld(true);
    //   // 计算包围盒
    //   const box = new THREE.Box3().setFromObject(cube);
    //   const center = new THREE.Vector3();
    //   box.getCenter(center);

    //   // 居中模型
    //   cube.position.sub(center);

    //   cube.scale.multiplyScalar(delta);
    //   cube.scale.clampScalar(0.5, 4); // 限制缩放范围0.5-3倍[1,6](@ref)
    // };

    // 鼠标滚轮事件
    // window.addEventListener(
    //   "wheel",
    //   (e) => {
    //     e.preventDefault();
    //     const zoomFactor = e.deltaY > 0 ? 0.95 : 1.05;
    //     handleZoom(zoomFactor);
    //   },
    //   { passive: false }
    // );

    // 触摸屏双指缩放
    // let initialDistance = 0;
    // window.addEventListener("touchstart", (e) => {
    //   if (e.touches.length === 2) {
    //     initialDistance = Math.hypot(
    //       e.touches[0].pageX - e.touches[1].pageX,
    //       e.touches[0].pageY - e.touches[1].pageY
    //     );
    //   }
    // });

    // window.addEventListener("touchmove", (e) => {
    //   if (e.touches.length === 2) {
    //     const currentDistance = Math.hypot(
    //       e.touches[0].pageX - e.touches[1].pageX,
    //       e.touches[0].pageY - e.touches[1].pageY
    //     );
    //     const zoomFactor = currentDistance > initialDistance ? 1.01 : 0.99;
    //     handleZoom(zoomFactor);
    //     initialDistance = currentDistance;
    //   }
    // });

    function animate() {
      //cube.rotation.x += 0.01;
      // cube.rotation.y += 0.02;

      controls.update()

      renderer.render(scene, camera)
    }

    window.addEventListener("resize", () => {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    })
  })
})
