import { IAppLoad, NsGraphCmd } from '@antv/xflow';
import React, { useRef, useEffect, useImperativeHandle } from 'react';
/** 交互组件 */
import {
  /** XFlow核心组件 */
  XFlow,
  /** 流程图画布组件 */
  FlowchartCanvas,
  /** 流程图配置扩展 */
  FlowchartExtension,
  /** 流程图节点组件 */
  FlowchartNodePanel,
  /** 流程图表单组件 */
  FlowchartFormPanel,
  /** 通用组件：快捷键 */
  KeyBindings,
  /** 通用组件：画布缩放 */
  CanvasScaleToolbar,
  /** 通用组件：右键菜单 */
  CanvasContextMenu,
  /** 通用组件：工具栏 */
  CanvasToolbar,
  /** 通用组件：对齐线 */
  CanvasSnapline,
  /** 通用组件：节点连接桩 */
  CanvasNodePortTooltip,
  IApplication,
  XFlowNodeCommands,
} from '@antv/xflow';
import { Graph } from '@antv/x6';
/** 配置Command*/
import { useCmdConfig, initGraphCmds } from './config-cmd';
/** 配置Menu */
import { useMenuConfig } from './config-menu';
/** 配置Toolbar */
import { TOOLBAR_ITEMS, useToolbarConfig } from './config-toolbar';
/** 配置快捷键 */
import { useKeybindingConfig } from './config-keybinding';
import { registerNode } from './node/registerNode';
import CustomFlowchartFormPanel from './node/FlowFormPanel';
/** 配置Dnd组件面板 */
// import CustomCircle from './react-node/CustomCircle';
// import CustomRect from './react-node/CustomRect';

import '@antv/xflow/dist/index.css';
import './index.less';
import { TYPE } from './node/auditNode/mapServe';

export interface IProps {
  meta: { flowId: string; type: 'edit' };
  flowDetail: any;
  onSelectNode?: Function;
  parentRef?: any;
}

