<template>
  <div class="logic-flow-view">
    <!-- 辅助工具栏 -->
    <Control
      class="demo-control"
      :lf="lf"
      v-if="lf && panelConfig"
      :catTurboData="true"
      @catTurboData="$_catTurboData"
      @catSaveData="$_catSaveData"
      @catData="$_catData"
      @deploy="$_deploy"
      @renderImportView="$_renderImportView"
    ></Control>
    <!-- 节点面板 -->
    <NodePanel :lf="lf" :nodeList="panelConfig" v-if="panelConfig"></NodePanel>
    <!-- 画布 -->
    <div id="LF-view" ref="container"></div>
    <!-- 用户节点自定义操作面板 -->
    <AddPanel
      v-if="showAddPanel"
      class="add-panel"
      :style="addPanelStyle"
      :lf="lf"
      :nodeData="addClickNode"
      @addNodeFinish="hideAddPanel"
    >
    </AddPanel>
    <!-- 属性面板 -->
    <el-drawer :visible.sync="dialogVisible" direction="rtl" size="100%">
      <debug
        v-if="dialogVisible"
        :nodeData="clickNode"
        :socketResponse="socketResponse"
        :lf="lf"
        @setPropertiesFinish="setPropertiesFinish"
      ></debug>
    </el-drawer>
    <el-dialog
      title="算法参数配置"
      :visible.sync="algorithmVisible"
      width="60%"
    >
      <algorithmDialog
        v-if="algorithmVisible"
        :nodeData="clickNode"
        :socketResponse="socketResponse"
        :lf="lf"
        @capturePic="capturePic"
        @setPropertiesFinish="setPropertiesFinish"
      ></algorithmDialog>
    </el-dialog>
    <!-- 数据查看面板 -->
    <el-dialog title="数据" :visible.sync="dataVisible" width="50%">
      <DataDialog :graphData="graphData"></DataDialog>
    </el-dialog>
  </div>
</template>
<script>
import LogicFlow from "@logicflow/core";

import { Menu, Snapshot, MiniMap } from "@logicflow/extension";
import "@logicflow/core/dist/style/index.css";
import "@logicflow/extension/lib/style/index.css";
import NodePanel from "./LFComponents/NodePanel";
import AddPanel from "./LFComponents/AddPanel";
import Control from "./LFComponents/Control";
import Debug from "./debug/index.vue";
import DataDialog from "./LFComponents/DataDialog";
import algorithmDialog from "./algorithmConfig";
import Check from "./checkPointDialog/dialog.vue";
import { nodeList } from "./config";
import { toTurboData, toLogicflowData } from "../Util/AdpterForTurbo";
import {
  registerStart,
  registerUser,
  registerEnd,
  registerPush,
  registerdevice,
  registeralgorithm,
  registerScene,
  registerPolyline,
  registerTask,
  registerConnect,
} from "./registerNode";

