import { useEffect, useRef, useState } from "react";
import * as BABYLON from "@babylonjs/core";
import "@babylonjs/core/Debug/debugLayer";
import "@babylonjs/inspector";
import "@babylonjs/loaders/glTF";
import { GridMaterial } from "@babylonjs/materials/";
import { HemisphericLight, Vector3 } from "@babylonjs/core";
import { useAppSelector } from "../store/hooks";
import "../page/style/standard.css";
import EqInfoData from "./EqInfoData";
import AlarmTipGreen from "./../page/assets/icon/g.png";
import AlarmTipYellow from "./../page/assets/icon/y.png";
import AlarmTipRed from "./../page/assets/icon/r.png";
import {selectLine1Before} from "../store/LinePageSlice";

const lineNameNo = ["一","二","三","四","五"]
const myStyle = {
  width: "1041px",
  height: "562px",
  outline: "none",
};
interface MybabylonJSProps {
  modelPath: string; // 明确 modelPath 属性的类型为 string
}
interface EqListType {
  [key: string]: EqMsg
}
interface EqMsg {
  equipmentName?:string;
  run?:boolean;
  error?:boolean;
  inputNum?:number;
  outputNum?:number;
  quantityTime?:number;
  status?:string;
  statusTime?:number;
  localDateTime?:number;
  equipmentCode?:string;
  equipmentId?:number;
}
function MybabylonJS({ modelPath }: MybabylonJSProps) {
  const [eqList, setEqList] = useState<EqListType>({});
  const allData = useAppSelector(selectLine1Before) as any; // 使用`any`来绕过类型检查
  const canvasRef = useRef(null);
  const resetRef = useRef<(() => void) | null>(null);
  const [selectedMeshName, setSelectedMeshName] = useState<string | null>(null);
  const [selectedMeshId, setSelectedMeshId] = useState<string | null>(null);
  const [selectedMeshObj, setSelectedMeshObj] = useState<EqMsg>({
    equipmentName: "",
    run: true,
    error: false,
  });
  const [showInfo, setShowInfo] = useState(true);

  // 使用 useRef 来存储当前加载的模型引用
  const currentMeshesRef = useRef<Array<BABYLON.AbstractMesh>>([]);
  useEffect(() => {
    const equStatus = allData?.equStatus;
    if (equStatus) {
        setEqList(equStatus);
    }
  },[allData])
  useEffect(() => {
    const equStatus = allData?.equStatus;
    if (equStatus) {
      for (let i = 0; i < EqInfoData[modelPath].length; i++) {
        for (let j = 0; j < EqInfoData[modelPath][i].data.length; j++) {
          EqInfoData[modelPath][i].data[j].value = equStatus[EqInfoData[modelPath][i].data[j].code][EqInfoData[modelPath][i].data[j].label] ? equStatus[EqInfoData[modelPath][i].data[j].code][EqInfoData[modelPath][i].data[j].label] : 0
        }
      }
    }
  },[allData,modelPath])
  useEffect(() => {
    if (selectedMeshId && eqList[selectedMeshId]) {
      setSelectedMeshObj({
        equipmentName:eqList[selectedMeshId].equipmentName,
        run:eqList[selectedMeshId].run ? eqList[selectedMeshId].run : true,
        error:eqList[selectedMeshId].error ? eqList[selectedMeshId].error : false,
      });
    }
  },[selectedMeshId])
  useEffect(() => {
    // 确保 canvas 引用存在
    if (!canvasRef.current) return;
    const canvas = canvasRef.current;
    const engine = new BABYLON.Engine(canvas, true, {
      preserveDrawingBuffer: true,
      stencil: true,
    });

    const createScene = async function () {
      // This creates a basic Babylon Scene object (non-mesh)
      const scene = new BABYLON.Scene(engine);
      scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
      const baseLight = new HemisphericLight(
        "hemiLight",
        new Vector3(-1, 1, 0),
        scene
      );
      baseLight.intensity = 1;
      baseLight.diffuse = new BABYLON.Color3(1, 1, 1);
      baseLight.specular = new BABYLON.Color3(0.25, 0.25, 0.25);
      baseLight.groundColor = new BABYLON.Color3(0.5, 0.5, 0.5);

      //add an arcRotateCamera to the scene
      const camera = new BABYLON.ArcRotateCamera(
        "camera",
        BABYLON.Tools.ToRadians(245),
        BABYLON.Tools.ToRadians(25),
        modelPath.slice(-3) === "2-1"
          ? 120
          : modelPath.slice(-1) === "1"
          ? 110
          : modelPath.slice(-3) === "5-2"
          ? 100
          : modelPath.slice(-3) === "1-2"
          ? 90
          : 65,
        new BABYLON.Vector3(-13, 0, 0)
      );
      camera.lowerRadiusLimit = 10;
      camera.upperRadiusLimit = 600;

      // This attaches the camera to the canvas
      camera.attachControl(canvas, true);

      //创建一个材质
      const newMt = new BABYLON.StandardMaterial("newMt");
      newMt.diffuseColor = BABYLON.Color3.Blue();

      const ground = BABYLON.MeshBuilder.CreateGround(
        "ground",
        {
          width: 1000,
          height: 1000,
          subdivisions: 1,
        },
        scene
      );

      ground.scaling.x = 100;
      ground.scaling.z = ground.scaling.x;
      ground.isPickable = false;

      let grid = new GridMaterial("grid", scene);

      grid.majorUnitFrequency = 10;
      grid.minorUnitVisibility = 0.3;
      grid.gridRatio = 0.04;
      grid.backFaceCulling = !1;
      grid.mainColor = new BABYLON.Color3(1, 1, 1);
      grid.lineColor = new BABYLON.Color3(1, 1, 1);
      grid.opacity = 0;
      grid.zOffset = 1;
      grid.opacityTexture = new BABYLON.Texture(
        "/public/png/backgroundGround.png",
        scene
      );
      ground.material = grid;

      let hl = new BABYLON.HighlightLayer("hl1", scene);
      let hl2 = new BABYLON.HighlightLayer("hl2", scene);

      // 定义一个函数来加载或重新加载模型
      const loadOrReloadModel = async () => {
        // 在加载新模型之前卸载已加载的模型
        currentMeshesRef.current.forEach((mesh) => {
          if (mesh && mesh.parent) {
            scene.removeMesh(mesh, true);
          }
        });
        currentMeshesRef.current = []; // 重置模型数组
        try {
          // 使用 ImportMeshAsync 加载新模型
          var LOD0MESH = await BABYLON.SceneLoader.ImportMeshAsync(
            "",
            "/Line/",
            `${modelPath}.babylon`,
            scene
          );
          // 将新加载的模型添加到 currentMeshesRef 中
          currentMeshesRef.current.push(...LOD0MESH.meshes);

          // ...为新加载的模型设置交互逻辑

          LOD0MESH.meshes.map((mesh) => {
            mesh.isPickable = true;
            mesh.actionManager = new BABYLON.ActionManager(scene);
            if (modelPath.slice(-1) === "1") {
              if (
                mesh.name.includes("磨边") ||
                mesh.name.includes("清洗") ||
                mesh.name.includes("镀膜") ||
                mesh.name.includes("固化") ||
                mesh.name.includes("丝印") ||
                mesh.name.includes("打孔")
              ) {
                // @ts-ignore
                hl.addMesh(mesh, BABYLON.Color3.Green());
              }
            } else {
              if (
                mesh.name.includes("钢化") ||
                mesh.name.includes("包装") ||
                mesh.name.includes("铺纸") ||
                mesh.name.includes("下片机械手")
              ) {
                // @ts-ignore
                hl.addMesh(mesh, BABYLON.Color3.Green());
              }
            }
            mesh._scene.onPointerDown = async (event, _pickResult) => {
              console.log('_pickResult',_pickResult)
              const pickInfo = mesh._scene.pick(
                mesh._scene.pointerX,
                mesh._scene.pointerY
              );
              //判断是否是右键
              if (!(event.buttons === 1 && pickInfo.pickedMesh)) return;
              const MeshName = pickInfo.pickedMesh.name;
              const MeshNameId = pickInfo.pickedMesh.metadata.tags;

              setSelectedMeshName(MeshName);
              setSelectedMeshId(MeshNameId);
            };
          });
        } catch (error) {
          console.error("加载模型失败:", error);
        }
      };

      // 调用函数以加载或重新加载模型
      loadOrReloadModel();

      function reset() {
        camera.target = new BABYLON.Vector3(-13, 0, 0);
        camera.alpha = BABYLON.Tools.ToRadians(245);
        camera.beta = BABYLON.Tools.ToRadians(25);
        camera.radius =
        modelPath.slice(-3) === "2-1"
          ? 120
          : modelPath.slice(-1) === "1"
          ? 110
          : modelPath.slice(-3) === "5-2"
          ? 100
          : modelPath.slice(-3) === "1-2"
          ? 90
          : 65
        setShowInfo(true);
        setSelectedMeshName(null);
      }
      // 外部初始位置按钮
      resetRef.current = reset;

      let resetCamera = setTimeout(reset, 15000);
      scene.onPointerObservable.add((pointerInfo) => {
        switch (pointerInfo.type) {
          case BABYLON.PointerEventTypes.POINTERMOVE:
            clearTimeout(resetCamera);
            resetCamera = setTimeout(reset, 15000);
            setShowInfo(false);
        }
      });
      return scene;
    };

    // call the createScene function
    const scene = createScene();

    // run the render loop
    scene.then(
      (scene) => {
        console.log("createScene被调用了=====", scene);
        engine.runRenderLoop(function () {
          scene.render();
        });
      },
      (reason) => {
        console.log("reason=============", reason);
      }
    );

    // Resize
    window.addEventListener("resize", function () {
      engine.resize();
    });
    // 组件卸载时的清理逻辑
    return () => {
      // 清理场景和引擎资源
      engine.dispose();
    };
  }, [modelPath]);
  const resetModel = () => {
    //模型初始位置
    if (resetRef.current) {
      resetRef.current();
    }
  };
  return (
    <div style={myStyle}>
      {/* <h2 className="model_name">当前选择: {selectedMeshName}</h2> */}
      <div className="model_info">
        <span className="reset_btn" onClick={resetModel}></span>
        <span className="title">
        第{lineNameNo[Number(modelPath.slice(-3,-2))-1]}产线钢化{modelPath.slice(-1) === "1" ? "前段" : "后段"}
        </span>
      </div>
      {selectedMeshName && (
        <div className="eq_detail_info">
          <div>
            <span className="left_name">设备名称：</span>
            <span className="right_value">{selectedMeshObj.equipmentName}</span>
          </div>
          <div>
            <span className="left_name">报警状态：</span>
            <span className="right_value">
              {selectedMeshObj.error ? (
                <>
                  <img
                    src={AlarmTipRed}
                    alt=""
                    width={17}
                    style={{ position: "relative", top: "2px", marginRight: 5 }}
                  />
                  <span>报警</span>
                </>
              ) : (
                <>
                  <img
                    src={AlarmTipGreen}
                    alt=""
                    width={17}
                    style={{ position: "relative", top: "2px", marginRight: 5 }}
                  />
                  <span>正常</span>
                </>
              )}
            </span>
          </div>
          <div>
            <span className="left_name">在线状态：</span>
            <span className="right_value">
              {selectedMeshObj.run ? (
                <>
                  <img
                    src={AlarmTipGreen}
                    alt=""
                    width={17}
                    style={{ position: "relative", top: "2px", marginRight: 5 }}
                  />
                  <span>在线</span>
                </>
              ) : (
                <>
                  <img
                    src={AlarmTipYellow}
                    alt=""
                    width={17}
                    style={{ position: "relative", top: "2px", marginRight: 5 }}
                  />
                  <span>离线</span>
                </>
              )}
            </span>
          </div>
        </div>
      )}
      {showInfo &&
        EqInfoData[modelPath] &&
        EqInfoData[modelPath].map((item) => {
          return (
            <div
              className="eq_info"
              key={item.data[0].code+item.data[0].label}
              style={{ left: item.position[0], top: item.position[1] }}
            >
              <div className="eq_info_inner" style={{ color: "#00FFF0" }}>
                {item.name}
              </div>
              {item.data.map((info) => {
                return (
                  <div className="eq_info_inner" key={info.code+info.label}>
                    {info.name}：{info.value}
                  </div>
                );
              })}
            </div>
          );
        })}

      <canvas ref={canvasRef} style={myStyle} />
    </div>
  );
}

export default MybabylonJS;
