<template>
  <div class="start-button-group">
    <el-button
      v-for="(btn, index) in startButtonList"
      :key="index"
      :type="btn.alias === 'startFlow' ? 'primary' : 'default'"
      :loading="btn.alias === 'startFlow' ? startFlowLoading : saveDraftLoading"
      :disabled="startFlowLoading"
      @click="handleClick(btn.alias)"
    >
      {{ btn.name }}
    </el-button>
    <el-button :disabled="startFlowLoading" @click="handleOpenFlowChart">
      流程图
    </el-button>
    <el-button :disabled="startFlowLoading" @click="showFigureDialog">
      预测图
    </el-button>
    <el-button v-print="'#flow-form-container'" :disabled="startFlowLoading">
      打印
    </el-button>
    <el-button :disabled="startFlowLoading" @click="handleCancel">
      取消
    </el-button>
    <!-- 选择待办任务节点弹窗 -->
    <todo-task-dialog ref="todoTaskDialog" :table-data="tableData" />
    <!-- 选择路径跳转 -->
    <select-path-to-jump ref="selectPathJump" is-show-dialog alias="process" />
    <!-- 流程图 -->
    <ht-flow-chart
      ref="flowChart"
      :def-id="defId"
      custom-class="start-btn__flow-chart"
    />
    <!-- 审批预测 -->
    <processForecast
      ref="processForecast"
      :inst-id="instId"
      :data="data"
      :def-id="defId"
    ></processForecast>
    <el-dialog
      title="执行人为空时由发起人指定"
      :visible.sync="executorIsEmptyDialog"
      :close-on-click-modal="false"
      :show-close="false"
      append-to-body
    >
      <el-form v-form>
        <ht-form-item label="审批人员">
          <ht-user-selector-input
            v-model="userSelectValue"
            permission="b"
            :config="{ id: 'user.id', fullname: 'user.fullname' }"
            :append-to-body="true"
            single
          ></ht-user-selector-input>
        </ht-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="confirm">
          确 定
        </el-button>
      </div>
    </el-dialog>
    <el-dialog
      title="自定义流程步骤"
      :visible.sync="freedomDialog"
      :close-on-click-modal="false"
      :show-close="false"
      append-to-body
      width="940px"
    >
      <el-form v-form data-vv-scope="freedomDataForm">
        <el-button
          @click="
            freedomData.push({
              nodeName: '',
              nodeType: '',
              userName: '',
              userId: '',
              account: '',
              field: '',
            })
          "
        >
          添加
        </el-button>
        <el-table :data="freedomData" style="width: 100%">
          <el-table-column label="节点名称">
            <template slot-scope="scope">
              <ht-input
                v-model="freedomData[scope.$index].nodeName"
                :validate="'required'"
              ></ht-input>
            </template>
          </el-table-column>
          <el-table-column label="节点类型">
            <template slot-scope="scope">
              <ht-select
                v-model="freedomData[scope.$index].nodeType"
                :options="[
                  { key: '1', value: '用户任务' },
                  { key: '2', value: '会签并行' },
                  { key: '3', value: '会签串行' },
                ]"
                :validate="'required'"
              ></ht-select>
            </template>
          </el-table-column>
          <el-table-column label="节点审批人">
            <template slot-scope="scope">
              <ht-user-selector-input
                v-model="freedomData[scope.$index].userName"
                permission="b"
                :config="{
                  id: `freedomData[${scope.$index}].userId`,
                  account: `freedomData[${scope.$index}].account`,
                }"
                :append-to-body="true"
              ></ht-user-selector-input>
            </template>
          </el-table-column>
          <el-table-column label="节点表单授权" width="130">
            <template slot-scope="scope">
              <el-button @click="setAuth(scope.$index)">授权</el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="50">
            <template slot-scope="scope">
              <i
                class="el-icon-delete"
                @click="freedomData.splice(scope.$index, 1)"
              ></i>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button
          size="small"
          @click="
            freedomDialog = false
            startFlowLoading = false
          "
        >
          取消
        </el-button>
        <el-button
          type="primary"
          size="small"
          :disabled="freedomDisalied"
          @click="freedomConfirm"
        >
          确 定
        </el-button>
      </div>
    </el-dialog>
    <flow-form-auth ref="flowFormAuth" @setValue="setValue" />
  </div>
</template>

