<template>
  <div class="app-container">
    <el-collapse v-model="activeNames" @change="handleChange">
      <el-collapse-item key="common" name="common">
        <div slot="title" class="panel-tab__title"><i class="el-icon-info" />常规</div>
        <ElementBaseInfo
          :id-edit-disabled="idEditDisabled"
          :business-object="elementBusinessObject"
          :type="elementType"
          :model="model"
        />
      </el-collapse-item>
      <el-collapse-item v-if="conditionFormVisible" key="circulationConditions" name="circulationConditions">
        <div slot="title" class="panel-tab__title"><i class="el-icon-s-promotion" />流转条件</div>
        <FlowCondition :business-object="elementBusinessObject" :type="elementType" :model="model" />
      </el-collapse-item>
      <el-collapse-item key="执行监听器" name="3">
        <div slot="title" class="panel-tab__title"><i class="el-icon-message-solid" />执行监听器</div>
        <element-listeners :id="elementId" :type="elementType" />
      </el-collapse-item>
      <el-collapse-item v-if="actionVisible" key="执行动作" name="commandAction">
        <div slot="title" class="panel-tab__title"><i class="el-icon-message-solid" />执行动作</div>
        <ElementAction
          :id="elementId"
          ref="elementAction"
          :type="elementType"
          @elementAction="handleGetAction"
        />
      </el-collapse-item>
      <el-collapse-item key="others" name="others">
        <div slot="title" class="panel-tab__title"><i class="el-icon-s-promotion" />其他</div>
        <element-other-config :id="elementId" />
      </el-collapse-item>
    </el-collapse>

  </div>
</template>

<script>
import ElementBaseInfo from '@/components/BpmnProcessDesigner/package/penal/base/ElementBaseInfo.vue'
import ElementOtherConfig from '@/components/BpmnProcessDesigner/package/penal/other/ElementOtherConfig.vue'
import ElementListeners from '@/components/BpmnProcessDesigner/package/penal/listeners/ElementListeners.vue'
import FlowCondition from './FlowCondition.vue'
import ElementAction from '@/components/BpmnProcessDesigner/package/penal/executeAction/ElementAction.vue'
import ElementTask from '@/components/BpmnProcessDesigner/package/penal/task/ElementTask.vue'
import ElementMultiInstance from '@/components/BpmnProcessDesigner/package/penal/multi-instance/ElementMultiInstance.vue'
import ElementProperties from '@/components/BpmnProcessDesigner/package/penal/properties/ElementProperties.vue'
import UserTaskListeners from '@/components/BpmnProcessDesigner/package/penal/listeners/UserTaskListeners.vue'
import { isArray } from 'min-dash'