export const Demo: React.FC<IProps> = props => {
  const { meta, flowDetail, parentRef } = props;
  const isEdit = meta.type == 'edit';
  const toolbarConfig = useToolbarConfig();
  const menuConfig = useMenuConfig();
  const keybindingConfig = useKeybindingConfig();
  const graphRef = useRef<Graph>();
  const appRef = useRef<IApplication>();
  const commandConfig: any = useCmdConfig(props);

  // 封装供外部主动调用的接口
  useImperativeHandle(parentRef, () => ({
    getGraphData: async cb => {
      appRef.current.commandService.executeCommand<NsGraphCmd.SaveGraphData.IArgs>(
        TOOLBAR_ITEMS.SAVE_GRAPH_DATA,
        {
          saveGraphDataService: (meta, graphData) => {
            let data = JSON.parse(JSON.stringify(graphData));
            let simpleNodes = data?.nodes?.map(curNode => {
              let childrenNodes = data.edges
                .map(edge => {
                  if (edge.source?.cell == curNode.id) {
                    return data.nodes.find(item => item.id == edge.target?.cell);
                  }
                })
                .filter(item => item);
              //按优先级排序子节点
              const children = childrenNodes
                .sort((a, b) => a.priority - b.priority)
                .map(item => item.id);
              const node = {
                id: curNode.id,
                type: curNode.type,
                //条件节点
                formItems:
                  curNode.type == TYPE.JUDGE && !curNode.formItems ? '[]' : curNode.formItems,
                priority: curNode.priority,
                //审批节点
                initiator: curNode.type == TYPE.INITIATOR ? curNode.initiator : null,
                audits: curNode.type == TYPE.AUDIT ? curNode.audits : null,
                children: children,
              };
              return node;
            });
            data.nodes = data.nodes.map(item => {
              let newItem = JSON.parse(JSON.stringify(item));
              delete newItem.incomingEdges;
              delete newItem.originData;
              delete newItem.outgoingEdges;
              delete newItem.ports.groups;
              // let ports = { ...item.ports };
              // delete ports.groups;
              // return {
              //   id: item.id,
              //   renderKey: item.renderKey,
              //   name: item.name,
              //   label: item.label,
              //   width: item.width,
              //   height: item.height,
              //   ports: ports,
              //   isCustom: item.isCustom,
              //   parentKey: item.parentKey,
              //   x: item.x,
              //   y: item.y,
              //   zIndex: item.zIndex,
              //   count: item.count,
              // };
              return newItem;
            });
            // graphData.edges = []
            data.edges = data.edges.map(item => {
              // delete item.data;
              // delete item.attrs;
              // delete item.sourcePort;
              // delete item.sourcePortId;
              // delete item.targetPort;
              // delete item.targetPortId;
              // delete item.zIndex;
              return {
                id: item.id,
                source: item.source,
                target: item.target,
                // attr: JSON.stringify(item.attrs),
              };
            });

            console.log(simpleNodes);
            console.log(JSON.stringify(data));
            cb?.(JSON.stringify(data), JSON.stringify(simpleNodes));
            return data;
          },
        }
      );
    },
  }));
  /**
   * @param app 当前XFlow工作空间
   * @param extensionRegistry 当前XFlow配置项
   */
  const onLoad: IAppLoad = async app => {
    appRef.current = app;
    graphRef.current = await app.getGraphInstance();
    // graphRef.current.disableSnapline()
    renderGraph();
  };

  const renderGraph = () => {
    if (flowDetail.nodes.length == 0 || !appRef.current) return;
    initGraphCmds(appRef.current, flowDetail);
    // 设置选中状态
    const node = flowDetail.nodes.find(item => item.isCheck);
    if (node) {
      const args = {
        nodeIds: [node.id],
        resetSelection: true,
      };
      setTimeout(() => {
        appRef.current.commandService.executeCommand(XFlowNodeCommands.SELECT_NODE.id, args);
      }, 100);
    }
  };
  const getConfig = () => {
    const defaultOption = {
      grid: 1,
      mousewheel: {
        enabled: true,
        /** 将鼠标位置作为中心缩放 */
        zoomAtMousePosition: true,
      },
      resizing: {
        enabled: true,
        minWidth: 0,
        minHeight: 0,
        preserveAspectRatio: false,
      },
      snapline: false,
    };
    return isEdit
      ? defaultOption
      : {
          ...defaultOption,
          grid: false,
          resizing: false,
          panning: false,
          selecting: {
            enabled: true,
            showNodeSelectionBox: true,
          },
          interacting: false,
          mousewheel: false,
          connecting: {
            highlight: false,
            allowBlank: false,
            allowPort: false,
            dangling: false,
          },
        };
  };
  useEffect(() => {
    if (graphRef.current) {
      graphRef.current.on('node:click', (...arg) => {
        console.log(arg);
      });
    }
  }, [graphRef]);

  useEffect(() => {
    renderGraph();
  }, [flowDetail, appRef.current]);

  return (
    <XFlow
      className="flow-user-custom-clz"
      commandConfig={commandConfig}
      onLoad={onLoad}
      meta={meta}
    >
      <FlowchartNodePanel
        registerNode={{
          title: '节点',
          key: 'custom',
          nodes: registerNode,
        }}
        showOfficial={false}
        defaultActiveKey={['custom']}
        position={{ width: 162, top: 40, bottom: 0, left: isEdit ? 0 : -999 }}
      />
      {isEdit && (
        <CanvasToolbar
          className="xflow-workspace-toolbar-top"
          layout="horizontal"
          config={toolbarConfig}
          position={{ top: 0, left: 0, right: 0, bottom: 0 }}
        />
      )}
      <FlowchartCanvas
        config={getConfig()}
        position={{ top: isEdit ? 40 : 0, left: 0, right: 0, bottom: 0 }}
      >
        {isEdit && (
          <>
            <CanvasScaleToolbar
              layout="horizontal"
              position={{ top: -40, right: 0 }}
              style={{
                width: 150,
                left: 'auto',
                height: 39,
              }}
            />
            <CanvasContextMenu config={menuConfig} />
            <CanvasSnapline color="#faad14" />
            <CanvasNodePortTooltip />
          </>
        )}
      </FlowchartCanvas>
      {isEdit && (
        <>
          <FlowchartExtension />
          {/* <FlowchartFormPanel show={true} position={{ width: 200, top: 40, bottom: 0, right: 0 }} /> */}
          <CustomFlowchartFormPanel />
          <KeyBindings config={keybindingConfig} />
        </>
      )}
    </XFlow>
  );
};

// 高阶组件
const DemoHoc = Demo => {
  const forwardRef = (props, ref) => {
    return <Demo parentRef={ref} {...props}></Demo>;
  };
  return React.forwardRef(forwardRef);
};

export default DemoHoc(Demo);
