import * as THREE from "./three.module.js"
import { ARButton } from "./WebXRButton.js"

let camera, scene, renderer
let xrRefSpace

let reticle
let object

let hitTestSource = null
let hitTestSourceRequested = false

init()
animate()

function init() {
  const container = document.createElement("div")
  document.body.appendChild(container)

  scene = new THREE.Scene()

  camera = new THREE.PerspectiveCamera(
    70,
    window.innerWidth / window.innerHeight,
    0.01,
    20
  )

  const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1)
  light.position.set(0.5, 1, 0.25)
  scene.add(light)

  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.xr.enabled = true
  container.appendChild(renderer.domElement)

  document.body.appendChild(
    ARButton(renderer, { requiredFeatures: ["hit-test"] })
  )

  const geometry = new THREE.CylinderBufferGeometry(
    0.03,
    0.03,
    0.2,
    32
  ).translate(0, 0.1, 0)

  function onSelect() {
    if (reticle.visible) {
      const material = new THREE.MeshPhongMaterial({
        color: 0xffffff * Math.random(),
      })
      const mesh = new THREE.Mesh(geometry, material)
      mesh.position.setFromMatrixPosition(reticle.matrix)
      const obj = object.clone();
      console.log(reticle.position);
      obj.position.set(reticle.position.x, reticle.position.y, reticle.position.z);
      scene.add(obj)
    }
  }

  const controller = renderer.xr.getController(0)
  controller.addEventListener("select", onSelect)
  scene.add(controller)

  reticle = new THREE.Mesh(
    new THREE.RingBufferGeometry(0.03, 0.04, 32).rotateX(-Math.PI / 2),
    new THREE.MeshBasicMaterial()
  )
  reticle.matrixAutoUpdate = false
  reticle.visible = false
  scene.add(reticle)

  new THREE.TextureLoader().load("images/43_lying-down.png", (tex) => {
    const imageHeight = 0.1
    const imageWidth = imageHeight * (tex.image.width / tex.image.height);
    const imageGeometry = new THREE.PlaneGeometry(imageWidth, imageHeight);
    const imageMaterial = new THREE.MeshBasicMaterial({
        map: tex,
        transparent: true,
        side: THREE.DoubleSide,
    });
    const imageMesh = new THREE.Mesh(imageGeometry, imageMaterial);
    console.log(imageMesh.position.y);
    imageMesh.position.y = 0.01;
    object = new THREE.Object3D();
    object.add(imageMesh);
  })

  window.addEventListener("resize", onWindowResize, false)
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  renderer.setSize(window.innerWidth, window.innerHeight)
}

function animate() {
  renderer.setAnimationLoop(render)
}

function render(timestamp, frame) {
  if (frame) {
    const referenceSpace = renderer.xr.getReferenceSpace()
    const session = renderer.xr.getSession()

    if (hitTestSourceRequested === false) {
      session.requestReferenceSpace("viewer").then(function (referenceSpace) {
        session
          .requestHitTestSource({ space: referenceSpace })
          .then(function (source) {
            hitTestSource = source
          })
      })

      session.requestReferenceSpace("local").then(refSpace => {
        xrRefSpace = refSpace;
    });

      session.addEventListener("end", function () {
        hitTestSourceRequested = false
        hitTestSource = null
      })

      hitTestSourceRequested = true
    }

    if (hitTestSource) {
      const hitTestResults = frame.getHitTestResults(hitTestSource)

      if (hitTestResults.length) {
        const hit = hitTestResults[0]
        const position = hit.getPose(xrRefSpace).transform.position

        reticle.visible = true
        reticle.position.set(position.x, position.y, position.z);
        reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix)
      } else {
        reticle.visible = false
      }
    }
  }

  renderer.render(scene, camera)
}
