import _Drawer from "@alifd/next/es/drawer";
import _Input from "@alifd/next/es/input";
import _extends from "@babel/runtime/helpers/extends";
import React, { useRef, useEffect, useState, useImperativeHandle, forwardRef, useContext } from "react";
import G6 from "@antv/g6";
import { t } from "../../../../src/locale";
import { defaultLayout } from "./default-layout";
import { cloneDeep } from "lodash";
import ContextMenu from "./components/context-menu";
import { registerNodes } from "./node";
import { registerLines } from "./lines";
import { FlowEvent } from "./type";
import { FlowEventService } from "./service";
import SetterPanel from "./setter-panel";
import BoxSlotComponent from "../../_components/boxSlotComponent";
import { FlowContext } from "../context";
var SetterPanelMap = SetterPanel;

// 注入支持的节点
registerNodes();
// 注入支持的线
registerLines();
var FlowPage = /*#__PURE__*/forwardRef(function (props, ref) {
  var _curModel$current2, _curModel$current3;
  var FlowCtx = useContext(FlowContext);
  var flowData = props.flowData;
  var refContainer = useRef();
  var graphRef = useRef();
  var curModel = useRef();

  // const flowEventService = new FlowEventService();

  // TODO:使用 useRef 来保持对同一个 FlowEventService 实例的引用
  var flowEventServiceRef = useRef();
  if (!flowEventServiceRef.current) {
    flowEventServiceRef.current = new FlowEventService();
  }
  var flowEventService = flowEventServiceRef.current;
  var _useState = useState(),
    position = _useState[0],
    setPosition = _useState[1];
  var _useState2 = useState(false),
    menuOpen = _useState2[0],
    setMenuOpen = _useState2[1];
  var _useState3 = useState([]),
    menuList = _useState3[0],
    setMenuList = _useState3[1];
  var _useState4 = useState(false),
    settingOpen = _useState4[0],
    setSettingOpen = _useState4[1];
  var _useState5 = useState(""),
    label = _useState5[0],
    setLabel = _useState5[1];
  useEffect(function () {
    if (!settingOpen) {
      curModel.current = null;
      setMenuOpen(false);
    }
  }, [settingOpen]);
  useEffect(function () {
    var _refContainer$current;
    var _ref = (refContainer === null || refContainer === void 0 ? void 0 : (_refContainer$current = refContainer.current) === null || _refContainer$current === void 0 ? void 0 : _refContainer$current.getBoundingClientRect()) || {},
      width = _ref.width,
      height = _ref.height;
    var graph = new G6.TreeGraph({
      container: refContainer.current,
      width: width,
      height: height,
      layout: defaultLayout,
      minZoom: 1,
      maxZoom: 1,
      linkCenter: true,
      defaultNode: {
        type: "start"
      },
      animate: false,
      modes: {
        "default": ["drag-canvas"] // 允许按住移动画布和节点
      }
    });

    // graph.on("afteradditem", () => {
    //   // updateItemData(graph, width)
    // });
    // graph.on("afterremoveitem", () => {
    //   // updateItemData(graph, width)
    // });

    graph.edge(function (config) {
      // 获取线的源节点和目标节点
      // const sourceNode: any = graph.findById(config.source);
      // const targetNode: any = graph.findById(config.target);

      // 获取源节点和目标节点的配置
      // const sourceModel = sourceNode?.getModel();
      // const targetModel = targetNode?.getModel();

      // let label = "";

      // // 如果是条件节点，则取条件名称
      // if (sourceModel?.type === "condition") {
      //   const { name } =
      //     sourceModel?.config?.find(
      //       (o: any) => o.id === targetModel?.conditionId
      //     ) || {};
      //   label = name;
      // }

      return {
        type: "flow-line",
        style: {
          stroke: "#91d5ff"
        }
      };
    });
    updateGraphData(graph, flowData, true);
    graphRef.current = graph;
    graph.on("node:click", function (evt) {
      var _curModel$current;
      var item = evt.item,
        target = evt.target;
      var targetType = target.get("type");
      var name = target.get("name");
      var model = item.getModel();
      if ([FlowEvent.action, FlowEvent.condition, FlowEvent.rule, FlowEvent.eventFlowNode].includes(model.type) && targetType !== "marker") {
        curModel.current = item.getModel();
        setLabel(curModel.current.label);
        setSettingOpen(true);
        setMenuOpen(false);
        return;
      }
      if (model.id === ((_curModel$current = curModel.current) === null || _curModel$current === void 0 ? void 0 : _curModel$current.id)) {
        return;
      }
      setMenuOpen(false);
      if (targetType === "marker" && (name === FlowEvent.addItem || name === FlowEvent.removeItem)) {
        curModel.current = item.getModel();
        var _flowEventService$get = flowEventService.getMenusPosition(item, target, graph, refContainer),
          left = _flowEventService$get.left,
          top = _flowEventService$get.top;
        var newMenus = name === FlowEvent.addItem ? flowEventService.getMenusByNode(model, FlowCtx) : flowEventService.getDeleteMenus(model, graph);
        changeMenus(newMenus, top, left);
      }
    });
    graph.on("canvas:click", function () {
      setMenuOpen(false);
      curModel.current = null;
    });
    return function () {
      graph.destroy();
    };
  }, []);
  var changeMenus = function changeMenus(newMenus, tops, lefts) {
    setTimeout(function () {
      setPosition({
        top: tops,
        left: lefts
      });
      setMenuList(newMenus);
      setMenuOpen(true);
    }, 10);
  };
  useImperativeHandle(ref, function () {
    return {
      save: function save() {
        var _graphRef$current;
        return (_graphRef$current = graphRef.current) === null || _graphRef$current === void 0 ? void 0 : _graphRef$current.save();
      }
    };
  }, []);

  // const updateItemData = (graph: any, width: number) => {
  //   const newData = graph.save();
  //   const depth = getTreeDepth(newData);
  //   graph.changeSize(width, depth * 40 + 56 * (depth - 1) + 200);
  // }

  var updateGraphData = function updateGraphData(graph, data, isFirst) {
    if (isFirst === void 0) {
      isFirst = false;
    }
    var newFlowData = cloneDeep(flowEventService.updatedParentConfigs(data));
    if (isFirst) {
      graph.data(newFlowData);
      graph.render();
      graph.fitCenter();
    } else {
      var viewPoint = graph.getViewPortCenterPoint();
      graph.changeData(newFlowData);
      graph.refresh();
      var newViewPoint = graph.getViewPortCenterPoint();
      //更新画布位置
      graph.translate(newViewPoint.x - viewPoint.x, newViewPoint.y - viewPoint.y);
    }
  };
  var onSelect = function onSelect(key) {
    if (!curModel.current) return;
    var curData = cloneDeep(graphRef.current.save()); //当前数据 
    var newData; //更新数据
    if (key === FlowEvent.deleteContent || key === FlowEvent.deleteAfter) {
      if (key === FlowEvent.deleteContent && curModel.current.children.length) {
        var _graphRef$current$fin;
        var parentId = curModel.current.parentConfig.parentId;
        var parentModel = (_graphRef$current$fin = graphRef.current.findById(parentId)) === null || _graphRef$current$fin === void 0 ? void 0 : _graphRef$current$fin.getModel();
        if (parentModel) {
          newData = flowEventService.getNewTreeGraphData(curData, key, curModel.current.id, null);
        }
      } else {
        newData = flowEventService.getNewTreeGraphData(curData, key, curModel.current.id, null);
      }
    } else {
      // 新增逻辑
      var newNode = flowEventService.createFlowNode(curModel, key);
      var isInsertNode = flowEventService.isInsertNode(key, curModel.current);
      newData = flowEventService.getNewTreeGraphData(curData, FlowEvent.insert, curModel.current.id, newNode, isInsertNode);
    }
    //根据新数据进行更新数据源并重新渲染
    updateGraphData(graphRef.current, newData);
    setMenuOpen(false);
    curModel.current = null;
  };
  var onSetterPanelChange = function onSetterPanelChange(value) {
    graphRef.current.updateItem(curModel.current.id, value);
  };
  var DrawCloseFn = function DrawCloseFn() {
    setSettingOpen(false);
  };
  return /*#__PURE__*/React.createElement("div", {
    className: "flowPageMain"
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      height: "calc(100vh - 65px)",
      width: "calc(100vw - 40px)",
      overflowY: "auto",
      overflowX: "hidden",
      backgroundColor: "#F2F7FA"
    },
    ref: refContainer
  }, menuList.length > 0 && /*#__PURE__*/React.createElement(ContextMenu, {
    position: position,
    items: menuList,
    onSelect: onSelect,
    open: menuOpen
  }), /*#__PURE__*/React.createElement(_Drawer, {
    className: "flowEventDrawer",
    title: t("setter.setKey"),
    width: "500px",
    placement: "right",
    visible: settingOpen,
    onClose: DrawCloseFn
  }, curModel.current && /*#__PURE__*/React.createElement(BoxSlotComponent, {
    title: t("setter.nodeDec")
  }, /*#__PURE__*/React.createElement(_Input, {
    hasClear: true,
    value: label,
    style: {
      width: 100 + "%",
      minWidth: 0
    },
    onChange: function onChange(e) {
      setLabel(e);
      onSetterPanelChange(_extends({}, curModel.current, {
        label: e
      }));
    }
  })), SetterPanelMap && SetterPanelMap[(_curModel$current2 = curModel.current) === null || _curModel$current2 === void 0 ? void 0 : _curModel$current2.type] && /*#__PURE__*/React.createElement(SetterPanelMap[(_curModel$current3 = curModel.current) === null || _curModel$current3 === void 0 ? void 0 : _curModel$current3.type], {
    current: curModel.current,
    onChange: onSetterPanelChange
  }))));
});
export default FlowPage;