<template>
  <div
    class="approval-buttons"
    :class="{ 'app-model': isFromApplicationModule }"
  >
    <!-- 征询任务 -->
    <template v-if="status === 'TRANSFORMEDINQU' && isShowApprovalBtn">
      <inquiry-reply-button :disabled="disabled" @close-dialog="handleClose" />
      <inquiry-button
        :disabled.sync="disabled"
        :name="inquiryBtnName"
        alias="inquiry"
        @close-dialog="handleClose"
      />
    </template>
    <!-- 加签任务 -->
    <countersign-feedback-button
      v-if="
        status === 'USERADDSIGN' &&
        !isDone &&
        !['circulate', 'received'].includes(from)
      "
      :disabled="disabled"
      :is-get-approval-btn="isShowApprovalBtn"
      @close-dialog="handleClose"
    />
    <!-- 沟通任务 -->
    <communicate-feedback-button
      v-if="isCommunicateFeedbackTask && !isDone"
      :read-id="readId"
      :disabled="disabled"
      :is-get-approval-btn="isShowApprovalBtn"
    />
    <!-- 正常待办 -->
    <template v-if="isShowApprovalBtn">
      <component
        :is="btn.components"
        v-for="btn in showButtonList"
        :key="btn.alias"
        :name="$td(`flow.bnt.${procDefKey}.${nodeId}.${btn.alias}`, btn.name)"
        :alias="btn.alias"
        :node-type="nodeType"
        :data="data"
        :form-key="formKey"
        :form-type="formType"
        :disabled.sync="disabled"
        :before-click="beforeClick"
        :dialog-before-click="dialogBeforeClick"
        :dialog-after-click="dialogAfterClick"
        :opinion-field="opinionField"
        :append-opinion="appendOpinion"
        :is-get-approval-btn="isShowApprovalBtn"
        :approval-button-list="approvalButtonList"
        @close-dialog="handleClose"
      ></component>
      <div
        v-if="
          moreBtnList.length ||
          (showButtonList.length == 6 && (isShowDelBtn || hasHangUpOrLock))
        "
        class="approval-button-item more-btn-wrap"
      >
        <div>
          <el-button @click="handleClose">{{ $t('Common.Close') }}</el-button>
        </div>
        <el-dropdown trigger="click" @command="handleCommand">
          <el-button
            plain
            :disabled="disabled && !isHangUp"
            class="dropdown-more-btn"
          >
            更多操作
            <i class="el-icon-caret-bottom"></i>
          </el-button>
          <el-dropdown-menu slot="dropdown" class="dropdown-btns">
            <el-dropdown-item v-for="item in moreBtnList" :key="item.alias">
              <component
                :is="item.components"
                :ref="item.components"
                :key="item.alias"
                :approval-button-list="approvalButtonList"
                :name="
                  $td(
                    `flow.bnt.${procDefKey}.${nodeId}.${item.alias}`,
                    item.name
                  )
                "
                :alias="item.alias"
                :node-type="nodeType"
                :data="data"
                :form-key="formKey"
                :form-type="formType"
                :disabled="disabled"
                :before-click="beforeClick"
                :dialog-before-click="dialogBeforeClick"
                :dialog-after-click="dialogAfterClick"
                :opinion-field="opinionField"
                :append-opinion="appendOpinion"
                :is-get-approval-btn="isShowApprovalBtn"
                @close-dialog="handleClose"
              ></component>
            </el-dropdown-item>
            <template v-for="(btn, index) in approvalButtonList">
              <el-dropdown-item
                v-if="btn.alias === 'lockUnlock'"
                :key="`${btn.alias}_${index}`"
                class="lock-unlock"
                command="lockUnlock"
              >
                {{ taskStatus === 'canLock' ? btn.name : '取消签收' }}
              </el-dropdown-item>
              <el-dropdown-item
                v-if="
                  (btn.alias === 'hangUp' && !isHangUp) ||
                  (btn.alias === 'cancelHangUp' && isHangUp)
                "
                :key="btn.alias"
                :command="btn.alias"
              >
                {{ btn.name }}
              </el-dropdown-item>
            </template>
            <el-dropdown-item
              v-if="isShowApprovalBtn && isShowDelay"
              command="delay"
              :disabled="disabled"
            >
              {{ $t('Common.DelayedProcessing') }}
            </el-dropdown-item>
            <el-dropdown-item
              v-if="
                showDelBtn &&
                !['TRANSFORMEDINQU', 'USERADDSIGN'].includes(status)
              "
              command="delInstance"
            >
              <span class="delete-btn">{{ $t('Common.Remove') }}</span>
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
      <template v-else>
        <template v-for="(btn, index) in approvalButtonList">
          <div
            v-if="btn.alias === 'lockUnlock'"
            :key="index"
            class="lock-unlock"
          >
            <el-button :disabled="disabled" @click="handleSignFor">
              {{ taskStatus === 'canLock' ? btn.name : '取消签收' }}
            </el-button>
          </div>
          <!-- 挂起、取消挂起 按钮 -->

          <div
            v-if="
              (btn.alias === 'hangUp' && !isHangUp) ||
              (btn.alias === 'cancelHangUp' && isHangUp)
            "
            :key="btn.alias + index"
            class="hangup__cancel-hangup"
          >
            <el-button @click="handleHangUp">
              {{ btn.name }}
            </el-button>
          </div>
        </template>
      </template>
    </template>

    <!-- 已办或者我的请求列表进入且允许撤回时显示撤回按钮 -->
    <revoke-button
      v-if="
        (isShowRevokeBtn && isRequest && !isEndOrArtificialEnd) ||
        isRevokeCurrentNode
      "
      :disabled="disabled"
      :node-id="currentNodeInfo.taskKey"
      :before-click="beforeClick"
      :dialog-before-click="dialogBeforeClick"
      :dialog-after-click="dialogAfterClick"
      alias="revoke"
    />
    <!-- 传阅时回复按钮 -->
    <circulation-reply-button v-if="isShowReply" :disabled="disabled" />
    <!-- 关闭、标为已阅 -->
    <div class="approval-button-item close-button">
      <el-button
        v-if="isReceivedTaskStatus === 'FOLLOW' && !isRead && !isMarkedRead"
        type="primary"
        :disabled="disabled"
        @click="handleSetRead"
      >
        {{ $t('Common.CirculateRead') }}
      </el-button>
      <template
        v-if="
          !moreBtnList.length &&
          ((showButtonList.length === 6 && !isShowDelBtn && !hasHangUpOrLock) ||
            showButtonList.length < 6)
        "
      >
        <el-button v-if="isShowDelBtn" type="danger" @click="handleDelInst">
          {{ $t('Common.Remove') }}
        </el-button>
        <el-button
          v-if="isShowApprovalBtn && isShowDelay"
          :disabled="disabled"
          @click="handleDelay()"
        >
          {{ $t('Common.DelayedProcessing') }}
        </el-button>

        <el-button @click="handleClose">
          {{ $t('Common.Close') }}
        </el-button>
      </template>
      <el-button
        v-if="isDelegate"
        class="btn-margin"
        type="primary"
        @click="handleTakeBack"
      >
        {{ $t('myTask.takeBack') }}
      </el-button>
    </div>
    <!-- 选择领导代审批弹窗 -->
    <leader-dialog ref="leaderDialog" />
  </div>
