<template>
  <div>
    <el-dialog
      v-if="isShowDialog"
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      :before-close="handleClose"
      :close-on-click-modal="false"
      append-to-body
      custom-class="free-jump-dailog"
      class="choose-target-node"
    >
      <table v-if="hasAfterNodesLength" v-form class="node-table">
        <tr class="node-table-row">
          <th class="node-table-th">
            <span>{{ tableLabel }}</span>
          </th>
          <th v-if="selectConfig.choiceExcutor">
            <span>{{ $t('taskToJump.SelectProcessor') }}</span>
          </th>
        </tr>
        <tr
          v-for="(row, index) in selectConfig.afterNodes"
          :key="index"
          data-subname="selectConfig.afterNodes"
          :data-index="index"
          class="node-table-row"
        >
          <td class="node-table-td">
            <el-radio
              v-if="selectConfig.jumpType"
              v-model="selectNodeId"
              :label="row.nodeId"
            >
              {{ row.nodeName }}
            </el-radio>
            <span v-else>{{ row.nodeName }}</span>
          </td>
          <td v-if="selectConfig.choiceExcutor" class="node-table-td">
            <div v-if="row.nodeType != 'end'" class="node-table-wrap">
              <ht-select
                v-if="selectConfig.choiceExcutor == 'candidate'"
                v-model="row.selectUserIds"
                multiple
                clearable
                filterable
                :props="{ key: 'id', value: 'name' }"
                :options="row.excutorList"
              ></ht-select>
              <ht-user-selector-input
                v-else
                v-model="row.selectUsers"
                :config="{ id: 'row.id' }"
                permission="w"
                append-to-body
              />
            </div>
          </td>
        </tr>
      </table>
      <el-form
        v-if="showOpinion"
        v-form
        :model="formData"
        label-width="80px"
        data-vv-scope="agreeApprovalForm"
      >
        <ht-form-item
          :label="$t('taskToJump.ApprovalOpinion')"
          class="opinion-label"
        >
          <approval-comments
            :approval-opinion="approvalOpinion"
            @get-opinion="getOpinion"
          ></approval-comments>
        </ht-form-item>
        <ht-form-item
          v-if="isShowSignature"
          :label="$t('taskToJump.SignatureAndPassword')"
        >
          <ht-input
            v-model="signaturePassword"
            validate="required"
            show-password
          ></ht-input>
        </ht-form-item>
        <ht-form-item :label="$t('taskToJump.AttachmentUpload')">
          <ht-file
            v-model="fileList"
            :uploading.sync="fileUploading"
            type="list"
            :downloadable="false"
          />
        </ht-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button v-if="isShowHelpBtn" type="text" @click="handleHelp">
          {{ $t('Common.Help') }}
        </el-button>
        <el-button :disabled="fileUploading" @click="handleClose">
          {{ $t('Common.Cancel') }}
        </el-button>
        <el-button type="primary" :loading="fileUploading" @click="confirm">
          {{ $t('Common.Confirm') }}
        </el-button>
      </div>
    </el-dialog>
    <el-drawer
      v-else
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      :before-close="handleClose"
      :close-on-click-modal="false"
      append-to-body
      custom-class="free-jump-dailog"
      class="choose-target-node right-drawer-wrap"
      :size="380"
      :modal="false"
      :wrapper-closable="false"
      :class="{
        'dialog-model-drawer': isDialog && !isFromTaskManager,
        'horizontal-layout-drawer': layout === 'horizontal',
        'flow-module-drawer': isFromApplicationModule,
      }"
    >
      <div class="dialog__content">
        <table v-if="hasAfterNodesLength" v-form class="node-table">
          <tr class="node-table-row">
            <th class="node-table-th">
              <span>{{ tableLabel }}</span>
            </th>
            <th v-if="selectConfig.choiceExcutor" class="node-table-th">
              <span>{{ $t('taskToJump.SelectProcessor') }}</span>
            </th>
          </tr>
          <tr
            v-for="(row, index) in selectConfig.afterNodes"
            :key="index"
            data-subname="selectConfig.afterNodes"
            :data-index="index"
            class="node-table-row"
          >
            <td class="node-table-td">
              <el-radio
                v-if="selectConfig.jumpType"
                v-model="selectNodeId"
                :label="row.nodeId"
              >
                {{ row.nodeName }}
              </el-radio>
              <span v-else>{{ row.nodeName }}</span>
            </td>
            <td v-if="selectConfig.choiceExcutor" class="node-table-td">
              <div v-if="row.nodeType != 'end'" class="node-table-wrap">
                <ht-select
                  v-if="selectConfig.choiceExcutor == 'candidate'"
                  v-model="row.selectUserIds"
                  multiple
                  clearable
                  filterable
                  :props="{ key: 'id', value: 'name' }"
                  :options="row.excutorList"
                ></ht-select>
                <ht-user-selector-input
                  v-else
                  v-model="row.selectUsers"
                  :config="{ id: 'row.id' }"
                  permission="w"
                  append-to-body
                />
              </div>
            </td>
          </tr>
        </table>
        <el-form
          v-if="showOpinion"
          v-form
          :model="formData"
          label-width="80px"
          data-vv-scope="agreeApprovalForm"
        >
          <ht-form-item
            :label="$t('taskToJump.ApprovalOpinion')"
            class="opinion-label"
          >
            <approval-comments
              :approval-opinion="approvalOpinion"
              @get-opinion="getOpinion"
            ></approval-comments>
          </ht-form-item>
          <ht-form-item
            v-if="isShowSignature"
            :label="$t('taskToJump.SignatureAndPassword')"
          >
            <ht-input
              v-model="signaturePassword"
              validate="required"
              show-password
            ></ht-input>
          </ht-form-item>
          <ht-form-item :label="$t('taskToJump.AttachmentUpload')">
            <ht-file
              v-model="fileList"
              :uploading.sync="fileUploading"
              type="list"
              :downloadable="false"
            />
          </ht-form-item>
        </el-form>
      </div>
      <div class="dialog-footer dialog-footer__btns">
        <el-button v-if="isShowHelpBtn" type="text" @click="handleHelp">
          {{ $t('Common.Help') }}
        </el-button>
        <el-button type="primary" :loading="fileUploading" @click="confirm">
          {{ $t('Common.Confirm') }}
        </el-button>
        <el-button :disabled="fileUploading" @click="handleClose">
          {{ $t('Common.Cancel') }}
        </el-button>
      </div>
    </el-drawer>

    <el-dialog
      :title="$t('Common.Help')"
      :visible.sync="helpDialog"
      width="55%"
      :close-on-click-modal="false"
      append-to-body
    >
      <div class="help-content" v-html="valHelp"></div>
    </el-dialog>
  </div>
