<template>
  <div class="process-panel__container" :style="{ width: `${this.width}px` }">
    <a-collapse v-model="activeTab" expandIconPosition="right">
      <a-collapse-panel key="base">
        <div slot="header" class="panel-tab__title"><a-icon type="setting" />常规</div>
        <element-base-info :id-edit-disabled="idEditDisabled" :business-object="elementBusinessObject" :type="elementType" />
      </a-collapse-panel >
      <a-collapse-panel v-if="elementType === 'Process'" key="message">
        <div slot="header" class="panel-tab__title"><a-icon type="message" />消息与信号</div>
        <signal-and-massage />
      </a-collapse-panel >
      <a-collapse-panel v-if="conditionFormVisible" key="condition">
        <div slot="header" class="panel-tab__title"><a-icon type="bell" />流转条件</div>
        <flow-condition :business-object="elementBusinessObject" :type="elementType" />
      </a-collapse-panel >
      <a-collapse-panel v-if="formVisible" key="form">
        <div slot="header" class="panel-tab__title"><a-icon type="container" />表单</div>
        <element-form :id="elementId" :type="elementType" />
      </a-collapse-panel >
      <a-collapse-panel v-if="elementType.indexOf('Task') !== -1" key="task">
        <div slot="header" class="panel-tab__title"><a-icon type="carry-out" />任务</div>
        <element-task :id="elementId" :type="elementType" :business-object="elementBusinessObject" ref="elementTask">
          <template #assignee="{assignee}">
            <slot v-bind:assignee="assignee" name="assignee"></slot>
          </template>
          <template #candidateUsers="{candidateUsers}">
            <slot v-bind:candidateUsers="candidateUsers" name="candidateUsers"></slot>
          </template>
          <template #candidateGroups="{candidateGroups}">
            <slot v-bind:candidateGroups="candidateGroups" name="candidateGroups"></slot>
          </template>
        </element-task>
      </a-collapse-panel >
      <a-collapse-panel v-if="elementType.indexOf('Task') !== -1" key="multiInstance">
        <div slot="header" class="panel-tab__title"><a-icon type="apartment" />多实例</div>
        <element-multi-instance ref="elementMultiInstance" :business-object="elementBusinessObject" :type="elementType">
          <template #collection="{collection}">
            <slot v-bind:collection="collection" name="collection"></slot>
          </template>
        </element-multi-instance>
      </a-collapse-panel >
    <a-collapse-panel v-if="elementType.indexOf('BoundaryEvent')!==-1" key="BoundaryEvent">
            <div slot="header" class="panel-tab__title"><a-icon type="bell" />详情</div>
    <BoundaryEventModule ref="boundaryEventModule" :business-object="elementBusinessObject" :type="elementType">

    </BoundaryEventModule>
    </a-collapse-panel>
      <a-collapse-panel key="listeners" >
        <div slot="header" class="panel-tab__title"><a-icon type="bell" />执行监听器</div>
        <element-listeners :id="elementId" :type="elementType" />
      </a-collapse-panel >
      <a-collapse-panel v-if="elementType === 'UserTask'" key="taskListeners">
        <div slot="header" class="panel-tab__title"><a-icon type="bell" />任务监听器</div>
        <user-task-listeners :id="elementId" :type="elementType" />
      </a-collapse-panel >
      <a-collapse-panel key="extensions" >
        <div slot="header" class="panel-tab__title"><a-icon type="plus-circle" />扩展属性</div>
        <element-properties :id="elementId" :type="elementType" />
      </a-collapse-panel>
      <a-collapse-panel key="other">
        <div slot="header" class="panel-tab__title"><a-icon type="tool" />其他</div>
        <element-other-config :id="elementId" />
      </a-collapse-panel >
    </a-collapse>
  </div>
</template>
<script>
import ElementBaseInfo from './base/ElementBaseInfo'
import ElementOtherConfig from './other/ElementOtherConfig'
import ElementTask from './task/ElementTask'
import ElementMultiInstance from './multi-instance/ElementMultiInstance'
import FlowCondition from './flow-condition/FlowCondition'
import SignalAndMassage from './signal-message/SignalAndMessage'
import ElementListeners from './listeners/ElementListeners'
import ElementProperties from './properties/ElementProperties'
import ElementForm from './form/ElementForm'
import UserTaskListeners from './listeners/UserTaskListeners'
import BoundaryEventModule from './boundary-event/BoundaryEventModule.vue'
// import BpmnModeler from 'bpmn-js/lib/Modeler'
/**
 * 侧边栏
 * @Author MiyueFE
 * @Home https://github.com/miyuesc
 * @Date 2021年3月31日18:57:51
 */