<script>
  import print from '@/assets/print'

  import req from '@/utils/request'
  import TodoTaskDialog from './TodoTaskDialog'
  import SelectPathToJump from '@/views/matter/components/SelectPathToJump'
  import processForecast from '@/views/matter/processForecast/processForecast.vue'

  import approvalButton from '@/mixins/approvalButton'
  import fromModule from '@/mixins/fromModule'
  const flowFormAuth = () => import('@/views/matter/newMatter/FlowFormAuth.vue')

  import {
    getAfterJumpNodesByDefId,
    startProcess,
    savaProcessDraft,
    getInstanceByInstId,
  } from '@/api/process'

  import { validObject } from '@/utils'
  import { resultJudge } from '@/utils/event.js'
  import { Base64 } from 'js-base64'

  //别名对应点击事件
  const EVENT_MAP = {
    startFlow: 'handleStartProcess',
    saveDraft: 'savaDraftBeforeRunBeforeScript',
  }
  export default {
    name: 'StartButtonGroup',
    components: {
      TodoTaskDialog,
      SelectPathToJump,
      flowFormAuth,
      processForecast,
    },
    directives: {
      print,
    },
    mixins: [approvalButton, fromModule],
    props: {
      flowObject: {
        type: Object,
        default: () => {
          return {}
        },
      },
      startButtonList: {
        type: Array,
        default: () => {
          return []
        },
      },
      approvalFormData: {
        type: Object,
        default: () => {
          return {}
        },
      },
      data: {
        type: Object,
        default: () => {
          return {}
        },
      },
      formKey: {
        type: String,
        default: '',
      },
      beforeClick: {
        type: Function,
        default: null,
      },
      mainDefId: {
        type: String,
        default: '',
      },
      formType: {
        type: String,
        default: 'INNER',
      },
    },
    data() {
      return {
        freedomDisalied: false,
        freedomData: [],
        freedomDialog: false,
        updateSubTableJson: '',
        tableData: [],
        executorIsEmptyDialog: false,
        user: {
          id: '',
          fullname: '',
        },
        userSelectValue: '',
        EipUserSelectorData: {},
        executorIsEmptyInsts: {},
        executorIsEmptyRow: {},
        flowData: {},
        startFlowLoading: false,
        saveDraftLoading: false,
        currentAlias: '',
        selectIndex: 0,
        resInstId: '',
      }
    },
    computed: {
      defId() {
        return this.$route.query.defId || this.mainDefId
      },
      instId() {
        return this.$route.query?.instId || ''
      },
      processName() {
        return this.$route.query.name
      },
      instStatus() {
        return this.$route.query?.instStatus || ''
      },
      copyInstId() {
        return this.$route.query.copyInstId
      },
    },
    methods: {
      setValue(val) {
        this.freedomData[this.selectIndex].field = val
      },
      setAuth(index) {
        this.selectIndex = index
        let param = {
          flowKey: this.flowObject.defKey,
          formKey: this.formKey,
          nodeId: 'userTask' + (index + 1),
          parentflowKey: '',
          type: '1',
          // bpmnDefId: 'zyxzylccs:1:1596031489851453440',
          bpmnDefId: '',
        }
        this.$refs.flowFormAuth.showDialog(param)
      },
      freedomConfirm() {
        if (this.freedomData && this.freedomData.length == 0) {
          this.$message.error(`请至少添加一个节点!`)
          return
        }
        this.$root.$validator
          .validateAll('freedomDataForm')
          .then((result) => {
            if (result) {
              this.freedomDisalied = true
              this.startProcess()
            } else {
              this.$message.error(`还有内容未填写`)
            }
          })
          .catch((items) => {
            this.$message.error(`还有内容未填写`)
          })
          .finally(() => {
            this.freedomDisalied = false
            this.startFlowLoading = false
            this.loading = false
          })
      },
      handleClick(alias) {
        this.currentAlias = alias
        if (alias == 'startFlow') {
          if (this.beforeClick) {
            resultJudge(this.beforeClick(alias)).then((result) => {
              if (result) {
                this.startFlowLoading = true
                this.handleStartProcess()
              }
            })
          } else {
            this.startFlowLoading = true
            this.handleStartProcess()
          }
        }
        if (alias == 'saveDraft') {
          this.saveDraftLoading = true
          this.savaDraftBeforeRunBeforeScript()
        }
      },
      handleStartProcess() {
        //执行前置脚本
        this.submitBefore('startFlow', 'isNewProcess')
        this.submitAfter('startFlow')
      },
      onSubmit() {
        if (this.currentAlias === 'saveDraft') {
          this.handleSavaDraft(false)
        } else {
          this.getAfterJumpNodes()
        }
      },
      setFormData() {
        const currentUrgentConfig = localStorage.getItem('urgentStateValue')
        let instId = this.instId
        if (this.$route.query.instId) {
          instId = this.$route.query.instId
        }
        let data = {
          defId: this.defId,
          formKey: this.formKey,
          supportMobile: 0,
          proInstId: instId,
          startOrgId: '',
          urgentStateValue: currentUrgentConfig
            ? JSON.parse(currentUrgentConfig)
            : '',
          freedomData: this.freedomData,
        }
        // URL表单合并参数
        if (this.formType == 'FRAME') {
          Object.assign(data, this.approvalFormData)
        } else {
          // 在线表单则设置data属性
          data.data = Base64.encode(JSON.stringify(this.approvalFormData))
        }

        // 领导秘书代理领导发起流程
        if (this.leaderId) {
          data.agentLeaderId = this.leaderId
        }
        return data
      },
      //启动流程
      startProcess() {
        const data = this.setFormData()
        const formImportTempJson = sessionStorage.getItem('formImportTempJson')
        if (formImportTempJson) {
          data.updateSubTableJson = formImportTempJson
        }
        startProcess(validObject(data))
          .then((res) => {
            getInstanceByInstId(res.instId, async (insts) => {
              if (res.state) {
                this.freedomDisalied = false
                // 保存版本号自增1
                Object.keys(this.data).forEach((key) => {
                  const dataVal = this.data[key]
                  if (dataVal && typeof dataVal.form_data_rev_ == 'number') {
                    dataVal.form_data_rev_++
                  } else if (dataVal && typeof dataVal == 'object') {
                    dataVal.form_data_rev_ = 0
                  }
                })
                const { curBoPkVal, tasks, inst, instId } = res
                this.flowData = { curBoPkVal, tasks, inst, instId }
                if (curBoPkVal) {
                  sessionStorage.setItem('formImportTempRefId', curBoPkVal)
                }
                sessionStorage.removeItem('formImportTempJson')
                this.executorIsEmptyInsts = insts
                this.executorIsEmptyRow = res
                //节点属性配置执行人为空时选择 assign:由审批人指定
                if (res.executorIsEmpty && res.executorIsEmpty == 'assign') {
                  this.executorIsEmptyDialog = true
                } else {
                  this.$message.success(res.message)

                  // 流程启动完，关闭流程启动页面
                  await this.$store.dispatch(
                    'tabsBar/delVisitedRoute',
                    this.$route
                  )

                  if (tasks?.length > 0) {
                    tasks.length === 1 &&
                      this.handleJumps({
                        taskId: tasks[0].id,
                        isGetApprovalBtn: true,
                        instId,
                      })
                    tasks.length > 1 && this.handleSelectTodoTask(tasks)
                  } else {
                    this.handleJumps({
                      instId,
                      type: 'request',
                      myApplication: true,
                    })
                  }
                }
              }
            })
          })
          .finally(() => {
            this.startFlowLoading = false
          })
      },
      //发起人配置审批人后确认事件
      confirm() {
        let tasks = this.flowData.tasks
        let instId = this.flowData.instId
        if (!(this.user.fullname && this.user.id)) {
          this.$message.warning('请选择审批人员')
          return
        }
        let map = {
          userId: this.user.id,
          userName: this.user.fullname,
          taskId: this.executorIsEmptyRow.assignTaskId,
          instId: this.executorIsEmptyRow.instId,
        }
        req
          .post(
            window.context.bpmRunTime + '/runtime/instance/v1/assignBpmTask',
            map
          )
          .then((res) => {
            if (res.state) {
              this.$message.success(res.message)
              this.$nextTick(() => {
                {
                  if (tasks?.length > 0) {
                    tasks.length === 1 &&
                      this.handleJumps({
                        taskId: tasks[0].id,
                        isGetApprovalBtn: true,
                        instId,
                      })
                    tasks.length > 1 && this.handleSelectTodoTask(tasks)
                  } else {
                    this.handleJumps({ instId })
                  }
                }
              })
            }
            this.executorIsEmptyDialog = false
          })
          .catch((e) => {
            this.executorIsEmptyDialog = false
          })
      },
      pushDone() {
        if (JSON.stringify(this.$route.query) == '{}') {
          this.$router.go(-1)
        } else {
          window.close()
        }
      },
      //启动流程成功后当有多个代办任务时,打开选择待办任务弹窗
      handleSelectTodoTask(taskList) {
        this.cancelBtnLoading()
        this.tableData = taskList
        this.$refs.todoTaskDialog.openDialog()
      },
      handleJumps(query) {
        this.$router.push({
          path: '/matter/approvalForm',
          query: {
            ...query,
          },
        })
      },
      //获取跳转节点
      getAfterJumpNodes() {
        var _this = this
        const params = {
          defId: this.defId,
          data: this.approvalFormData,
          alias: 'process',
        }
        //判断当前流程是不是自由流程,如果是,要弹出自由流程配置框
        if (this.flowObject.flowType == 2) {
          this.freedomDialog = true
        } else {
          getAfterJumpNodesByDefId(params).then((res) => {
            const afterNodes = res?.afterNodes
            if (afterNodes.length === 0) {
              this.startProcess()
            } else {
              this.handleSavaDraft(false).then((res) => {
                _this.cancelBtnLoading()
                _this.$route.query.taskId = ''
                _this.$refs.selectPathJump.showDialog(params)
              })
            }
          })
        }
      },
      cancelBtnLoading() {
        this.startFlowLoading = false
        this.saveDraftLoading = false
      },
      savaDraftBeforeRunBeforeScript() {
        //执行前置脚本
        this.submitBefore('saveDraft', 'isNewProcess')
      },
      //保存为草稿
      handleSavaDraft(isJump) {
        return new Promise((resolve, rej) => {
          const data = this.setFormData()
          const formImportTempJson =
            sessionStorage.getItem('formImportTempJson')
          if (formImportTempJson) {
            data.updateSubTableJson = formImportTempJson
          }
          savaProcessDraft(validObject(data))
            .then((res) => {
              if (res.state) {
                // 保存版本号自增1 可以保证前端连续保存不会报错
                Object.keys(this.data).forEach((key) => {
                  if (
                    this.data[key].form_data_rev_ ||
                    this.data[key].form_data_rev_ === 0
                  ) {
                    this.data[key].form_data_rev_++
                  } else {
                    this.data[key].form_data_rev_ = 0
                  }
                })
                this.$message.success(res.message)
                this.saveInstId
              }
              if (res?.curBoPkVal) {
                sessionStorage.setItem('formImportTempRefId', res.curBoPkVal)
              }
              sessionStorage.removeItem('formImportTempJson')
              this.resInstId = res?.instId
              this.$route.query.instId = res?.instId
              if (isJump) {
                this.$router.push({
                  path: '/matter/startProcess',
                  query: {
                    defId: this.defId,
                    instId: res?.instId,
                    name: this.processName,
                    instStatus: 'draft',
                  },
                })
              }
              resolve()
            })
            .finally(() => {
              this.saveDraftLoading = false
            })
        })
      },
      handleOpenFlowChart() {
        this.$refs.flowChart.handleOpen()
      },
      //预测图
      showFigureDialog() {
        // if (!this.instId) {
        //   this.$message({
        //     message: '查看审批预测需要先保留该流程，是否确认保存',
        //     type: 'warning',
        //   })
        //   return
        // }
        this.handleSavaDraft(false).then((res) => {
          this.$refs.processForecast.handleOpen(
            this.instId || this.resInstId,
            '',
            '',
            false
          ) //父组件调用子组件方法
        })
      },
      handleCancel() {
        this.$confirm('是否关闭？', '提示', {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning',
          closeOnClickModal: false,
        })
          .then(() => {
            if (this.$route.query.application) {
              sessionStorage.setItem('close-tab', new Date().getTime())
            } else if (this.isFromApplicationModule || this.fullScreenState) {
              const message = {
                message: 'closeTab',
              }
              window.top.postMessage(message, '*')
              this.$router.push('/')
              window.close()
              //
            } else if (this.copyInstId) {
              //复制流程取消时，回到流程中心,关闭流程启动页面
              this.$store.dispatch('tabsBar/delVisitedRoute', this.$route)
              this.$router.push({
                path: '/matter/new',
              })
            } else {
              this.$tabs.close()
            }
          })
          .catch(() => {})
      },
    },
  }
</script>

<style lang="scss" scoped>
  .start-button-group {
    ::v-deep {
      .el-button {
        font-size: 14px;
        font-weight: bold;
      }
    }
  }
</style>
