import {
  Scene,
  WebGLRenderer,
  PerspectiveCamera,
  BoxGeometry,
  MeshLambertMaterial,
  Mesh,
  DirectionalLight,
  DirectionalLightHelper,
  AmbientLight,
  Box3,
  Vector3,
  DoubleSide,
  // ArrowHelper,
  AxesHelper,
  EquirectangularReflectionMapping,
} from "three";
import { ViewHelper } from "three/addons/helpers/ViewHelper.js";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
import { convertDatToObj } from "./convertDatToObj.ts";
interface InitProps {
  domElement: HTMLElement;
}
class ThreeStore {
  scene?: Scene;
  camera?: PerspectiveCamera;
  webGLRenderer?: WebGLRenderer;
  domElement?: HTMLElement;
  orbitControls?: OrbitControls;
  viewHelper?: ViewHelper;
  OBJModel = {} as never;

  constructor() {
    console.log("three-store init!");
  }
  destroy = () => {
    window.removeEventListener("resize", this.onResize);
  };
  init = (props: InitProps) => {
    console.log("three init");
    const { domElement } = props;
    this.domElement = domElement;
    const width = this.domElement.clientWidth;
    const height = this.domElement.clientHeight;
    this.scene = new Scene();
    this.camera = new PerspectiveCamera(75, width / height, 0.1, 1000);

    this.camera!.position.set(1, 1, 1); // 设置相机在三维空间中的位置
    this.camera!.lookAt(this.scene.position); // 让相机看向场景的中心

    this.renderer();
    this.addOrbitControls();
    // this.addDirectionalLight({ helper: true });
    this.addAmbientLight();
    // this.addObject();
    this.animate();
    window.addEventListener("resize", this.onResize, false);
  };
  renderer = () => {
    this.webGLRenderer = new WebGLRenderer({ antialias: true }); // WebGL渲染器，并开启抗锯齿
    const width = this.domElement!.clientWidth;
    const height = this.domElement!.clientHeight;
    this.webGLRenderer.setSize(width, height); // 设置渲染器大小与窗口相同
    this.domElement!.appendChild(this.webGLRenderer.domElement); // 将渲染器输出的canvas元素添加到DOM中
  };

  addObject = () => {
    const geometry = new BoxGeometry(1, 1, 1); // 创建一个立方体几何体
    const material = new MeshLambertMaterial({ color: 0xff0000 }); // 创建材质
    const cube = new Mesh(geometry, material); // 创建网格对象（将几何体和材质结合）
    this.scene!.add(cube); // 将立方体添加到场景中
  };

  removeOBJModel = (id: string) => {
    if (this.OBJModel[id]) {
      this.scene?.remove(this.OBJModel[id]);
    }
  };
  addOBJModel = ({
    url = "",
    id = "defaultId",
    Material = new MeshLambertMaterial({
      color: 0xffffff,
      wireframe: true,
    }),
  }) => {
    if (!url) {
      console.warn("url is empty");
      return;
    }
    // instantiate a loader
    const loader = new OBJLoader();
    // load a resource
    loader.load(
      // resource URL
      url,
      // called when resource is loaded
      (object) => {
        this.removeOBJModel(id);
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        this.OBJModel[id] = object;
        this.scene!.add(object);
        console.log("object loaded", object);

        const box = new Box3().setFromObject(object);
        const size = box.getSize(new Vector3());

        console.log(size, "obj model size");
        // 计算模型的中心点
        const center = box.getCenter(new Vector3());

        console.log(center, "center");
        // 将模型居中，减去中心点然后除以最大尺寸的一半进行标准化
        object.position.sub(center);
        // object.scale.set(1 / size.x, 1 / size.y, 1 / size.z).multiplyScalar(1); // desiredScaleFactor是你想要的缩放比例

        // 旋转45°
        object.rotation.y = Math.PI / 4;
        // 调整相机视野以适应模型
        const newSize = box.getSize(new Vector3());
        const maxDim = Math.max(newSize.x, newSize.y, newSize.z);
        this.camera!.position.z = maxDim * 1.5; // 设置相机距离，使模型适合视窗

        object.traverse((child) => {
          if (child instanceof Mesh) {
            // 将所有网格的材质替换为自定义材质
            const material = Material; // 创建材质
            material.side = DoubleSide;
            child.material = material;
            child.material.side = DoubleSide;
          }
        });
      },
      // called when loading is in progresses
      (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      // called when loading has errors
      (error) => {
        console.log("An error happened", error);
      },
    );
  };
  addHDR = ({ url = "" }) => {
    const hdrLoader = new RGBELoader();
    hdrLoader.load(url, (texture) => {
      texture.mapping = EquirectangularReflectionMapping; // 设置映射方式为全景反射映射
      this.scene!.environment = texture; // 将纹理设置为场景环境
      this.scene!.background = texture;
      // 如果你正在使用基于物理的渲染材质（如MeshStandardMaterial或MeshPhysicalMaterial），它们会自动使用环境贴图
    });
  };
  addAxesHelper = (props?: { size?: number }) => {
    const { size = 5 } = props || {};
    const axesHelper = new AxesHelper(size);
    this.scene!.add(axesHelper);
  };

  addDirectionalLight = (props?: { helper?: boolean }) => {
    const { helper = true } = props || {};
    const light = new DirectionalLight(0xffffff, 1); // 创建一个平行光源
    light.position.set(50, 50, 50); // 设置光源的位置

    this.scene!.add(light); // 将光源添加到场景中
    if (helper) {
      const lightHelper = new DirectionalLightHelper(light, 5);
      this.scene!.add(lightHelper);
    }
  };
  addAmbientLight = (color = 0xffffff) => {
    const ambientLight = new AmbientLight(color); // 创建一个环境光
    this.scene!.add(ambientLight);
  };
  addOrbitControls = () => {
    this.orbitControls = new OrbitControls(
      this.camera!,
      this.webGLRenderer!.domElement,
    );
  };
  addViewHelper = () => {
    this.viewHelper = new ViewHelper(
      this.camera!,
      this.webGLRenderer!.domElement,
    );

    // 添加鼠标事件监听器
    this.webGLRenderer!.domElement.addEventListener('pointerdown', (event) => {
      this.viewHelper?.handleClick(event);
    });
  };
  onResize = () => {
    const domElement = this.domElement!;
    const width = domElement.clientWidth;
    const height = domElement.clientHeight;

    this.camera!.aspect = width / height; // 对于透视相机
    this.camera!.updateProjectionMatrix();

    // 或者对于正交相机设置视口大小
    // this.camera!.left = -width / 2;
    // this.camera!.right = width / 2;
    // this.camera!.top = height / 2;
    // this.camera!.bottom = -height / 2;
    // this.camera!.updateProjectionMatrix();

    // 更新渲染器大小以填充整个窗口
    this.webGLRenderer!.setSize(width, height);

    // 渲染一次以反映更改
    this.webGLRenderer!.render(this.scene!, this.camera!);
  };
  animate = () => {
    requestAnimationFrame(this.animate); // 请求浏览器调用指定的回调函数更新动画

    // 渲染主场景
    this.webGLRenderer!.render(this.scene!, this.camera!);
    this.orbitControls!.update();

    // 渲染 ViewHelper（简化版本）
    if (this.viewHelper) {
      this.webGLRenderer!.autoClear = false;
      this.viewHelper.render(this.webGLRenderer!);
      this.webGLRenderer!.autoClear = true;
    }
  };
}

export { convertDatToObj };
export default ThreeStore;
