<template>
  <div class="start-process">
    <nav-bar
      :title="form && form.name"
      :isCustom="true"
      @go-back="handleGoBack"
    >
      <template #right v-if="mergencyConfig && mergencyConfig.conf.length > 0">
        <i
          class="icon-jinjizhuangtai ergency-icon"
          :style="{ color: `${mergencyConfig.conf[urgentStateIndex].color}` }"
          @click="$refs.startProcessForm.showMergencyConfig = true"
        ></i>
      </template>
    </nav-bar>
    <flow-form
      ref="startProcessForm"
      :key="defId"
      :form="form"
      :data.sync="data"
      :def-id="defId"
      :permission="permission"
      :record-data="recordData"
      @formTypeChange="handleFormTypeChange"
      @urgentStateValueChange="handleUrgentStateChange"
      @urgentStateList="getUrgentStateList"
    />
    <ul class="start-process__footer">
      <div class="footer-btn__left">
        <li class="footer-item__btn prognostic-map" @click="showFigureDialog">
          <i class="icon-yucetu btn-icon"></i>
          <span class="footer-text__btn">预测图</span>
        </li>
        <li class="footer-item__btn flow-map" @click="handleOpenFlowChart">
          <i class="icon-liuchengtu1 btn-icon"></i>
          <span class="footer-text__btn">流程图</span>
        </li>
        <li
          class="footer-item__btn"
          v-if="buttonMap.saveDraft && buttonMap.saveDraft.alias"
          @click="handleClick('saveDraft')"
        >
          <i class="icon-baocun1 btn-icon"></i>
          <span class="footer-text__btn">
            {{ buttonMap.saveDraft.name }}
          </span>
        </li>
      </div>
      <li
        class="footer-item__btn start-flow__btn"
        v-if="buttonMap.startFlow && buttonMap.startFlow.alias"
      >
        <van-button
          type="info"
          :loading="startFlowLoading"
          @click="handleClick('startFlow')"
        >
          {{ buttonMap.startFlow.name }}
        </van-button>
      </li>
    </ul>
    <!-- 选择路径跳转 -->
    <TaskSelectDestination
      ref="taskSelectDestination"
      task-id
      :def-id="defId"
      :inst-id="instId"
      :currentAlias="currentAlias"
      :leader-id="leaderId"
    />
    <!-- 流程图 -->

    <FlowChart
      ref="popupFlowChart"
      :showPage="false"
      :instId="instId"
      :data="data"
      :def-id="defId"
    ></FlowChart>
    <!-- 审批预测 -->
    <processForecast
      ref="processForecast"
      :instId="instId"
      :data="data"
      :showPage.sync="showPage"
    ></processForecast>
    <van-action-sheet
      v-model="executorIsEmptyDialog"
      class="select-user-action"
      :close-on-click-overlay="false"
      get-container="body"
    >
      <div class="header">
        <span class="left-cancel" @click="cancel">取消</span>
        <span class="center-title">执行人为空时由发起人指定</span>
        <span class="right-confirm" @click="confirm">确定</span>
      </div>
      <van-form class="btn-form-content" v-form ref="userActionForm">
        <van-field
          name="users"
          label="审批人员"
          :rules="[{ required: true, message: '请选择审批人员' }]"
          class="required-mark"
        >
          <template #input>
            <ht-user-selector-input
              v-model="userSelectValue"
              :config="{ id: 'user.id', fullname: 'user.fullname' }"
              :append-to-body="true"
              single
            ></ht-user-selector-input>
          </template>
        </van-field>
      </van-form>
    </van-action-sheet>
    <!-- 相关流程跳转提示弹窗 -->
    <relevant-tip-popup
      :showPopup.sync="showRelevantTipPopup"
      @click-flow="handleClickFlow"
      @sava-form="handleSavaForm"
    ></relevant-tip-popup>
  </div>
</template>

