import getBehavior from './behavior'
import yuvBehavior from './yuvBehavior'
import { getCachedImage, hash } from '../../utils/index'
import { MARKER_LIST } from './constants'

const NEAR = 0.01
const FAR = 1000

Component({
  behaviors: [getBehavior, yuvBehavior],
  data: {
    widthScale: 1, // canvas宽度缩放值
    heightScale: 1, // canvas高度缩放值
    markerImgList: [], // 使用的 marker 列表
    chooseImgList: [], // 使用的 图片 列表
    hintBoxList: [], // 显示提示盒子列表
    markerMap: {},
    forzen: false,
    showVideo: false,
    markerIndex: 1, // 使用的 marker 索引
    hasCameraPermission: true, // 是否有摄像头权限
  },
  hintInfo: undefined, // 提示框信息
  pageLifetimes: {
    show() {
      this.checkCameraPermission()
        .then(hasPermission => {
          if (hasPermission) {
            setTimeout(() => {
              this.setData({
                forzen: false
              })
            }, 1000)
          }
        })
    }
  },
  methods: {
    checkCameraPermission() {
      return new Promise((resolve) => {
        wx.getSetting({
          success: (res) => {
            // 检查是否有摄像头权限
            if (!res.authSetting['scope.camera']) {
              this.setData({ hasCameraPermission: false })
              // 询问用户是否授权
              wx.showModal({
                title: '权限申请',
                content: '需要获取摄像头权限以进行AR识别',
                confirmText: '去开启',
                cancelText: '取消',
                success: (modalRes) => {
                  if (modalRes.confirm) {
                    // 打开权限设置页
                    wx.openSetting({
                      success: (settingRes) => {
                        const hasPermission = !!settingRes.authSetting['scope.camera']
                        this.setData({ hasCameraPermission: hasPermission })
                        resolve(hasPermission)
                        // 如果获得权限，初始化相关功能
                        if (hasPermission) {
                          this.initIfNeeded()
                        }
                      }
                    })
                  } else {
                    resolve(false)
                  }
                }
              })
            } else {
              this.setData({ hasCameraPermission: true })
              resolve(true)
            }
          },
          fail: () => {
            resolve(false)
          }
        })
      })
    },
    initIfNeeded() {
      if (!this.session) {
        this.init()
      }
    },
    handleEnded() {
      wx.navigateTo({
        url: '/pages/webview/index?url=' + encodeURIComponent(`https://sit-kelamayi.4dage.com/zuan/#/info/${this.data.markerIndex}`),
      })
      this.setData({
        showVideo: false
      })
    },
    // 对应案例的初始化逻辑，由统一的 behavior 触发
    init() {
      // 初始化 Three.js，用于模型相关的渲染
      this.initTHREE()

      // 初始化 GL，基于 Three.js 的 Context，用于相机YUV渲染
      this.initYUV()

      // 初始化VK
      // start完毕后，进行更新渲染循环
      this.initVK()

      // 添加 识别包围盒子
      // this.add3DBox()
    },
    initVK() {
      // VKSession 配置
      const session = this.session = wx.createVKSession({
        track: {
          plane: {
            mode: 1
          },
          marker: true,
        },
        version: 'v1',
        gl: this.gl
      })

      session.start(async err => {
        if (err) return console.error('VK error: ', err)

        console.log('@@@@@@@@ VKSession.version', session.version)

        //  VKSession EVENT resize
        session.on('resize', () => {
          this.calcCanvasSize()
        })

        // VKSession EVENT addAnchors
        // session.on('addAnchors', anchors => {
        //   this.left.visible = true
        //   this.right.visible = true
        //   this.top.visible = true
        //   this.bottom.visible = true
        // })

        // VKSession EVENT updateAnchors
        session.on('updateAnchors', anchors => {
          // marker 模式下，目前仅有一个识别目标，可以直接取
          const anchor = anchors[0]
          const markerId = anchor.id
          const size = anchor.size
          this.hintInfo = {
            markerId,
            size
          }

          const url = this.data.markerMap[markerId]
          if (url) {
            const match = url.match(/\/kelamayi\/(\d+)/);
            const id = match ? match[1] : null;
            console.log('识别到的图片：', url, id)
            if (id && !this.data.forzen) {
              this.setData({
                forzen: true,
                markerIndex: Number(id),
                showVideo: true
              })
            }
          }
        })

        // VKSession removeAnchors
        // 识别目标丢失时，会触发一次
        session.on('removeAnchors', anchors => {
          // this.left.visible = false
          // this.right.visible = false
          // this.top.visible = false
          // this.bottom.visible = false

          if (this.data.hintBoxList && this.data.hintBoxList.length > 0) {
            // 清理信息
            this.hintInfo = undefined
            // 存在列表的情况，去除remove
            this.setData({
              hintBoxList: []
            })
          }
        })

        console.log('ready to initloop')
        // start 初始化完毕后，进行更新渲染循环
        this.initLoop()

        const batchSize = 2;
        const delay = 1000;
        
        for (let i = 0; i < MARKER_LIST.length; i += batchSize) {
          const batch = MARKER_LIST.slice(i, i + batchSize);
          const promises = batch.map(async url => {
            const cacheKey = 'image_marker_' + hash(url);
            const sysPath = await getCachedImage(url, cacheKey);
            return [sysPath, url];
          });
          
          // 等待当前批次完成
          const results = await Promise.all(promises);
          
          // 处理当前批次结果
          for (const [path, url] of results) {
            console.log('marker添加成功：', path);
            const id = session.addMarker(path);
            console.log('markerId：', id);
            this.data.markerMap[id] = url;
          }
          
          // 如果不是最后一批，等待2秒
          if (i + batchSize < MARKER_LIST.length) {
            await new Promise(resolve => setTimeout(resolve, delay));
          }
        }
      })
    },
    loop() {
      // console.log('loop')

      // 获取 VKFrame
      const frame = this.session.getVKFrame(this.canvas.width, this.canvas.height)

      // 成功获取 VKFrame 才进行
      if (!frame) { return }

      // 更新相机 YUV 数据
      this.renderYUV(frame)

      // 获取 VKCamera
      const VKCamera = frame.camera

      // 相机
      if (VKCamera) {
        // 接管 ThreeJs 相机矩阵更新，Marker模式下，主要由视图和投影矩阵改变渲染效果
        this.camera.matrixAutoUpdate = false

        // 视图矩阵
        this.camera.matrixWorldInverse.fromArray(VKCamera.viewMatrix)
        this.camera.matrixWorld.getInverse(this.camera.matrixWorldInverse)

        // 投影矩阵
        const projectionMatrix = VKCamera.getProjectionMatrix(NEAR, FAR)
        this.camera.projectionMatrix.fromArray(projectionMatrix)
        this.camera.projectionMatrixInverse.getInverse(this.camera.projectionMatrix)
      }

      // 绘制而为提示框的逻辑
      // if (this.hintInfo) {
      //   // 存在提示信息，则更新
      //   const THREE = this.THREE

      //   // 原点偏移矩阵，VK情况下，marker 点对应就是 0 0 0，世界矩阵可以认为是一个单位矩阵
      //   // marker 右侧点可以理解是 0.5 0 0
      //   const center = new THREE.Vector3()
      //   const right = new THREE.Vector3(0.5, 0, 0)

      //   // 获取设备空间坐标
      //   const devicePos = center.clone().project(this.camera)

      //   // 转换坐标系，从 (-1, 1) 转到 (0, 100)，同时移到左上角 0 0，右下角 1 1
      //   const screenPos = new THREE.Vector3(0, 0, 0)
      //   screenPos.x = devicePos.x * 50 + 50
      //   screenPos.y = 50 - devicePos.y * 50

      //   // 获取右侧点信息
      //   const deviceRightPos = right.clone().project(this.camera)
      //   const screenRightPos = new THREE.Vector3(0, 0, 0)
      //   screenRightPos.x = deviceRightPos.x * 50 + 50

      //   const markerHalfWidth = screenRightPos.x - screenPos.x

      //   this.setData({
      //     hintBoxList: [
      //       {
      //         markerId: this.hintInfo.markerId,
      //         left: screenPos.x - markerHalfWidth,
      //         top: screenPos.y - markerHalfWidth,
      //         width: markerHalfWidth * this.data.domWidth * 2 / 100,
      //         height: markerHalfWidth * this.data.domWidth * 2 / 100,
      //       }
      //     ]
      //   })
      // }

      this.renderer.autoClearColor = false
      this.renderer.state.setCullFace(this.THREE.CullFaceBack)
      this.renderer.render(this.scene, this.camera)
      this.renderer.state.setCullFace(this.THREE.CullFaceNone)
    },
    add3DBox() {
      // 添加marker需要的 三维包围框

      const THREE = this.THREE
      const scene = this.scene

      const material = new THREE.MeshPhysicalMaterial({
        metalness: 0.0,
        roughness: 0.1,
        color: 0x64f573,
      })
      const geometry = new THREE.BoxGeometry(1, 1, 1)

      const borderSize = 0.1

      const left = new THREE.Mesh(geometry, material)
      left.position.set(-0.5, 0, 0)
      left.rotation.set(-Math.PI / 2, 0, 0)
      left.scale.set(borderSize, 1.1, borderSize)
      scene.add(left)
      left.visible = false
      this.left = left

      const right = new THREE.Mesh(geometry, material)
      right.position.set(0.5, 0, 0)
      right.rotation.set(-Math.PI / 2, 0, 0)
      right.scale.set(borderSize, 1.1, borderSize)
      scene.add(right)
      right.visible = false
      this.right = right

      const top = new THREE.Mesh(geometry, material)
      top.position.set(0, 0, 0.5)
      top.rotation.set(0, 0, 0)
      top.scale.set(1.1, borderSize, borderSize)
      scene.add(top)
      top.visible = false
      this.top = top

      const bottom = new THREE.Mesh(geometry, material)
      bottom.position.set(0, 0, -0.5)
      bottom.rotation.set(0, 0, 0)
      bottom.scale.set(1.1, borderSize, borderSize)
      scene.add(bottom)
      bottom.visible = false
      this.bottom = bottom

      console.log('add3DBox is finish')
    },
  },
})