import * as go from "gojs";
import { ReactDiagram, ReactPalette } from "gojs-react";
import * as React from "react";
// import { FLOWCHART } from "../../resources/ui/gojs/graph-types/flowchart";
import { UMLCHART as FLOWCHART } from "../../resources/ui/gojs/graph-types/uml";
import { transitionTemplate } from "../../resources/ui/gojs/nodes/transition";
// props passed in from a parent component holding state, some of which will be passed to ReactDiagram
interface WrapperProps {
  nodeDataArray: Array<go.ObjectData>;
  linkDataArray: Array<go.ObjectData>;
  modelData: go.ObjectData;
  skipsDiagramUpdate: boolean;
  onDiagramEvent: (e: go.DiagramEvent) => void;
  onModelChange: (e: go.IncrementalData) => void;
}

export class DiagramWrapper extends React.Component<WrapperProps, {}> {
  /**
   * Ref to keep a reference to the component, which provides access to the GoJS diagram via getDiagram().
   */
  private diagramRef: React.RefObject<ReactDiagram>;
  private paletteRef: React.RefObject<ReactPalette>;

  constructor(props: WrapperProps) {
    super(props);
    this.diagramRef = React.createRef();
    this.paletteRef = React.createRef();
  }

  /**
   * Get the diagram reference and add any desired diagram listeners.
   * Typically the same function will be used for each listener,
   * with the function using a switch statement to handle the events.
   * This is only necessary when you want to define additional app-specific diagram listeners.
   */
  public componentDidMount() {
    if (!this.diagramRef.current) return;
    const diagram = this.diagramRef.current.getDiagram();
    if (diagram instanceof go.Diagram) {
      diagram.div.style.height = "800px";
      diagram.div.style.width = "1000px";
      diagram.nodeTemplateMap.add("transition", transitionTemplate());
      diagram.linkTemplateMap;
      diagram.addDiagramListener("ChangedSelection", (e) => {});
    }

    if (!this.paletteRef.current) return;
    const palette = this.paletteRef.current.getPalette();

    palette.div.style.height = "800px";
    palette.div.style.width = "1000px";
  }

  /**
   * Get the diagram reference and remove listeners that were added during mounting.
   * This is only necessary when you have defined additional app-specific diagram listeners.
   */
  public componentWillUnmount() {
    if (!this.diagramRef.current) return;
    const diagram = this.diagramRef.current.getDiagram();
    if (diagram instanceof go.Diagram) {
      diagram.removeDiagramListener(
        "ChangedSelection",
        this.props.onDiagramEvent
      );
    }
  }

  onModelChange(...args) {
    console.log(...args);
  }

  /**
   * Diagram initialization method, which is passed to the ReactDiagram component.
   * This method is responsible for making the diagram and initializing the model, any templates,
   * and maybe doing other initialization tasks like customizing tools.
   * The model's data should not be set here, as the ReactDiagram component handles that via the other props.
   */
  private initDiagram(): go.Diagram {
    const diagram = FLOWCHART();

    // diagram.grid.visible = true;
    diagram.toolManager.draggingTool.isGridSnapEnabled = true;
    diagram.toolManager.resizingTool.isGridSnapEnabled = true;

    return diagram;
  }

  public render() {
    return (
      <>
        <ReactDiagram
          ref={this.diagramRef}
          divClassName="none"
          initDiagram={this.initDiagram}
          nodeDataArray={this.props.nodeDataArray}
          linkDataArray={this.props.linkDataArray}
          modelData={this.props.modelData}
          skipsDiagramUpdate={this.props.skipsDiagramUpdate}
        />
        <ReactPalette
          ref={this.paletteRef}
          initPalette={(...args) => {
            const myPalette = new go.Palette();
            // the list of data to show in the Palette

            myPalette.nodeTemplateMap.add("transition", transitionTemplate());

            return myPalette;
          }}
          divClassName="none"
          nodeDataArray={[
            {
              key: 1337,
              label: "Transtion",
              guard: "x+1",
              category: "transition",
              icon:
                "https://maxcdn.icons8.com/Share/icon/Industry/robot1600.png",
              description: "General Legal Division Director",
              serviceName: "testservice",
              serviceInputs: [
                {
                  portId: 21,
                  label: "i1"
                },
                {
                  portId: 22,
                  label: "i2"
                },
                {
                  portId: 23,
                  label: "i3"
                }
              ],
              serviceOutputs: [
                {
                  portId: 10,
                  label: "outp"
                }
              ],
              guardInputs: [
                {
                  portId: 21,
                  label: "g1"
                },
                {
                  portId: 22,
                  label: "g2"
                },
                {
                  portId: 23,
                  label: "g3"
                }
              ],
              guardOutputs: [
                {
                  portId: 10,
                  label: "g1"
                }
              ]
            },
            {}
          ]}
        ></ReactPalette>
      </>
    );
  }
}

export default DiagramWrapper;
