<template>
  <div class="bpmn-element">
    <div class="title"></div>
    <component
      :is="getComponent"
      v-if="element"
      ref="Component"
      :element="element"
      :modeler="modeler"
    />
  </div>
</template>

<script>
import BpmnProcess from "./components/Process";
import BpmnStartEnd from "./components/StartEndNode";
import BpmnUserTask from "./components/UserTaskNode";
import BpmnSequenceFlow from "./components/Condition";

export default {
  components: {
    BpmnProcess,
    BpmnStartEnd,
    BpmnUserTask,
    BpmnSequenceFlow,
  },
  provide() {
    return {
      parseElement: this.parseElement,
      updateProperties: this.updateProperties,
    };
  },
  props: {
    modeler: { type: Object, default: () => null },
  },
  data() {
    return {
      element: null,
    };
  },
  computed: {
    getComponent() {
      const type = this.element?.type;
      if (type === "bpmn:Process") {
        return "BpmnProcess";
      }
      if (
        ["bpmn:EndEvent", "bpmn:StartEvent", "bpmn:ExclusiveGateway"].includes(
          type
        )
      ) {
        return "BpmnStartEnd";
      }
      if (type === "bpmn:UserTask") {
        return "BpmnUserTask";
      }
      if (type === "bpmn:SequenceFlow") {
        return "BpmnSequenceFlow";
      }
      return null;
    },
    showGeneral() {
      return this.element?.type;
    },
    showPerson() {
      return this.element?.type === "bpmn:UserTask";
    },
    showForm() {
      return ![
        "bpmn:StartEvent",
        "bpmn:EndEvent",
        "bpmn:SequenceFlow",
      ].includes(this.element?.type);
    },
  },
  mounted() {
    this.handleModeler();
  },
  methods: {
    handleModeler() {
      this.modeler.on("root.added", (e) => {
        if (e.element.type === "bpmn:Process") {
          this.element = null;
          this.$nextTick().then(() => {
            this.element = e.element;
          });
        }
      });
      this.modeler.on("element.click", (e) => {
        const { element } = e;
        if (element.type === "bpmn:Process") {
          this.element = element;
        }
      });
      this.modeler.on("selection.changed", (e) => {
        // hack 同类型面板不刷新
        this.element = null;
        const element = e.newSelection[0];
        if (element) {
          this.$nextTick().then(() => {
            this.element = element;
          });
        }
      });
    },
    parseElement(element) {
      const result = {
        ...element.businessObject,
        ...element.businessObject.$attrs,
      };
      // 移除flowable前缀，格式化数组
      Object.keys(result).forEach((key) => {
        if (key.indexOf("flowable:") === 0) {
          const newKey = key.replace("flowable:", "");
          result[newKey] = result[key];
          delete result[key];
        }
      });
      if ("documentation" in result) {
        let str = "";
        result.documentation.forEach((item) => {
          str += item.text;
        });
        result.documentation = str;
      }
      return result;
    },
    updateProperties(properties) {
      const modeling = this.modeler.get("modeling");
      modeling.updateProperties(this.element, properties);
    },
  },
};
</script>

<style lang="less">
.bpmn-element {
  height: 100%;
  .ant-tabs {
    height: 100%;
    &-nav {
      .ant-tabs-tab {
        margin-right: 0;
      }
    }
    &-bar {
      margin-bottom: 0;
      padding-right: 14px;
    }
    &-content {
      height: calc(100% - 50px);
    }
    &-tabpane {
      position: relative;
      height: 100%;
      padding-top: 16px;
      overflow-y: auto;
      padding-right: 20px;
    }
  }
}
</style>
