import type { MutableRefObject } from "react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import type { RelationGraphExpose, RGLink, RGNode, RGNodeSlotProps, RGOptions } from "relation-graph/react";
import RelationGraph from "relation-graph/react";
import { exceptStr } from "@/utils/common";
import { extractTree } from "@/pages/salaryItemDiagram";
import { RGEventTargetType, RGUserEvent } from "relation-graph/types/types/types";
import cs from "classnames";
import styles from "./index.less";

const NodeSlot: React.FC<RGNodeSlotProps> = ({ node }) => {
  if (node.id === "0") {
    return <div className={styles.rootNode}> {node.text} </div>;
  }
  // @ts-ignore
  if (node.id !== "0" && !node.data.parentId) {
    return <div className={cs(styles.levelNode, styles.commonNode)}> {node.text} </div>;
  }
  return <div className={styles.commonNode}>
    <span title={node.text}>{node.text}</span>
  </div>;
};
const Index: React.FC = () => {
  const [itemsTree, setItemsTree] = useState<any[]>([]);
  const [i18n, setI18n] = useState<any>({});
  const [menuXY, setMenuXY] = useState<any>({ left: "", top: "", data: {} });
  const graphRef = useRef() as MutableRefObject<RelationGraphExpose>;
  useEffect(() => {
    window.parent.postMessage({ type: "init" }, "*");
    window.addEventListener("message", receiveMessageFromIndex, false);
    return () => {
      window.removeEventListener("message", receiveMessageFromIndex, false);
    };
  }, []);
  const receiveMessageFromIndex = (event: any) => {
    const data: any = exceptStr(event.data);
    if (!_.isEmpty(data)) {
      const { itemsTree, i18n } = data;
      setI18n(i18n);
      setItemsTree(itemsTree);
    }
  };
  const dataSource: any = useMemo(() => {
    setMenuXY({ left: "", top: "", data: {} });
    return {
      rootId: "0",
      nodes: [{ id: "0", text: i18n["薪资项目"] }, ..._.map(extractTree(itemsTree), o => ({
        id: o.salaryItemId.toString(),
        text: o.salaryItemName, data: { ...o }
      }))],
      lines: _.map(extractTree(itemsTree), o => ({
        from: o.parentId ? o.parentId.toString() : "0",
        to: o.salaryItemId.toString()
      }))
    };
  }, [itemsTree, i18n]);
  useEffect(() => {
    if (!_.isEmpty(dataSource.nodes) && !_.isEmpty(dataSource.lines)) {
      const init = showGraph();
    }
  }, [dataSource]);
  const showGraph = async () => {
    await graphRef.current.setJsonData(dataSource, (graphInstance) => {
    });
  };
  const options: RGOptions = useMemo(() => {
    return {
      debug: false,
      layout: {
        label: "树",
        layoutName: "tree",
        layoutClassName: "seeks-layout-center",
        from: "left",
        // 通过这4个属性来调整 tree-层级距离&节点距离
        min_per_width: undefined,
        max_per_width: 300,
        min_per_height: 60,
        max_per_height: undefined,
        levelDistance: "" // 如果此选项有值，则优先级高于上面那4个选项
      },
      defaultExpandHolderPosition: "right",
      defaultNodeWidth: 180,
      defaultNodeHeight: 50,
      defaultLineShape: 4,
      defaultNodeBorderWidth: 1,
      defaultLineColor: "#333",
      defaultExpandHolderColor: "rgba(0, 206, 209, 1)",
      defaultNodeColor: "transparent",
      defaultNodeBorderColor: "#333",
      allowShowMiniToolBar: true, //工具栏展示与否
      toolBarDirection: 'h',
      toolBarPositionH: 'right',
      toolBarPositionV: 'top',
      allowShowFullscreenMenu: false,
      allowShowDownloadButton: false,
      disableZoom: true,
      disableDragNode: true,
    };
  }, []);
  const onNodeRightClick = (e: RGUserEvent & { pageX: number, pageY: number }, objectType: RGEventTargetType, object: RGNode | RGLink | undefined) => {
    if (objectType === "node") {
      // @ts-ignore
      setMenuXY({ left: e.pageX, top: e.pageY, data: object?.data });
    } else {
      setMenuXY({ left: "", top: "", data: {} });
    }
    return true;
  };
  const onNodeClick = (node: RGNode) => {
    setMenuXY({ left: "", top: "", data: {} });
    if (node.type === "node") {
      // @ts-ignore
      const { formulaId } = node?.data;
      formulaId &&
      window.parent.postMessage({ type: "turn", payload: { id: "VIEW", params: { formulaId } } }, "*");
    }
    return true;
  };
  const handleNodeOpt = (id: string) => {
    const { data } = menuXY;
    window.parent.postMessage({
      type: "turn",
      payload: {
        id, params: {
          visible: true, id: data?.groupId, dataType: data?.dateType,
          formulaId: data?.formulaId, valueType: data?.valueType,
          salaryItemId: data?.salaryItemId
        }
      }
    }, "*");
  };
  return <div style={{ height: "100%", width: "100%" }}>
    <RelationGraph ref={graphRef} options={options} nodeSlot={NodeSlot}
      // @ts-ignore
                   onContextmenu={onNodeRightClick} onNodeClick={onNodeClick} onCanvasClick={onNodeClick}
    />
    {
      !_.isEmpty(menuXY.data) &&
      <div className={styles["c-right-menu-panel"]} style={{ ...menuXY }}>
        {
          menuXY.data.canAddItem &&
          <div className={styles["c-node-menu-item"]} onClick={() => handleNodeOpt("ADD")}>{i18n["添加薪资项目"]}</div>
        }
        {
          !_.isNil(menuXY.data.formulaId) && menuXY.data.formulaId !== 0 && menuXY.data.canEditItem &&
          <div className={styles["c-node-menu-item"]} onClick={() => handleNodeOpt("EDIT")}>{i18n["编辑公式"]}</div>
        }
      </div>
    }
  </div>;
};
export default Index;