</template>

<script>
  import approvalButton from '@/mixins/approvalButton'
  import { startProcess, savaTaskComplete } from '@/api/process'

  import { validObject } from '@/utils'
  import { mapState } from 'vuex'

  export default {
    name: 'SelectPathToJump',
    mixins: [approvalButton],
    props: {
      isShowDialog: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        tableData: [],
        selectConfig: {},
        helpDialog: false,
        valHelp: '',
        showOpinion: true,
        jumpType: '',
        formData: {},
        selectNodeId: '',
        currentUserInfo: {
          id: '',
          fullname: '',
        },
        startParams: {},
        fileUploading: false,
      }
    },
    computed: {
      ...mapState('user', ['userInfo']),
      ...mapState('routes', ['fullScreenState']),
      tableLabel() {
        return this.selectConfig.jumpType ? '选择节点' : '目标节点'
      },
      isShowHelpBtn() {
        const { help, helpGlobal, jumpType } = this.selectConfig
        const jumpTypeList = ['free', 'select', 'free,select', 'select,free']
        return (help || helpGlobal) && jumpTypeList.includes(jumpType)
      },
      hasAfterNodesLength() {
        return (
          this.selectConfig.afterNodes &&
          this.selectConfig.afterNodes.length > 0
        )
      },
      dialogTitle() {
        return this.hasAfterNodesLength ? '选择目标节点' : '审批同意'
      },
    },
    mounted() {
      this.startParams = {}
      this.setJumpType()
    },
    methods: {
      openSelectPathJumpDialog(data, from = 'todo') {
        //完成任务（同意）时，需要带参数-表单数据，否则会丢失通过初始赋值的表单字段数据
        this.startParams.data = data
        if (this.isFree) {
          this.jumpType = 'free'
        }
        if (from === 'todo') {
        } else {
          this.showOpinion = false
        }
        this.dialogVisible = true
        this.afterOpenSelectPathJumpDialog()
      },
      setJumpType() {
        this.jumpType = this.getNodeProperties()?.jumpType
      },
      afterOpenSelectPathJumpDialog() {
        this.getApprovalOpinionByInstIdAndTaskId()
        const params = {
          defId: this.bpmTask.procDefId || '',
          instId: this.instId || '',
          type: this.jumpType || '',
        }
        this.getAfterJumpNodes(params, this.setSelectConfigVal)
      },
      showDialog(startParams) {
        this.startParams = startParams
        const params = {
          defId: this.startParams.defId || '',
          instId: '',
          type: '',
        }
        if (this.startParams.data) {
          this.$set(params, 'data', this.startParams.data)
        }
        this.dialogVisible = true
        this.showOpinion = false
        this.getAfterJumpNodes(params, this.setSelectConfigVal)
      },
      getValueByKey(array, key) {
        let value = ''
        if (array && array.length > 0) {
          value = array.map((it) => it[key]).join(',')
        }
        return value
      },
      setSelectConfigVal() {
        if (this.isFree) {
          this.selectConfig = {
            ...this.selectConfig,
            jumpType: this.jumpType,
            choiceExcutor: this.jumpType,
          }
        }
        const { afterNodes, helpGlobal, help } = this.selectConfig
        if (afterNodes?.length === 1) {
          this.selectNodeId = afterNodes[0].nodeId
        }
        // 如果是自由选择，默认带出候选人，然后在再基于候选人进行调整（删减或增加）
        if (
          afterNodes?.length > 0 &&
          this.selectConfig.choiceExcutor &&
          this.selectConfig.choiceExcutor != 'candidate'
        ) {
          this.selectConfig.afterNodes = afterNodes.map((item) => {
            return {
              ...item,
              selectUsers: this.getValueByKey(item.excutorList, 'name'),
              id: this.getValueByKey(item.excutorList, 'id'),
            }
          })
        }
        if (help) {
          this.valHelp = Base64.decode(help, 'utf-8')
        } else if (helpGlobal) {
          this.valHelp = Base64.decode(helpGlobal, 'utf-8')
        }
      },
      confirm() {
        if (this.alias === 'agree' && this.signatureField) {
          this.handleSignature()
          this.handleSubmit()
        } else {
          this.handleSubmit()
        }
      },
      handleSubmit() {
        if (this.taskId) {
          this.$confirm('确认办理此任务?', '提示', {
            cancelButtonText: '取消',
            confirmButtonText: '确定',
            type: 'warning',
            closeOnClickModal: false,
            beforeClose: (action, instance, done) => {
              if (action === 'confirm') {
                instance.confirmButtonLoading = true
                const data = this.getSubmitData()
                //删除多余参数
                if (data.hasOwnProperty('proInstId')) {
                  delete data.proInstId
                }
                if (data.hasOwnProperty('defId')) {
                  delete data.defId
                }
                if (data.hasOwnProperty('isSendNodeUsers')) {
                  delete data.isSendNodeUsers
                }
                if (data.hasOwnProperty('startOrgId')) {
                  delete data.startOrgId
                }
                savaTaskComplete(data)
                  .then((res) => {
                    if (!res.state) {
                      instance.confirmButtonLoading = false

                      return this.$message.error(res.message)
                    }
                    this.dialogVisible = false
                    this.$message.success(res.message)
                    instance.confirmButtonLoading = false
                    done()
                    this.$router.push({
                      path: '/matter/myTask',
                      query: {
                        type: 'done',
                        tabActiveName: 'done',
                      },
                    })
                  })
                  .catch((rej) => {
                    instance.confirmButtonLoading = false
                  })
              } else {
                done()
                instance.confirmButtonLoading = false
              }
            },
          }).then(() => {})
        } else {
          this.handleStartProcess()
        }
      },
      handleStartProcess() {
        const data = {
          ...this.getSubmitData(),
          supportMobile: 1,
        }
        //删除多余参数
        if (data.hasOwnProperty('actionName')) {
          delete data.actionName
        }
        if (data.hasOwnProperty('zfiles')) {
          delete data.zfiles
        }
        if (data.hasOwnProperty('jumpType')) {
          delete data.jumpType
        }
        if (data.hasOwnProperty('files')) {
          delete data.files
        }
        if (data.hasOwnProperty('opinion')) {
          delete data.opinion
        }
        this.loading = true
        startProcess(data)
          .then((res) => {
            this.$message.success(res.message)
            this.dialogVisible = false
            if (this.fullScreenState) {
              this.$router.go(-1)
            } else {
              this.$tabs.close()
            }
          })
          .finally(() => {
            this.loading = false
          })
      },
      getSubmitData() {
        //审批意见回填
        this.setOpinionWrap()
        let data = {
          ...this.getSubmitCommonData(),
          formType: this.data?.businessKey ? 'frame' : 'inner',
          defId: this.bpmTask.procDefId || this.startParams.defId,
          proInstId: this.instId || '',
          opinion: this.opinionValue,
          agentLeaderId: this.leaderId,
          isSendNodeUsers: '1',
          destination: this.selectNodeId,
          ...this.getEffectiveValue(),
        }
        if (this.jumpType) {
          data.jumpType = this.jumpType === 'select' ? 'select' : 'free'
        }
        if (this.startParams.data) {
          data.data = Base64.encode(JSON.stringify(this.startParams.data))
        }
        return data
      },
      getEffectiveValue() {
        const currentUrgentConfig = localStorage.getItem('urgentStateValue')
        const data = {
          urgentStateValue: currentUrgentConfig
            ? JSON.parse(currentUrgentConfig)
            : '',
          nodeUsers: JSON.stringify(this.getNodeUserList()),
          startOrgId: this.userInfo.org?.[0]?.orgId,
        }
        return validObject(data)
      },
      getNodeUserList() {
        let nodeUsers = []
        if (this.selectConfig?.choiceExcutor === 'candidate') {
          nodeUsers = this.getCandidateList()
        } else {
          nodeUsers = this.getNodeUsers()
        }
        return nodeUsers.length > 0 ? nodeUsers : ''
      },
      getCandidateList() {
        let candidateList = []
        this.selectConfig?.afterNodes?.map((item) => {
          if (item.selectUserIds?.length > 0) {
            const excutorList = item.excutorList
            const selectUsers = excutorList?.filter((it) => {
              return item.selectUserIds.includes(it.id)
            })
            candidateList.push({ nodeId: item.nodeId, executors: selectUsers })
          }
        })
        return candidateList
      },
      getNodeUsers() {
        let nodeUsers = []
        this.selectConfig?.afterNodes?.map((node) => {
          const currentSelectedUserList = node.selectUsers?.split(',')
          const selectedUserIds = node.id?.split(',')
          if (currentSelectedUserList?.length > 0) {
            const selectUsers = currentSelectedUserList
              ?.map((user, index) => {
                return {
                  id: selectedUserIds[index],
                  name: user,
                  type: 'user',
                }
              })
              ?.filter((it) => it.id)
            if (selectUsers && selectUsers.length) {
              nodeUsers.push({ nodeId: node.nodeId, executors: selectUsers })
            }
          }
        })
        return nodeUsers
      },
      handleHelp() {
        this.helpDialog = true
      },
    },
  }
</script>

<style lang="scss" scoped>
  .help-content {
    max-height: 600px;
    overflow: auto;
  }
  .node-table {
    width: 100%;
    margin-bottom: 20px;
    &-row {
      height: 40px;
      line-height: 40px;
      th,
      td {
        border-bottom: 1px solid $base-border-color;
      }
      th {
        text-align: left;
        span {
          margin-left: 120px;
        }
      }
    }
    &-td {
      text-align: left;
      .node-table-wrap,
      label {
        margin-left: 120px;
      }
    }
  }
  .choose-target-node {
    ::v-deep {
      .el-select__tags {
        max-height: 190px !important;
        overflow: auto;
      }
      .el-select {
        max-height: 200px;
        overflow: hidden;
      }
      .el-input__inner {
        max-height: 200px;
      }
    }
  }
</style>
