import { ref } from "vue";
import {
  Scene,
  PerspectiveCamera,
  Clock,
  WebGLRenderer,
  AmbientLight,
  Color,
  PlaneGeometry,
  Mesh,
  HemisphereLight,
  Group,
  Raycaster,
  Vector2,
  // PointLight,
  // PointLightHelper,
  // FogExp2,
  // Vector2,
} from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// import Stats from "three/addons/libs/stats.module.js";
import { getImg } from "@/utils";
import { Reflector } from "three/examples/jsm/objects/Reflector.js";
import { getBottomMaterial } from "./material";
import { modelGroup, initModels } from "./models";
import { lineGroup, lineLabelGroup, initBuildGirdLines } from "./lines";
import { vfxGroup } from "./vfx";
import { CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer.js";
import { Easing, Tween, update } from "@tweenjs/tween.js";
// import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
// import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass.js";
// import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
// import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";

export function useScene({ modelClick }: { modelClick: (model: any) => void }) {
  //@ts-ignore
  let stats: any, clock: any, controls: any;
  let camera: any,
    scene: any,
    renderer: any,
    mixer: any,
    verticalMirror: any,
    geometry: any,
    css3Renderer: any;
  // bloomComposer: any,
  // finalComposer: any;
  const containerRef = ref<HTMLElement | null>(null);
  const raycaster = new Raycaster();
  const mouse = new Vector2();

  // const params = {
  //   threshold: 0,
  //   strength: 1,
  //   radius: 0.5,
  //   exposure: 1,
  // };

  function init() {
    // console.log([containerRef.value], containerRef.value!.clientWidth,containerRef.value!.clientHeight);
    camera = new PerspectiveCamera(
      25,
      containerRef.value!.clientWidth / containerRef.value!.clientHeight,
      1,
      1000
    );
    camera.position.set(
      18.416546632171155,
      12.90089079540779,
      -16.681357401983476
    );

    scene = new Scene();
    // @ts-ignore
    window.scene = scene;
    // scene.background = new Color(0xefd1b5);

    clock = new Clock();

    const group = new Group();
    group.name = "智慧能源";

    //雾-指数
    // scene.fog = new FogExp2(0xcccccc, 0.002);

    //加载模型
    initModels();

    //线
    initBuildGirdLines();

    group.add(modelGroup, lineGroup, lineLabelGroup, vfxGroup);
    scene.add(group);

    //环境光
    const ambientLight = new AmbientLight(0xffffff, 0.6);
    scene.add(ambientLight);

    //半球光
    const directionalLight = new HemisphereLight(0xffffff, 0x080820, 1);
    directionalLight.position.set(0, 1000, 0);
    scene.add(directionalLight);

    //底部平面
    geometry = new PlaneGeometry(1, 1);
    // 创建材质，可以设置贴图
    let material = getBottomMaterial(
      "#ffffff", // 设置模型的颜色
      getImg("models/bg.png"),
      1,
      5
    );
    // 创建平面网格
    let plane = new Mesh(geometry, material);
    plane.scale.set(192, 108, 108);
    plane.position.y = 0.01;
    plane.rotateX(-Math.PI / 2);
    let plane2 = plane.clone();
    plane2.material = getBottomMaterial(
      "#ffffff", // 设置模型的颜色
      getImg("models/bg.png"),
      2,
      5
    );
    scene.add(plane2);
    scene.add(plane);

    //镜面
    verticalMirror = new Reflector(geometry, {
      clipBias: 0.003,
      textureWidth:
        containerRef.value!.clientWidth * window.devicePixelRatio * 0.5,
      textureHeight:
        containerRef.value!.clientHeight * window.devicePixelRatio * 0.5,
      color: new Color("#326973"),
    });
    verticalMirror.scale.set(100, 100, 100);
    verticalMirror.position.y = 0;
    verticalMirror.position.z = 0;
    verticalMirror.rotateX(-Math.PI / 2);
    scene.add(verticalMirror);

    //渲染器
    renderer = new WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(
      containerRef.value!.clientWidth,
      containerRef.value!.clientHeight
    );
    containerRef.value!.appendChild(renderer.domElement);

    //控制器
    controls = new OrbitControls(camera, renderer.domElement);
    controls.screenSpacePanning = false;
    controls.maxPolarAngle = Math.PI / 2.1;
    controls.minDistance = 5;
    controls.maxDistance = 40;
    setControlsVeiw(
      {
        x: -4.92927755506738,
        y: 1.9591040557652486e-19,
        z: -3.0835424654787844,
      },
      {
        x: 21.791887493897622,
        y: 15.919334531990208,
        z: -21.407410138122152,
      }
    );
    // controls.target.set(-4.7582917376881415, 0, -2.9423607740176285);
    // controls.update();

    // const renderScene = new RenderPass(scene, camera);

    // const bloomPass = new UnrealBloomPass(
    //   new Vector2(window.innerWidth, window.innerHeight),
    //   1.5,
    //   0.4,
    //   0.85
    // );
    // bloomPass.threshold = params.threshold;
    // bloomPass.strength = params.strength;
    // bloomPass.radius = params.radius;

    // bloomComposer = new EffectComposer(renderer);
    // bloomComposer.renderToScreen = false;
    // bloomComposer.addPass(renderScene);
    // bloomComposer.addPass(bloomPass);

    // const outputPass = new OutputPass();

    // finalComposer = new EffectComposer(renderer);
    // finalComposer.addPass(renderScene);
    // finalComposer.addPass(outputPass);

    // @ts-ignore
    // window.camera = camera;
    // // @ts-ignore
    // window.controls = controls;
    window.getCamera = () => {
      return [controls.target, controls.object.position];
    };

    //性能监控
    // stats = new Stats();

    // stats.dom.style.position = "absolute";
    // stats.dom.style.top = "10%";
    // stats.dom.style.left = "25%";
    // containerRef.value!.appendChild(stats.dom);

    // 创建一个CSS3渲染器CSS3DRenderer
    css3Renderer = new CSS3DRenderer();
    css3Renderer.setSize(
      containerRef.value!.clientWidth,
      containerRef.value!.clientHeight
    );
    // HTML标签<div id="tag"></div>外面父元素叠加到canvas画布上且重合
    css3Renderer.domElement.style.position = "absolute";
    css3Renderer.domElement.style.top = "0px";
    //设置.pointerEvents=none，解决HTML元素标签对threejs canvas画布鼠标事件的遮挡
    css3Renderer.domElement.style.pointerEvents = "none";
    css3Renderer.domElement.style.className = "css3Renderer";
    containerRef.value!.appendChild(css3Renderer.domElement);

    //监听窗口变化
    window.addEventListener("resize", onWindowResize);
    window.addEventListener("click", onMouseClick);
  }

  function onMouseClick(event: any) {
    // calculate mouse position in normalized device coordinates
    // (-1 to +1) for both components

    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
    raycaster.setFromCamera(mouse, camera);

    // 获取raycaster直线和所有模型相交的数组集合
    let intersects = raycaster.intersectObjects(modelGroup.children);
    // console.log(intersects);

    //将所有的相交的模型的颜色设置为红色
    // for (let i = 0; i < intersects.length; i++) {
    //   //@ts-ignore
    //   intersects[i].object.material.color.set(0xff0000);
    // }

    if (intersects.length > 0) modelClick(intersects[0].object);
  }

  function flyTo(target: any) {
    new Tween(controls.object.position)
      .to(target.position, target.time || 500) // Move to (300, 200) in 1 second.
      .easing(Easing.Quadratic.InOut) // Use an easing function to make the animation smooth.
      .onUpdate(() => {})
      .start(); // Start the tween immediately.;
    new Tween(controls.target)
      .to(target.targetContent, target.time || 500) // Move to (300, 200) in 1 second.
      .easing(Easing.Quadratic.InOut) // Use an easing function to make the animation smooth.
      .onUpdate(() => {})
      .start(); // Start the tween immediately.;;
  }

  function onWindowResize() {
    camera.aspect =
      containerRef.value!.clientWidth / containerRef.value!.clientHeight;
    camera.updateProjectionMatrix();

    css3Renderer.setSize(
      containerRef.value!.clientWidth,
      containerRef.value!.clientHeight
    );
    renderer.setSize(
      containerRef.value!.clientWidth,
      containerRef.value!.clientHeight
    );

    verticalMirror
      .getRenderTarget()
      .setSize(
        containerRef.value!.clientWidth * window.devicePixelRatio,
        containerRef.value!.clientHeight * window.devicePixelRatio
      );
  }

  function animate() {
    update();
    controls.update();
    requestAnimationFrame(animate);
    render();
    // stats.update();
  }

  function render() {
    const delta = clock.getDelta();

    if (mixer !== undefined) {
      mixer.update(delta);
    }

    // bloomComposer.render();
    // finalComposer.render();
    css3Renderer.render(scene, camera);
    renderer.render(scene, camera);
  }

  function setControlsVeiw(targetContent: any, position: any) {
    flyTo({ targetContent, position });
    // controls.target.set(targetContent.x, targetContent.y, targetContent.z);
    // controls.object.position.set(position.x, position.y, position.z);
    // controls.update();
  }

  return {
    containerRef,
    init,
    animate,
    setControlsVeiw,
  };
}