export default {
  name: 'EditPanel',
  components: {
    ElementBaseInfo,
    ElementOtherConfig,
    ElementListeners,
    FlowCondition,
    ElementAction,
    ElementTask, // 新增
    ElementMultiInstance, // 新增
    ElementProperties, // 新增
    UserTaskListeners // 新增
  },
  provide() {
    return {
      prefix: this.prefix,
      width: this.width
    }
  },
  props: {
    // 流程模型的数据
    model: {
      type: Object,
      default: () => {}
    },
    idEditDisabled: {
      type: Boolean,
      default: false
    },
    bpmnModeler: {
      type: Object,
      default: () => {}
    },
    prefix: {
      type: String,
      default: 'camunda'
    },
    width: {
      type: Number,
      default: 480
    }
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 导出遮罩层
      exportLoading: false,
      // 显示搜索条件
      showSearch: true,
      actionVisible: false,
      // 总条数
      total: 0,
      // 业务模型定义列表
      list: [],
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      activeNames: 'common',
      createId: null,
      elementId: '',
      elementBusinessObject: {}, // 元素 businessObject 镜像，提供给需要做判断的组件使用
      conditionFormVisible: false, // 流转条件设置
      elementType: '',
      // 流转条件
      flowConditionForm: {
        type: 'normal'
      },
      formVisible: false, // 新增：表单配置
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 10,
        modelCode: null,
        modelName: null,
        modelComment: null,
        remark: null,
        modelEnable: null,
        formId: null,
        pageShow: null,
        bpmEnable: null,
        bpmId: null,
        createTime: []
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        modelName: [{ required: true, message: '业务名称不能为空', trigger: 'blur' }],
        modelComment: [{ required: true, message: '业务描述不能为空', trigger: 'blur' }],
        modelEnable: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
        formId: [{ required: true, message: '表单id不能为空', trigger: 'blur' }],
        pageShow: [{ required: true, message: '页签选项：不能为空', trigger: 'blur' }],
        bpmEnable: [{ required: true, message: '工作流启用标记不能为空', trigger: 'blur' }]
      }
    }
  },
  watch: {
    elementId: {
      handler() {
        this.activeTab = 'base'
      }
    }
  },
  created() {
    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'),
        elementFactory: this.bpmnModeler.get('elementFactory'),
        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 }) => {
        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
      // console.log(`
      //         ----------
      // select element changed:
      //           id:  ${activatedElement.id}
      //         type:  ${activatedElement.businessObject.$type}
      //         ----------
      //         `)
      // console.log('businessObject: ', activatedElement.businessObject)
      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.actionVisible = !!(
        this.elementType === 'UserTask'
      )
      this.formVisible = this.elementType === 'UserTask' || this.elementType === 'StartEvent'
    },
    beforeDestroy() {
      window.bpmnInstances = null
    },
    handleChange(val) {
      console.log(val)
    },
    // 流转条件类型选择
    updateFlowType(v) {
      console.log(v)
    },
    handleGetAction(data, tasks) {
      // const attachList = data[0]?.$attrs.allExtensions
      // if (isArray(attachList)) {
      //   const dealData = attachList.reduce((result, item) => {
      //     const { id, values } = item
      //     const uniqueValues = values.map(value => {
      //       const { value: objValue } = value
      //       const { eTableId, eChangeField, eValue } = objValue
      //       // const uniqueIdentifier = `${id}-${eTableId}-${eChangeField}-${eValue}`
      //       return {
      //         id,
      //         eTableId,
      //         eChangeField,
      //         eValue
      //       }
      //     })
      //     return [...result, ...uniqueValues.filter(obj => !result.some(r => r.id === obj.id))]
      //   }, [])
      const attachList = data.flatMap((item) => item?.$attrs.allExtensions || [])
      if (isArray(attachList)) {
        const dealData = attachList.reduce((result, item) => {
          const { activityId, values } = item
          const uniqueValues = values.map((value) => {
            const { value: objValue } = value
            const { eTableId, eChangeField, eValue } = objValue
            return {
              activityId,
              eTableId,
              eChangeField,
              eValue
            }
          })
          return [...result, ...uniqueValues.filter((obj) => !result.some((r) => r.activityId === obj.activityId && r.eTableId === obj.eTableId && r.eChangeField === obj.eChangeField && r.eValue === obj.eValue))]
        }, [])
        // const allSaveData = tasks.filter((ts) => !dealData.some((deal) => deal.activityId === ts.activityId && deal.eTableId === ts.eTableId && deal.eChangeField === ts.eChangeField && deal.eValue === ts.eValue))
        this.$emit('saveData', dealData)
      } else {
        this.$emit('saveData', [])
      }

      // const dealData = data.reduce((acc, item) => {
      //   const { id, values } = item
      //   values.forEach(value => {
      //     const { value: objValue } = value
      //     const { eTableId, eChangeField, eValue } = objValue
      //     const uniqueIdentifier = `${id}-${eTableId}-${eChangeField}-${eValue}`
      //     acc.add(uniqueIdentifier) // 使用 Set 保证唯一性
      //   })
      //   return acc
      // }, new Set())

      // const uniqueItemsData = Array.from(dealData).map(item => {
      //   const [id, eTableId, eChangeField, eValue] = item.split('-')
      //   return { id, eTableId, eChangeField, eValue }
      // })
      // this.$emit('saveData', dealData)
      // }
    }
  }
}
</script>