</template>

<script>
  import { mapState } from 'vuex'
  import { hangUpOrCancelHangUp, isTaskFirstNode } from '@/api/flow'
  import {
    getTaskLockStatus,
    getSponsorRevoke,
    canLock,
    setRead,
    deleteInstById,
    taskDelayById,
    takeBackTask,
  } from '@/api/process'

  const STATUS_MAP = {
    COMMU: 'CommunicateFeedbackButton', //沟通反馈
    USERADDSIGN: 'CountersignFeedbackButton', //加签反馈
  }
  const COMPONENTS_MAP = {
    agree: 'AgreeButton',
    agreeTrans: 'AgreeButton',
    oppose: 'AgreeButton',
    opposeTrans: 'AgreeButton',
    reject: 'RejectButton',
    inqu: 'InquiryButton',
    saveDraft: 'SavaButton',
    delegate: 'TransferButton',
    endProcess: 'TerminationButton',
    startTrans: 'ExchangeButton',
    addSign: 'CountersignButton',
  }
  const HANGUP = 1 //实例挂起
  const FORBIDDEN = 3 //实例禁止

  export default {
    name: 'ApprovalButton',
    components: {
      AgreeButton: () => import('./AgreeButton'),
      RejectButton: () => import('./RejectButton'),
      InquiryButton: () => import('./InquiryButton'),
      SavaButton: () => import('./SavaButton'),
      TransferButton: () => import('./TransferButton'),
      InquiryReplyButton: () => import('./InquiryReplyButton'),
      CountersignFeedbackButton: () => import('./CountersignFeedbackButton'),
      TerminationButton: () => import('./TerminationButton'), //终止
      CommunicateFeedbackButton: () => import('./CommunicateFeedbackButton'),
      CirculationReplyButton: () => import('./CirculationReplyButton'),
      ExchangeButton: () => import('./ExchangeButton'),
      CountersignButton: () => import('./CountersignButton'),
      RevokeButton: () => import('./RevokeButton'),
      LeaderDialog: () => import('@/views/matter/components/LeaderDialog'),
    },
    props: {
      nodeType: {
        type: String,
        default: '',
      },
      formKey: {
        type: String,
        default: '',
      },
      formType: {
        type: String,
        default: '',
      },
      data: {
        type: Object,
        default: () => {
          return null
        },
      },
      beforeClick: {
        type: Function,
        default: null,
      },
      dialogBeforeClick: {
        type: Function,
        default: null,
      },
      dialogAfterClick: {
        type: Function,
        default: null,
      },
      isGetApprovalButton: {
        type: Boolean,
        default: false,
      },
      processInstStatus: {
        type: [Number, String],
        default: null,
      },
      opinionField: {
        type: String,
        default: '',
      },
      appendOpinion: {
        type: Boolean,
        default: false,
      },
      readId: {
        type: String,
        default: '',
      },
      instanceStatus: {
        type: String,
        default: '',
      },
      currentNodeInfo: {
        type: Object,
        default: () => {},
      },
      nodeId: {
        type: String,
        default: '',
      },
      procDefKey: {
        type: String,
        default: '',
      },
      approvalButtonList: {
        type: Array,
        default: () => [],
      },
    },
    data() {
      return {
        isShowBtnByStatus: STATUS_MAP,
        disabled: false,
        isShowRevokeBtn: false,
        isHangUp: false,
        isMarkedRead: false,
        showDelBtn: false,
        delayTaskIdList: [],
      }
    },
    computed: {
      ...mapState('matter', ['taskStatus', 'isFromApplicationModule']),
      ...mapState('process', ['bpmTask']),
      ...mapState('user', ['account']),
      ...mapState('routes', ['fullScreenState']),
      taskId() {
        return this.$route.query.taskId || this.bpmTask.id
      },
      isDone() {
        return this.$route.query.type === 'done' && !this.isShowApprovalBtn
      },
      leaderId() {
        return this.$route.query.leaderId
      },
      instId() {
        return this.$route.query.instId || this.bpmTask.procInstId
      },
      from() {
        return this.$route.query.from
      },
      status() {
        return this.bpmTask.status
      },
      isReceivedTaskStatus() {
        return this.$route.query.receivedStatus
      },
      isCommunicateFeedbackTask() {
        return this.isReceivedTaskStatus === 'COMMU'
      },
      isShowReply() {
        return (
          this.from === 'received' &&
          !['COMMU', 'FOLLOW', 'feedback'].includes(this.isReceivedTaskStatus)
        )
      },
      isRead() {
        return Number(this.$route.query.isRead) === 1
      },
      hasHangUpOrLock() {
        return this.approvalButtonList?.some((item) =>
          ['hangUp', 'lockUnlock'].includes(item.alias)
        )
      },
      //当前显示按钮组件列表
      currentShowBtnList() {
        const btnList = this.approvalButtonList?.filter((item) => {
          return !['hangUp', 'cancelHangUp', 'lockUnlock'].includes(item.alias)
        })
        let bool = false
        const list = btnList?.map((btn) => {
          bool = btn.isLock
          return {
            ...btn,
            components: COMPONENTS_MAP[btn.alias],
          }
        })
        return bool && this.taskStatus === 'canLock' ? [] : list || []
      },
      showButtonList() {
        return this.currentShowBtnList.filter(
          (item, index) => index < 6 || item.alias === 'saveDraft'
        )
      },
      moreBtnList() {
        return this.currentShowBtnList.filter(
          (item, index) => index >= 6 && item.alias !== 'saveDraft'
        )
      },
      //正常待办显示审批按钮
      isShowApprovalBtn() {
        return Boolean(
          this.$route.query.isGetApprovalBtn || this.isGetApprovalButton
        )
      },
      isShowDelay() {
        return this.$route.query.key === 'onlyOneTask' ? false : true
      },
      isRequest() {
        return this.$route.query.type === 'request'
      },
      //是否允许本环节撤回
      isRevokeCurrentNode() {
        const { revoke, previousRevoke, opinionStatus } =
          this.currentNodeInfo || {}
        return (
          this.isDone &&
          revoke &&
          previousRevoke &&
          !['transAgree', 'opposeTrans'].includes(opinionStatus) &&
          !['back', 'backToStart'].includes(this.instanceStatus)
        )
      },
      //是否审批终止,人工结束,已撤回
      isEndOrArtificialEnd() {
        return ['end', 'manualend', 'revoke', 'revokeToStart'].includes(
          this.instanceStatus
        )
      },
      inquiryBtnName() {
        const inquiryBtnConfig = this.currentShowBtnList.find(
          (item) => item.alias === 'inqu'
        )
        return inquiryBtnConfig ? inquiryBtnConfig.name : '征询'
      },
      isShowDelBtn() {
        return (
          this.showDelBtn &&
          !['TRANSFORMEDINQU', 'USERADDSIGN'].includes(this.status)
        )
      },
      isDelegate() {
        return this.from === 'delegate' && this.$route.query.status !== 'finish'
      },
    },
    watch: {
      $route: 'initData',
      processInstStatus(val) {
        //1.流程被挂起(hangUp) 3.流程被禁止(forbidden)
        if (val === HANGUP) {
          this.disabled = true
          this.isHangUp = true
          this.$message.warning('当前流程实例已被挂起,无法审批')
        } else if (val === FORBIDDEN) {
          this.disabled = true
          this.$message.warning('当前流程实例已被禁止,无法审批')
        } else {
          this.isHangUp = false
          this.disabled = false
        }
      },
      instanceStatus(val) {
        let fromTodoTab = this.$route.query.isGetApprovalBtn
        if (fromTodoTab) {
          if (val === 'revokeToStart') {
            return (this.showDelBtn = true)
          } else if (val === 'back' || val === 'backToStart') {
            // 如果是驳回状态，进一步判断当前任务是否在第一个节点
            isTaskFirstNode(this.taskId).then((response) => {
              if (response.state) {
                return (this.showDelBtn = response.value)
              }
            })
          }
        }
        return (this.showDelBtn = false)
      },
    },
    mounted() {
      this.initData()
    },
    methods: {
      handleCommand(alias) {
        if (['cancelHangUp', 'hangUp'].includes(alias)) {
          this.handleHangUp()
        } else if (alias === 'lockUnlock') {
          this.handleSignFor()
        } else if (alias === 'delay') {
          this.handleDelay()
        } else if (alias === 'delInstance') {
          this.handleDelInst()
        }
      },
      initData() {
        const taskId = this.$route.query.taskId
        if (
          this.$route.query.type === 'request' &&
          taskId &&
          taskId.trim() != ''
        ) {
          //我的申请 进入，而且是进入任务待办，不显示撤回按钮
          return
        }
        if (['request', 'done'].includes(this.$route.query.type)) {
          this.getSponsorRevokeByInstId()
        }
      },
      //签收
      handleSignFor() {
        let query = {
          taskId: this.taskId,
          leaderId: this.leaderId ? this.leaderId : '',
        }
        canLock(query, () => {
          if (this.taskStatus === 'LockedBySomeone') {
            this.$message.warning(TASK_STATUS_MESSAGE[this.taskStatus])
          } else {
            getTaskLockStatus(query, (res) => {
              //重新加载页面
              // this.$tabs.reload()
              const tipMsg = res == 1 ? '签收成功' : '取消签收成功'
              this.$message.success(tipMsg)
              this.$emit('load-Data')
            })
          }
        })
      },
      //挂起，取消挂起
      handleHangUp() {
        const type = this.isHangUp ? 'unForbiddenInstance' : 'forbiddenInstance'
        const query = {
          instId: this.instId,
          type,
          taskId: this.taskId,
        }
        hangUpOrCancelHangUp(query, async (res) => {
          if (res.state) {
            this.isHangUp = !this.isHangUp
            await this.$message.success(res.message)
            if (this.isHangUp) {
              await this.$message.warning('当前流程已被挂起,无法审批')
              this.disabled = true
            } else {
              this.disabled = false
            }
          }
        })
      },
      getSponsorRevokeByInstId() {
        getSponsorRevoke(this.instId, (res) => {
          if (res.state) {
            this.isShowRevokeBtn = res.value
          }
        })
      },
      //关闭
      handleClose() {
        if (this.isGetApprovalButton) {
          this.$emit('close-dialog')
        } else if (this.$route.query.application) {
          sessionStorage.setItem('close-tab', new Date().getTime())
        } else if (this.isFromApplicationModule || this.fullScreenState) {
          this.$router.go(-1)
        } else {
          this.$tabs.close()
        }
      },
      //设为已阅
      handleSetRead() {
        setRead(this.readId).then((res) => {
          this.$message.success('标记成功')
          this.isMarkedRead = true
        })
      },
      handleDelay() {
        this.disabled = true
        taskDelayById(this.taskId).then((res) => {
          this.filterHasHandleTask()
          this.disabled = false
          const isAutoOpenNextTodo = JSON.parse(
            localStorage.getItem('isAutoOpenNextTodo')
          )
          const isDialog = JSON.parse(localStorage.getItem('isDialog'))
          if (isDialog) {
            this.$emit('close-dialog')
          }
          if (!isDialog) {
            if (isAutoOpenNextTodo) {
              if (res.state && res.value?.length > 1) {
                this.getNextTaskByTaskIdAndInstId(res.value[0])
              }
            } else {
              this.$router.push('/matter/myTask')
            }
          }
        })
      },
      filterHasHandleTask() {
        if (localStorage.getItem(this.account)) {
          const specialFocusTaskList =
            JSON.parse(localStorage.getItem(this.account)) || []
          const currentSpecialFocusTask = specialFocusTaskList.filter(
            (item) => item.taskId !== this.taskId
          )
          localStorage.setItem(
            this.account,
            JSON.stringify(currentSpecialFocusTask)
          )
        }
      },
      //获取下一个待办任务根据taskId,instId
      getNextTaskByTaskIdAndInstId(data) {
        let loading = this.$loading({
          target: document.querySelector('.app-main-container'),
          text: '正在获取下一个任务,请稍等...',
          spinner: 'el-icon-loading',
          background: '',
        })
        let time = 1500
        if (data) {
          this.$refs.leaderDialog.handleJumpsTodoPage(
            data,
            {
              isGetApprovalBtn: true,
            },
            true
          )
        } else {
          //判断是否是模块开发
          time = 0
          const path = '/matter/myTask?tabActiveName=done&type=done'
          if (this.fullScreenState) {
            this.$router.go(-1)
          } else {
            this.$tabs.replace({ path })
          }
        }
        setTimeout(() => {
          loading.close()
        }, time)
      },
      handleDelInst() {
        this.$confirm('是否确认删除此流程实例？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            deleteInstById(this.instId).then((res) => {
              if (res.state) {
                this.$message({
                  type: 'success',
                  message: res.message,
                })
                this.filterHasHandleTask()
              } else {
                this.$message({
                  type: 'warning',
                  message: res.message,
                })
              }
              setTimeout(() => {
                if (this.isGetApprovalButton) {
                  this.$emit('close-dialog')
                } else if (
                  this.isFromApplicationModule ||
                  this.fullScreenState
                ) {
                  this.$router.go(-1)
                } else {
                  this.$tabs.close()
                }
              }, 200)
            })
          })
          .catch((e) => {
            this.$message({
              type: 'info',
              message: '已取消删除',
            })
          })
      },
      handleTakeBack() {
        console.log(this.currentNodeInfo, 'this.currentNodeInfo')
        this.$confirm('确认收回此流程?', '提示', {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning',
          closeOnClickModal: false,
          beforeClose: (action, instance, done) => {
            if (action === 'confirm') {
              instance.confirmButtonLoading = true
              takeBackTask(this.currentNodeInfo.taskId).then((res) => {
                instance.confirmButtonLoading = false
                done()
                if (!res.state) return this.$message.error(res.message)
                this.$message.success(res.message)
                this.handleClose()
              })
            } else {
              done()
              instance.confirmButtonLoading = false
            }
          },
        }).then(() => {})
      },
    },
  }
</script>

<style lang="scss" scoped>
  .approval-buttons {
    display: flex;
    height: $base-min-height;
    line-height: $base-min-height;

    .approval-button-item,
    .hangup__cancel-hangup,
    .lock-unlock {
      margin-right: 8px;
      ::v-deep {
        .el-button {
          font-size: 14px;
          font-weight: bold;
          padding: 8.2px 16px;
        }
      }
    }
    .more-btn-wrap {
      display: flex;
      align-items: center;
    }
    .approval-button-item {
      .dropdown-more-btn {
        padding: 7.8px 16px;
        margin-left: 8px;
        border-radius: 4px;
        border-color: #dcdee0;
        color: #262626;
        background-color: #fff;
        &:hover {
          color: var(--themeColor);
          background-color: #fff;
          border-color: var(--themeColor);
        }
      }
    }
  }
</style>
