import { ArcRotateCamera, Color3, Tools, Engine, HemisphericLight, MeshBuilder, Scene, StandardMaterial, SceneLoader, Texture, Vector3, Animation, AbstractMesh , ActionManager, ExecuteCodeAction, AnimationGroup, Mesh} from "babylonjs";
import {AdvancedDynamicTexture, Button, TextBlock} from 'babylonjs-gui';
import 'babylonjs-loaders'

export default class SkyBox {
  engine: Engine
  scene: Scene
  camera: ArcRotateCamera | undefined;
  table: AbstractMesh[] | undefined;
  chair: AbstractMesh[] | undefined;
  animationGroup: AnimationGroup | undefined;

    constructor(private readonly canvas: boolean) {
    this.engine = new Engine(this.canvas);
    this.scene = this.CreateScene();

    this.engine.runRenderLoop(() => {
      this.scene.render();
    })
  }
  CreateScene(): Scene {
    const scene = new Scene(this.engine);

        this.camera = new ArcRotateCamera('camera', 5, 1.3, 50, new Vector3(0, 0, 0), scene)
        this.camera.attachControl(this.canvas, true)

        this.camera.lowerBetaLimit = Tools.ToRadians(0)
        this.camera.upperBetaLimit = Tools.ToRadians(80)
        this.camera.lowerRadiusLimit = 15

        const light = new HemisphericLight('light', new Vector3(1, 1, 0), scene)
        light.diffuse = new Color3(1, 1, 1)


        SceneLoader.ImportMeshAsync('', '/Meshes/', 'house.glb', this.scene).then((result) => {
          const plane = MeshBuilder.CreatePlane('plane', { size: 1 })
          plane.parent = result.meshes[0]
          plane.position.y = 3
          plane.position.z = 9.5
          plane.position.x = -0.5

          const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane, 128, 128, false)
          advancedTexture.renderScale = 1

          const button = Button.CreateSimpleButton('button', '进入房间')
          button.width = 1
          button.height = 0.5
          button.color = 'white'
          button.background = 'green'

          button.onPointerClickObservable.add(() => {
            const cameraAnimation = new Animation('cameraAnimation', 'radius', 30,
              Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT)

            const Keys = [
              { frame: 0, value: this.camera!.radius },
              { frame: 60, value: 6.5 }
            ]
            cameraAnimation.setKeys(Keys)
            this.camera!.animations = []
            this.camera!.animations.push(cameraAnimation)
            this.camera!.lowerRadiusLimit = 3

            scene.beginAnimation(this.camera, 0, 60, false, 0.6, () => {
              this.camera!.upperRadiusLimit = 6.8
            })
          })

          advancedTexture.addControl(button)

          const LogoPlane = MeshBuilder.CreatePlane('logo', { width: 3, height: 1.5 }, this.scene)
          LogoPlane.rotation.y = Math.PI / 2
          LogoPlane.position.x = 5.9
          LogoPlane.position.y = 2
          LogoPlane.position.z = 1

          const LogoMaterial = new StandardMaterial('logoMaterial', scene)
          LogoMaterial.diffuseTexture = new Texture('/Meshes/gwise.png', scene)
          LogoMaterial.emissiveColor = new Color3(0.5, 0.5, 0.5)
          LogoPlane.material = LogoMaterial
        })

        SceneLoader.ImportMeshAsync('', '/Meshes/', 'chair.glb', this.scene).then((result) => {
          this.chair = result.meshes
          this.chair[0].position.x = 1.5

          this.chair.forEach((mesh) => {
            console.log(mesh.name)
            mesh.actionManager = new ActionManager(this.scene)

            mesh.actionManager.registerAction(
              new ExecuteCodeAction(ActionManager.OnPickTrigger, () => {
                this.animationGroup!.play(false)
              })
            )
          })

          this.createAnimation(this.chair[0])

          const LinePoints = [
            new Vector3(0, 0.5, 0),
            new Vector3(0, 1.5, 0)
          ]

          const line = MeshBuilder.CreateDashedLines('dashedLine', {
            points: LinePoints,
            dashSize: 0.5,
            gapSize: 0.2,
            dashNb: 20
          }, this.scene)

          line.parent = this.chair[0]

          const disc = MeshBuilder.CreateDisc('circle', { radius: 0.3, tessellation: 60 }, this.scene)
          disc.parent = this.chair[0]
          disc.position.y = 1.6
          disc.rotation.x = Math.PI

          const advancedTexture = AdvancedDynamicTexture.CreateForMesh(disc, 128, 128, false)
          advancedTexture.renderScale = 1

          const textBlock = new TextBlock()
          textBlock.text = '点击椅子'
          textBlock.color = 'white'
          textBlock.fontSize = 16
          textBlock.fontWeight = '800'

          advancedTexture.addControl(textBlock)
        })

        SceneLoader.ImportMeshAsync('', '/Meshes/', 'table.glb', this.scene).then((result) => {
          this.table = result.meshes

          this.table[0].position.x = -1
          this.table[0].scaling = new Vector3(1.4, 1.4, 1.4)
        })

    return scene;
  }
  createAnimation(mesh: any) {
    // 创建动画并作用于position属性
    const positionAnimation = new Animation('move', 'position', 30,
      Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CYCLE)

    // 定义关键帧
    let Keys = [
      { frame: 0, value: new Vector3(1.5, 0, 0) },
      { frame: 20, value: new Vector3(1, 0, -1) },
      { frame: 40, value: new Vector3(-0.5, 0, -1.5) },
      { frame: 60, value: new Vector3(-0.6, 0, -0.8) }
    ]
    positionAnimation.setKeys(Keys)

    const rotationAnimation = new Animation('rotation', 'rotation', 30,
      Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CYCLE)

    Keys = [
      { frame: 0, value: new Vector3(0, Math.PI, 0) },
      { frame: 20, value: new Vector3(0, Math.PI + Math.PI / 10, 0) },
      { frame: 40, value: new Vector3(0, Math.PI + Math.PI / 5, 0) },
      { frame: 60, value: new Vector3(0, Math.PI + Math.PI / 3.6) }
    ]
    rotationAnimation.setKeys(Keys)

    this.animationGroup = new AnimationGroup('Animation Group')
    this.animationGroup.addTargetedAnimation(positionAnimation, mesh)
    this.animationGroup.addTargetedAnimation(rotationAnimation, mesh)

    this.animationGroup.normalize(0, 60)
    this.animationGroup.speedRatio = 0.5

    const plane = MeshBuilder.CreatePlane('plane', { size: 0.3 })
    plane.parent = this.table![0]
    plane.position.y = 1
    plane.billboardMode = Mesh.BILLBOARDMODE_ALL

    const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane, 128, 128, false)
    advancedTexture.renderScale = 1

    const button = Button.CreateSimpleButton('button', '离开房间')
    button.width = 1
    button.height = 0.5
    button.color = 'white'
    button.background = 'green'

    button.onPointerClickObservable.add(() => {
      const cameraAnimation = new Animation('cameraAnimation', 'radius', 30,
        Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT)

      const Keys = [
        { frame: 0, value: this.camera!.radius },
        { frame: 60, value: 50 }
      ]
      cameraAnimation.setKeys(Keys)
      this.camera!.animations = []
      this.camera!.animations.push(cameraAnimation)
      this.camera!.upperRadiusLimit = 60

      this.scene.beginAnimation(this.camera, 0, 60, false, 0.6, () => {
        this.camera!.lowerRadiusLimit = 15
      })
    })

    advancedTexture.addControl(button)
  }
}