<script>
  import { mapActions, mapState } from 'vuex'
  import FlowForm from './form/FlowForm.vue'
  import processForecast from '@/views/matter/components/processForecast/processForecast.vue'
  import TaskSelectDestination from '@/views/matter/components/TaskSelectDestination.vue'
  import RelevantTipPopup from '@/views/matter/components/RelevantTipPopup'
  import {
    getProcessFormAndBo,
    getMainByDefIdOrKey,
    checkStartRight,
    savaProcessDraft,
    startProcess,
    getInstanceByInstId,
    assignBpmTask,
    getAfterJumpNodesByDefId,
  } from '@/api/process'
  import NavBar from '@/components/NavBar.vue'
  import FlowChart from '@/components/FlowChart.vue'
  import preJavascript from '@/mixins/preJavascript.js'
  import { validObject } from '@/utils'
  import popupMode from '@/mixins/popupMode'
  export default {
    components: {
      FlowForm,
      NavBar,
      FlowChart,
      processForecast,
      TaskSelectDestination,
      RelevantTipPopup,
    },
    mixins: [preJavascript, popupMode],
    name: 'StartProcess',
    data() {
      return {
        form: null,
        formType: null,
        data: null,
        permission: null,
        mainDefId: '',
        buttonMap: {},
        startFlowLoading: false,
        procInstId: '', //流程实例ID
        executorIsEmptyDialog: false,
        user: {
          id: '',
          fullname: '',
        },
        showPage: false,
        userSelectValue: '',
        mergencyValue: '',
        urgentStateIndex: 0,
        mergencyConfig: null,
        showRelevantTipPopup: false,
        currentRelevantId: '',
        currentAlias: '',
      }
    },
    computed: {
      ...mapState('login', ['currentUser']),
      defId() {
        return this.$route.query.defId || this.mainDefId
      },
      instId() {
        return this.$route.query?.instId || this.procInstId || ''
      },
      copyInstId() {
        return this.$route.query.copyInstId
      },
      userId() {
        return this.currentUser?.userId
      },
      recordData() {
        return {
          defId: this.defId,
        }
      },
      leaderId() {
        return this.$route.query?.leaderId || ''
      },
    },
    watch: {
      defId: {
        handler(val) {
          if (!this.defId && this.$route.query.flowKey) {
            getMainByDefIdOrKey('', this.$route.query.flowKey).then((resp) => {
              this.mainDefId = resp['defId']
            })
          }
          this.initData()
        },
        immediate: true,
      },
    },
    created() {
      this.$root.$on('click-relevant-flow', (row) => {
        this.currentRelevantId = row.id
        if (row.id) {
          this.showRelevantTipPopup = true
        }
      })
    },
    methods: {
      ...mapActions('process', ['getFlowKey']),
      handleFormTypeChange(type) {
        this.formType = type
      },
      initData() {
        if (!this.defId) {
          return
        }
        const { leaderId } = this.$route.query
        // 判断发起权限
        checkStartRight(this.userId, this.defId, leaderId || '').then(
          (response) => {
            if (response.state) {
              if (response.value) {
                this.getFormAndBoData()
                this.getFlowKey({ defId: this.defId })
              } else {
                this.$notify({
                  type: 'danger',
                  message: '您没有该流程的发起权限',
                  duration: 1500,
                  onClose: () => {
                    this.$router.go(-1)
                  },
                })
              }
            } else {
              this.$notify({
                type: 'danger',
                message: response.message
                  ? response.message
                  : '判断流程发起权限时出错',
              })
            }
          }
        )
      },
      handlerJs(diyJs) {
        this.$nextTick(() => {
          const userInfo = this.userInfo
          const currentUser = userInfo?.user
          let data = this.data
          let _this = this
          const $ = require('jquery')
          eval(diyJs)
        })
      },
      //流程启动时获取bo和表单
      getFormAndBoData() {
        let params = {}
        if (this.instId) {
          // 我的草稿进入发起页面
          params = { defId: this.defId, proInstId: this.instId }
        } else if (this.copyInstId) {
          // 流程复制进入发起页面
          params = { defId: this.defId, copyInstId: this.copyInstId }
        } else {
          // 常规发起
          params = { defId: this.defId }
        }
        getProcessFormAndBo(params).then((res) => {
          if (res.resultMsg === 'formEmpty') {
            this.$notify({ type: 'warning', message: '该流程尚未配置表单' })
          }
          const { buttons, form, data } = res || {}
          this.buttonMap = buttons.reduce((pre, cur) => {
            pre[cur.alias] = cur
            return pre
          }, {})
          this.form = form
          this.data = data
          this.permission =
            res && res.permission ? JSON.parse(res.permission) : null

          this.getParametersData()
          //处理表单的js脚本
          res.form && res.form.diyJs && this.handlerJs(res.form.diyJs)
        })
      },
      getParametersData() {
        if (this.$route.query.data) {
          let param = JSON.parse(Base64.decode(this.$route.query.data))

          Object.keys(this.data).forEach((boDefAlias) => {
            for (let key in param) {
              this.data[boDefAlias][key] = param[key]
            }
          })
        }
      },
      handleClick(alias) {
        // 启动流程前校验表单
        if (alias == 'startFlow') {
          return this.$refs.startProcessForm
            .getData(true)
            .then(() => {
              this.currentAlias = alias
              this.startFlowLoading = true
              //执行前置脚本
              this.submitBefore(alias)
            })
            .catch(() => {
              this.startFlowLoading = false
              return false
            })
        } else {
          //执行前置脚本
          this.submitBefore(alias)
        }
        return true
      },
      //获取跳转节点
      getAfterJumpNodes() {
        const params = {
          defId: this.defId,
          alias: 'process',
          data: this.data,
        }
        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) */
              this.$refs.taskSelectDestination.showDailog(params, '', '') //父组件调用子组件方法
            })
          }
        })
      },
      cancelBtnLoading() {
        this.startFlowLoading = false
        this.saveDraftLoading = false
      },
      onSubmit(alias) {
        const eventMap = {
          startFlow: 'getAfterJumpNodes', // 启动流程先获取有没有配置跳转的节点
          saveDraft: 'handleSavaDraft',
        }
        this[eventMap[alias]]()
      },
      //保存为草稿
      handleSavaDraft(type) {
        return new Promise((reslove, rej) => {
          const data = this.setFormData()
          const formImportTempJson =
            this.$storage.session.get('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.$toast('保存成功')
              this.procInstId = res.instId
              if (type === 'relevantFlow') {
                this.handleClickFlow()
              }

              reslove(res.instId)
            }
            if (res?.curBoPkVal) {
              this.$storage.session.set('formImportTempRefId', res.curBoPkVal)
            }
            this.$storage.session.remove('formImportTempJson')
          })
        })
      },
      //启动流程
      startProcess() {
        const data = this.setFormData()
        const formImportTempJson =
          this.$storage.session.get('formImportTempJson')
        if (formImportTempJson) {
          data.updateSubTableJson = formImportTempJson
        }
        startProcess(validObject(data))
          .then((res) => {
            getInstanceByInstId(res.instId, async (insts) => {
              if (res.state) {
                // 保存版本号自增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) {
                  this.$storage.session.set('formImportTempRefId', curBoPkVal)
                }
                this.$storage.session.remove('formImportTempJson')
                this.executorIsEmptyInsts = insts
                this.executorIsEmptyRow = res
                //节点属性配置执行人为空时选择 assign:由审批人指定
                if (res.executorIsEmpty && res.executorIsEmpty == 'assign') {
                  this.executorIsEmptyDialog = true
                } else {
                  this.$notify({ type: 'success', message: res.message })
                  if (tasks?.length > 0) {
                    tasks.length === 1 &&
                      this.handleJumps({
                        taskId: tasks[0].id,
                        isGetApprovalBtn: true,
                        instId,
                        status: tasks[0].status,
                      })
                    tasks.length > 1 && this.handleSelectTodoTask(tasks)
                  } else {
                    this.handleJumps({
                      instId,
                      type: 'request',
                      myApplication: true,
                      status: inst.status,
                    })
                  }
                }
              }
            })
          })
          .finally(() => {
            this.startFlowLoading = false
          })
      },
      setFormData() {
        const currentUrgentConfig = this.$storage.get('urgentStateValue')
        let data = {
          defId: this.defId,
          formKey: this.formKey,
          formType: this.formType,
          supportMobile: 1,
          proInstId: this.instId,
          urgentStateValue: currentUrgentConfig || '',
        }
        // URL表单合并参数
        if (this.formType == 'FRAME') {
          Object.assign(data, this.data)
        } else {
          // 在线表单则设置data属性
          data.data = Base64.encode(JSON.stringify(this.data))
        }

        // 领导秘书代理领导发起流程
        if (this.leaderId) {
          data.agentLeaderId = this.leaderId
        }
        return data
      },
      handleJumps(query) {
        this.$router.push({
          path: '/matter/approvalForm',
          query: {
            ...query,
          },
        })
      },
      handleOpenFlowChart() {
        this.$refs.popupFlowChart.showPop()
      },
      //预测图
      showFigureDialog() {
        if (!this.instId) {
          this.handleSavaDraft().then((res) => {
            this.$refs.processForecast.handleOpen(this.instId, '', '', false) //父组件调用子组件方法
          })
        } else {
          this.$refs.processForecast.handleOpen(this.instId, '', '', false)
        }
      },
      //发起人配置审批人后确认事件
      confirm() {
        let tasks = this.flowData.tasks
        let instId = this.flowData.instId
        if (!(this.user.fullname && this.user.id)) {
          this.$toast.fail('请选择审批人员')
          return
        }
        let map = {
          userId: this.user.id,
          userName: this.user.fullname,
          taskId: this.executorIsEmptyRow.assignTaskId,
          instId: this.executorIsEmptyRow.instId,
        }
        assignBpmTask(map)
          .then((res) => {
            if (res.state) {
              this.$notify({ type: 'success', message: 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
          })
      },
      //取消选择
      cancel() {
        this.executorIsEmptyDialog = false
        this.userSelectValue = ''
        this.user.id = ''
        this.user.fullname = ''
      },
      handleUrgentStateChange(val, index) {
        this.mergencyValue = val
        this.urgentStateIndex = index
      },
      getUrgentStateList(val) {
        this.mergencyConfig = val
      },
      handleSavaForm() {
        this.handleSavaDraft('relevantFlow')
      },
      handleClickFlow() {
        const query = {
          instId: this.currentRelevantId,
          isReadonly: true,
          isRelevantFlow: true,
          isStartProcess: true,
          backInstId: this.procInstId,
          backDefId: this.defId,
          type: 'done',
        }
        this.handleJumps(query)
      },
      handleGoBack() {
        if (
          this.$route.query.isStartProcess ||
          this.$route.query.instStatus === 'draft'
        ) {
          this.$router.push({
            path: '/matter/myRequest',
          })
        } else {
          this.$router.go(-1)
        }
      },
    },
  }
</script>

<style lang="scss" scoped>
  .start-process {
    .start-process__footer {
      display: flex;
      justify-content: space-between;
      position: fixed;
      bottom: 0;
      height: 64px;
      align-items: center;
      width: 100%;
      background: $base-white-color;
      border-top: 1px solid #eee;
      .footer-item__btn {
        display: flex;
        flex-direction: column;

        .btn-icon {
          font-size: $base-font-size-max;
        }
        .footer-text__btn {
          font-size: $base-font-size-small;
          margin-top: 3px;
        }
        ::v-deep {
          .van-button--info {
            height: 44px;
            line-height: 44px;
            padding: 12px 40px;
            font-size: 14px;
            border-radius: 8px;
            background-color: $--color-primary;
            border-color: $--color-primary;
          }
        }
      }

      .footer-btn__left {
        display: flex;
        flex: 1;
        margin-top: 2px;
        .footer-item__btn {
          flex: 1;
          text-align: center;
        }
      }
      .start-flow__btn {
        width: 124px;
        margin-right: 16px;
        margin-top: 4px;
      }
    }
  }

  .select-user-action {
    .header {
      height: 44px;
      line-height: 44px;
      padding: 0 16px;
      display: flex;
      justify-content: space-between;
      .left-cancel,
      .right-confirm {
        color: $base-gray-text-color;
        font-size: $base-font-size-default;
      }
      .right-confirm {
        color: $--color-primary;
      }
      .center-title {
        color: $base-title-color;
        font-size: 17px;
      }
    }
    .btn-form-content {
      margin-top: 8px;
      .required-mark {
        align-items: center;
        ::v-deep {
          .van-field__label {
            flex-basis: 158px;
            color: $base-text-color;
            margin-right: 0;
            position: relative;
            &::after {
              content: '*';
              position: absolute;
              top: 0;
              color: $base-danger-color;
              font-size: $base-font-size-large;
            }
          }
          .van-action-sheet__cancel {
            padding: 12px 0;
          }
        }
      }
      ::v-deep {
        .van-field__word-limit {
          height: 40px;
          line-height: 40px;
          margin-top: 0;
          color: $base-gray-disabled-text-color;
          font-size: $base-font-size-default;
          .van-field__word-num {
            color: #333;
          }
        }
      }
    }
    ::v-deep {
      .van-field {
        padding: 12px 16px;
        .van-field__control {
          text-align: right;
          color: $base-text-color;
        }
      }
      .van-field__error-message {
        text-align: right;
        color: $base-danger-color;
      }
      .van-field--error .van-field__control,
      .van-field--error .van-field__control::placeholder {
        color: $base-gray-disabled-text-color;
      }
      .van-action-sheet__content {
        max-height: 80vh;
        overflow-y: unset;
        .btn-form-content {
          max-height: calc(80vh - 52px);
          overflow-y: scroll;
        }
      }
      .van-field__value {
        .van-field__control {
          justify-content: flex-end;
        }
      }
      .van-hairline--top-bottom {
        &::after {
          border-top: none;
        }
      }
    }
  }

  .ergency-icon {
    font-size: 22px;
  }
  ::v-deep {
    .popup_header_margin {
      overflow: auto;
    }
    .van-icon.van-icon-arrow {
      font-size: 18px;
    }
  }
</style>