export default {
  name: 'MyPropertiesPanel',
  components: {
    UserTaskListeners,
    ElementForm,
    ElementProperties,
    ElementListeners,
    SignalAndMassage,
    FlowCondition,
    ElementMultiInstance,
    ElementTask,
    ElementOtherConfig,
    ElementBaseInfo,
    BoundaryEventModule
},
  componentName: 'MyPropertiesPanel',
  props: {
    bpmnModeler: Object,
    prefix: {
      type: String,
      default: 'activiti'
    },
    width: {
      type: Number,
      default: 480
    },
    idEditDisabled: {
      type: Boolean,
      default: false
    },
    assignee: {
      type: Array,
      default: () => [
        { username: 'admin', realname: '管理员' }
      ]
    },
    candidateUsers: {
      type: Array,
      default: () => []
    },
    candidateGroups: {
      type: Array,
      default: () => []
    }
  },
  provide() {
    return {
      prefix: this.prefix,
      width: this.width,
      assignee: this.assignee,
      candidateUsers: this.candidateUsers,
      candidateGroups: this.candidateGroups
    }
  },
  data() {
    return {
      activeTab: 'base',
      elementId: '',
      elementType: '',
      elementBusinessObject: {}, // 元素 businessObject 镜像，提供给需要做判断的组件使用
      conditionFormVisible: false, // 流转条件设置
      formVisible: false // 表单配置
    }
  },
  watch: {
    elementId: {
      handler() {
        // this.activeTab = 'base'
      }
    }
  },
  mounted() {
    this.initModels()
  },
  methods: {
    initModels() {
      // 初始化 modeler 以及其他 moddle
      if (!this.bpmnModeler) {
        // 避免加载时 流程图 并未加载完成
        this.timer = setTimeout(() => this.initModels(), 10)
        return
      }
      if (this.timer) clearTimeout(this.timer)
      window.bpmnInstances = {
        modeler: this.bpmnModeler,
        modeling: this.bpmnModeler.get('modeling'),
        moddle: this.bpmnModeler.get('moddle'),
        eventBus: this.bpmnModeler.get('eventBus'),
        bpmnFactory: this.bpmnModeler.get('bpmnFactory'),
        elementRegistry: this.bpmnModeler.get('elementRegistry'),
        replace: this.bpmnModeler.get('replace'),
        selection: this.bpmnModeler.get('selection')
      }
      this.getActiveElement()
    },
    getActiveElement() {
      // 初始第一个选中元素 bpmn:Process
      this.initFormOnChanged(null)
      this.bpmnModeler.on('import.done', e => {
        this.initFormOnChanged(null)
      })
      // 监听选择事件，修改当前激活的元素以及表单
      this.bpmnModeler.on('selection.changed', ({ newSelection }) => {
        console.log('newSelection', newSelection)
        this.initFormOnChanged(newSelection[0] || null)
      })
      this.bpmnModeler.on('element.changed', ({ element }) => {
        // 保证 修改 "默认流转路径" 类似需要修改多个元素的事件发生的时候，更新表单的元素与原选中元素不一致。
        if (element && element.id === this.elementId) {
          this.initFormOnChanged(element)
        }
      })
    },
    // 初始化数据
    initFormOnChanged(element) {
      let activatedElement = element
      if (!activatedElement) {
        activatedElement =
          window.bpmnInstances.elementRegistry.find(el => el.type === 'bpmn:Process') ??
          window.bpmnInstances.elementRegistry.find(el => el.type === 'bpmn:Collaboration')
      }
      if (!activatedElement) return
      window.bpmnInstances.bpmnElement = activatedElement
      this.bpmnElement = activatedElement
      this.elementId = activatedElement.id
      this.elementType = activatedElement.type.split(':')[1] || ''
      this.elementBusinessObject = JSON.parse(JSON.stringify(activatedElement.businessObject))
      this.conditionFormVisible = !!(
        this.elementType === 'SequenceFlow' &&
        activatedElement.source &&
        activatedElement.source.type.indexOf('StartEvent') === -1
      )
      this.formVisible = this.elementType === 'UserTask' || this.elementType === 'StartEvent'
    },
    beforeDestroy() {
      window.bpmnInstances = null
    },
    updateElementTask(key, val) {
      const taskAttr = Object.create(null)
      taskAttr[key] = val || null
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr)
    },
    updateLoop(key, val) {
      this.$refs.elementMultiInstance.updateLoop(key, val)
    }
  }
}
</script>