export default {
  name: "LF",
  components: {
    NodePanel,
    AddPanel,
    Control,
    Debug,
    DataDialog,
    Check,
    algorithmDialog,
  },
  data() {
    let _this = this;
    return {
      versionMenuConfig: {
        X: [
          {
            text: "删除",
            callback(node) {
              _this.lf.deleteNode(node.id);
            },
          },
          {
            text: "单步调试",
            callback(node) {
              _this.$data.clickNode = node;
              const graphData = _this.$data.lf.getGraphData();
              const fromNodesEdge = graphData.edges.find(
                (item) => item.targetNodeId === node.id
              );
              const preNodes = graphData.nodes.find(
                (item) => item.id === fromNodesEdge?.sourceNodeId
              );
              _this.for.preNode = preNodes;
              _this.$data.dialogVisible = true;
            },
          },
        ],
        K: [
          {
            text: "删除",
            callback(node) {
              _this.lf.deleteNode(node.id);
            },
          },
          {
            text: "配置",
            callback(node) {
              _this.$data.clickNode = node;
              const graphData = _this.$data.lf.getGraphData();
              const fromNodesEdge = graphData.edges.find(
                (item) => item.targetNodeId === node.id
              );
              const preNodes = graphData.nodes.find(
                (item) => item.id === fromNodesEdge?.sourceNodeId
              );
              _this.for.preNode = preNodes;

              // this.$emit("capturePic", node, callback);
              // this.capturePic(node);
              _this.preCapturePic(node, (res) => {
                if (res.pic) {
                  _this.$data.algorithmVisible = true;
                } else {
                  _this.$message.error(res.errMsg);
                }
              });
            },
          },
        ],
      },
      for: {},
      reviewRecord: {},
      lf: null,
      showAddPanel: false,
      addPanelStyle: {
        top: 0,
        left: 0,
      },
      nodeData: null,
      addClickNode: null,
      clickNode: null,
      dialogVisible: false,
      graphData: null,
      dataVisible: false,
      algorithmVisible: false,
      config: {
        background: {
          backgroundColor: "#f7f9ff",
        },
        grid: {
          size: 20,
          visible: false,
          type: "mesh",
          config: {
            color: "#ddd",
            thickness: 1,
          },
        },
        keyboard: {
          enabled: true,
        },
        edgeTextDraggable: true,
        hoverOutline: false,
      },
      moveData: {},
      nodeList,
    };
  },
  provide() {
    return {
      provObj: this.for,
    };
  },
  props: {
    panelConfig: Object,
    record: Object,
    socketResponse: Object,
    version: String,
  },
  watch: {
    record: {
      handler(newVal) {
        this.reviewRecord = newVal;
        this.$_render();
      },
      deep: true,
      immediate: true,
    },
  },
  activated() {},
  deactivated() {
    // this.bus.$off("send")
  },
  mounted() {
    this.$_initLf();
    // 禁止监听多个事件
  },
  methods: {
    preCapturePic(record, callback) {
      this.$emit("emitPreCapturePic", record, callback);
    },
    capturePic(record, callback) {
      this.$emit("emitCapturePci", record, callback);
    },
    setPropertiesFinish(record, callback) {
      this.lf.setProperties(record.id, {
        ...record.formData,
      });
      this.algorithmVisible = false;
      this.$emit("emitTransfromRecord", record.formData, callback);
    },
    $_catTurboData() {
      const graphData = this.$data.lf.getGraphData();
      // 数据转化为Turbo识别的数据结构
      this.$data.graphData = toTurboData(graphData);
      this.$data.dataVisible = true;
    },
    $_deploy() {
      this.$emit("emitDeploy");
    },
    $_catSaveData() {
      const graphData = this.$data.lf.getGraphData();
      // 数据转化为Turbo识别的数据结构

      this.$data.graphData = toTurboData(graphData);
      this.$emit("emitPostGraphData", this.$data.graphData);
    },
    $_initLf() {
      // 画布配置
      const lf = new LogicFlow({
        ...this.config,
        plugins: [MiniMap, Snapshot, Menu],
        container: this.$refs.container,
      });
      this.lf = lf;

      // 设置主题
      lf.setTheme({
        circle: {
          stroke: "#000000",
          strokeWidth: 1,
          outlineColor: "#88f",
        },
        rect: {
          outlineColor: "#88f",
          strokeWidth: 1,
        },
        polygon: {
          strokeWidth: 1,
        },
        polyline: {
          stroke: "#000000",
          hoverStroke: "#000000",
          selectedStroke: "#000000",
          outlineColor: "#88f",
          strokeWidth: 1,
        },
        nodeText: {
          color: "#000000",
        },
        edgeText: {
          color: "#000000",
          background: {
            fill: "#f7f9ff",
          },
        },
      });
      this.$_renderMenu();
      this.$_registerNode();
    },
    $_renderMenu() {
      let _this = this;
      this.lf.extension.menu.setMenuConfig({
        nodeMenu: this.versionMenuConfig[_this.version],
        // 覆盖默认的节点右键菜单
        edgeMenu: true, // 删除默认的边右键菜单
        graphMenu: [], // 覆盖默认的边右键菜单，与false表现一样
      });
    },
    // 自定义
    $_registerNode() {
      registerStart(this.lf);
      registerUser(this.lf);
      registerEnd(this.lf);
      registerPush(this.lf, this.clickPlus, this.mouseDownPlus);
      registerdevice(this.lf);
      registeralgorithm(this.lf);
      registerScene(this.lf);
      registerPolyline(this.lf);
      registerTask(this.lf);
      registerConnect(this.lf);
      this.$_render();
    },
    $_render() {
      const lFData = toLogicflowData(
        JSON.parse(JSON.stringify(this.reviewRecord))
      );
      if (this.lf) {
        this.lf.render(lFData);
        // this.lf.render(demoData)
        this.$_LfEvent();
      }
    },
    $_renderImportView(lFData) {
      this.lf.render(lFData);
      this.$_LfEvent();
    },
    $_getData() {
      const data = this.lf.getGraphData();
      console.log(JSON.stringify(data));
    },
    $_LfEvent() {
      this.lf.on("node:click", ({ data }) => {
        console.log(data);
      });
      this.lf.on("edge:click", ({ data }) => {
        console.log("edge:click", data);
        // this.$data.clickNode = data
        // this.$data.dialogVisible = true
      });
      this.lf.on("element:click", () => {
        this.hideAddPanel();
      });
      this.lf.on("edge:add", ({ data }) => {
        console.log("edge:add", data);
      });
      this.lf.on("node:mousemove", ({ data }) => {
        console.log("node:mousemove");
        this.moveData = data;
      });
      this.lf.on("blank:click", () => {
        this.hideAddPanel();
      });
      this.lf.on("connection:not-allowed", (data) => {
        this.$message({
          type: "error",
          message: data.msg,
        });
      });
      this.lf.on("node:mousemove", () => {
        console.log("on mousemove");
      });
    },
    clickPlus(e, attributes) {
      e.stopPropagation();
      const { clientX, clientY } = e;
      this.$data.addPanelStyle.top = clientY - 40 + "px";
      this.$data.addPanelStyle.left = clientX + "px";
      this.$data.showAddPanel = true;
      this.$data.addClickNode = attributes;
    },
    mouseDownPlus(e, attributes) {
      e.stopPropagation();
      console.log("mouseDownPlus", e, attributes);
    },
    hideAddPanel() {
      this.$data.showAddPanel = false;
      this.$data.addPanelStyle.top = 0;
      this.$data.addPanelStyle.left = 0;
      this.$data.addClickNode = null;
    },
    closeSocket() {
      this.$emit("emitTransfromRecord", { closeSocket: true });
    },

    $_catData() {
      this.$data.graphData = this.$data.lf.getGraphData();
      this.$data.dataVisible = true;
    },
    goto() {
      this.$router.push("/TurboAdpter");
    },
  },
};
</script>
<style lang="scss">
.logic-flow-view {
  height: 100vh;
  position: relative;
}
.demo-title {
  text-align: center;
  margin: 20px;
}
.demo-control {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
}
#LF-view {
  width: calc(100%);
  height: 100%;
  outline: none;
}
.time-plus {
  cursor: pointer;
}
.add-panel {
  position: absolute;
  z-index: 11;
  background-color: white;
  padding: 10px 5px;
}
.el-drawer__body {
  height: 80%;
  overflow: auto;
  margin-top: -30px;
  z-index: 3;
}

.uml-wrapper {
  background: #0073e5;
  border-radius: 3px;
  width: 100%;
  color: #fff;
  display: flex;
  height: 100%;
  box-sizing: border-box;
  justify-content: center;
  align-items: center;
  .uml-name {
    margin-left: 8px;
  }
}

.uml-head {
  text-align: center;
  line-height: 30px;
  font-size: 16px;
  font-weight: bold;
}

.uml-body {
  padding: 5px 10px;
  font-size: 12px;
}

.uml-footer {
  padding: 5px 10px;
  font-size: 14px;
}
</style>
