import { 
    Scene, 
    PerspectiveCamera, 
    WebGLRenderer, 
    Clock,
    Matrix4,
    Euler,
    sRGBEncoding,
    Math as ThreeMath
  } from 'three';

import { OrbitControls } from './lib/OrbitControls.js';
import { TransformControls } from './lib/TransformControls.js';
import LoaderTileFiles from './LoaderTileFiles.js';
import { Loader3DTiles } from 'three-loader-3dtiles';
import { CameraRig, FreeMovementControls } from 'three-story-controls'

import Stats from './lib/stats.module.js';
import StatsWidget from '@probe.gl/stats-widget';
import Control from './Control.js';
import {render} from './Render.js';

const queryParams = new URLSearchParams(document.location.search);
const canvasParent = document.querySelector('#canvas-parent');
const statsParent = document.querySelector('#stats-widget')

export default class MergeScene{
    constructor(){
        this.scene = null;
        this.camera = null;
        this.renderer = null;
        this.controls = null;
        this.threeJsStats = null;
        //this.tilesRuntime = null;
        this.statsRuntime = null;
        this.control = null;

        this.init();
    }

    init(){
      this.scene = new Scene();
      this.camera = new PerspectiveCamera(
        35,
        1,
        0.01,
        1000,
      );
      this.renderer = new WebGLRenderer();
      this.renderer.outputEncoding = sRGBEncoding;
      this.clock = new Clock()
      this.rig = new CameraRig(this.camera, this.scene)
      
      /*
      if (queryParams.get('orbit')) {
          this.controls = new OrbitControls( this.camera, canvasParent);
          this.controls.listenToKeyEvents( document.body );
          this.camera.position.set(0,200,0);
          this.controls.update();
      } 
      else {
          this.controls = new FreeMovementControls(this.rig, {
            panDegreeFactor: 2,
            wheelScaleFactor: 0.01,
            keyboardScaleFactor: 0.015,
            keyboardDampFactor: 0
          });
          this.controls.enable();
      }
      */
      this.controls = new OrbitControls( this.camera, canvasParent);
      this.controls.listenToKeyEvents( document.body );
      this.camera.position.set(0,200,0);
      this.controls.update();

      canvasParent.appendChild(this.renderer.domElement);
      this.threeJsStats = new Stats();
      this.threeJsStats.domElement.style.position = 'absolute';
      this.threeJsStats.domElement.style.top = '10px';
      this.threeJsStats.domElement.style.left = '10px';

      this.loaderTileFiles = new LoaderTileFiles(this.scene,this.renderer);

      this.control = new Control(this.scene,this.camera);   //鼠标的选中点击等等
      this.control.arrowControls = new TransformControls( this.camera , canvasParent );
      this.scene.add( this.control.arrowControls );
      this.initTransformControls();

      render.init(this.scene);

      canvasParent.appendChild( this.threeJsStats.domElement );
      if (queryParams.get('tilesetUrl')) {
          document.querySelector('#example-desc').style.display = 'none';
      }   
      window.addEventListener('resize', this.onWindowResize);
    }

    initTransformControls(){
      this.control.arrowControls.addEventListener( 'change', this.render.bind(this) );
      this.control.arrowControls.addEventListener( 'dragging-changed', function ( event ) {
        this.controls.enabled = ! event.value;
      }.bind(this) );
    }

    async loadTileset() {
      /*
      const result = await Loader3DTiles.load(
        {
          url:
            queryParams.get('tilesetUrl') ??
            //'https://testgis.4dage.com/LVBADUI_qp/tileset.json',  
            'https://int.nyt.com/data/3dscenes/ONA360/TILESET/0731_FREEMAN_ALLEY_10M_A_36x8K__10K-PN_50P_DB/tileset_tileset.json',
          renderer: this.renderer,
          options: {
            dracoDecoderPath: 'https://cdn.jsdelivr.net/npm/three@0.137.0/examples/js/libs/draco',
            basisTranscoderPath: 'https://cdn.jsdelivr.net/npm/three@0.137.0/examples/js/libs/basis',
            maximumScreenSpaceError: queryParams.get('sse') ?? 48,
          }
        }
      );
  
      const {model, runtime} = result;
      model.rotation.set(-Math.PI / 2, 0, Math.PI / 2);
  
      if (!queryParams.get('tilesetUrl')) {
        model.position.set(-1, 4, -16);
      }
  
      this.tilesRuntime = runtime;
      this.scene.add(model);
      modelManager.tilesMeshesUUIDs.push(model.uuid);
  
      this.statsRuntime = new StatsWidget(runtime.getStats(), {container: statsParent });
      statsParent.style.visibility = 'visible';
      */
      await this.loaderTileFiles.loadTilesets('https://testgis.4dage.com/LVBADUI_qp/','tileset.json');
      this.statsRuntime = new StatsWidget(this.loaderTileFiles.tilesRuntime.getStats(), {container: statsParent });
      statsParent.style.visibility = 'visible';
    }
    
    render(t) {
        const dt = this.clock.getDelta()
        this.controls.update(t);
        // if (this.tilesRuntime) {
        //     this.tilesRuntime.update(dt, this.renderer, this.camera);
        // }
        if (this.loaderTileFiles.tilesRuntime) {
          this.loaderTileFiles.tilesRuntime.update(dt, this.renderer, this.camera);
      }
        if (this.statsRuntime) {
            this.statsRuntime.update();
        }
        this.renderer.render(this.scene, this.camera);
        this.threeJsStats.update();
        window.requestAnimationFrame(this.render.bind(this));
    }
    
    onWindowResize() {
        this.renderer.setSize(canvasParent.clientWidth, canvasParent.clientHeight);
        this.camera.aspect = canvasParent.clientWidth / canvasParent.clientHeight;
        this.camera.updateProjectionMatrix();
    }

    start(){
        this.loadTileset();
        this.onWindowResize();
        this.render();
    }
}

let mergeScene = new MergeScene();
export {mergeScene}
