<template>
  <!-- SUB Contents -->
  <div class="ui--content-wrapper">
    <sdl-breadcrumb></sdl-breadcrumb>
    <!--Contents Area -->
    <div class="ui--form-container">
      <h4>1. {{ $t('sdl.approval.label.basicApprovalPath') }}</h4>
      <form class="needs-validation" novalidate="" @submit.prevent>
        <div>
          <div class="ui--approval-container">
            <div class="input-group">
              <input
                type="text"
                class="form-control"
                :placeholder="$t('sdl.common.label.payer')"
                aria-label="add User"
                v-model="searchUserNm"
                @keyup.esc="searchUserNm = ''"
                @keyup.enter.stop="openSearchUser()"
              />
              <button class="btn btn-outline-secondary" type="button" @click="openSearchUser">
                <i class="bi bi-search"></i>
              </button>
            </div>

            <div class="ui--approval-list">
              <!-- file-button -->
              <div class="ui--approval-button">
                <div class="ui--apv-flex">
                  <button
                    class="btn ui--btn-apv-outline"
                    type="button"
                    :class="{ on: approvalType === 'APPROVAL' }"
                    @click="changeApprovalType('APPROVAL')"
                  >
                    {{ $t('sdl.approval.label.APPROVE') }}
                  </button>
                  <button
                    class="btn ui--btn-apv-outline"
                    type="button"
                    :class="{ on: approvalType === 'AGREEMENT' }"
                    @click="changeApprovalType('AGREEMENT')"
                  >
                    {{ $t('sdl.approval.label.AGREEMENT') }}
                  </button>
                  <button
                    class="btn ui--btn-apv-outline"
                    type="button"
                    :class="{ on: approvalType === 'NOTIFICATION' }"
                    @click="changeApprovalType('NOTIFICATION')"
                  >
                    {{ $t('sdl.approval.label.NOTIFY') }}
                  </button>
                </div>
                <span class="ui--slide ms-2 me-2">|</span>
                <button class="btn ui--btn-xs" type="button" @click="changeApprovalType('EX_POST_APPROVAL')">
                  {{ $t('sdl.approval.label.SKIP') }}
                </button>
                <span class="ui--slide ms-2 me-2">|</span>
                <button class="btn ui--btn-xs" type="button" @click="setApprovalParallel(true)">
                  <i class="bi bi-view-stacked"></i>{{ $t('sdl.common.label.parallel') }}
                </button>
                <button class="btn ui--btn-xs" type="button" @click="setApprovalParallel(false)">
                  <i class="bi bi-grid"></i>{{ $t('sdl.approval.label.PARALLEL_CANCEL') }}
                </button>
                <!--
                <button v-if="showRequired" class="btn ui--btn-xs" @click="setApprovalRequired" type="button">
                  {{ $t('sdl.approval.label.addRequiredApprovalUser') }}
                </button>
                -->
                <span class="ui--slide ms-2 me-2">|</span>
                <button class="btn ui--btn-icon-sm" :title="$t('sdl.common.label.Top')" type="button" @click="stepTopUp()">
                  <i class="bi bi-skip-end-fill ui--trans-rotate-270"></i>
                </button>
                <button class="btn ui--btn-icon-sm" :title="$t('sdl.common.label.moveup')" type="button" @click="stepUp()">
                  <i class="bi bi-play-fill ui--trans-rotate-270"></i>
                </button>
                <button
                  class="btn ui--btn-icon-sm"
                  :title="$t('sdl.common.label.movedown')"
                  type="button"
                  @click="stepDown()"
                >
                  <i class="bi bi-play-fill ui--trans-rotate-90"></i>
                </button>
                <button
                  class="btn ui--btn-icon-sm"
                  :title="$t('sdl.common.label.bottom')"
                  type="button"
                  @click="stepBottomDown()"
                >
                  <i class="bi bi-skip-end-fill ui--trans-rotate-90"></i>
                </button>
                <button
                  class="btn ui--btn-icon-sm"
                  :title="$t('sdl.common.label.delete')"
                  type="button"
                  @click="deleteUserTopBtn"
                >
                  <i class="bi bi-x"></i>
                </button>
                <span class="ui--slide ms-2 me-2">|</span>
                <span
                  >{{ $t('sdl.common.label.total') }}<strong class="ms-1 me-2">{{ apprPathList.length }}</strong></span
                >
              </div>
              <ul>
                <li
                  v-for="user in apprPathList"
                  :key="`${user.userId}_${user.stepIdx}`"
                  :class="{
                    selected: user.selected,
                    draft: user.approvalType === 'DRAFTING',
                    disabled: user.employeeStatus !== 'B',
                  }"
                  @click="selectedPath(user)"
                >
                  <span class="count">{{ user.stepIdx }}</span>
                  <div class="ui--apv-flex" v-if="user.approvalType === 'DRAFTING'">
                    <button class="btn ui--btn-apv ui--btn-apv-request" type="button">
                      {{ $t('sdl.approval.label.REQUEST') }}
                    </button>
                  </div>
                  <div class="ui--apv-flex" v-else-if="user.approvalType === 'EX_POST_APPROVAL'">
                    <button class="btn ui--btn-apv ui--btn-apv-after on" type="button">
                      {{ $t('sdl.approval.label.SKIP') }}
                    </button>
                  </div>
                  <div class="ui--apv-flex" v-else-if="user.approvalType === 'PARALLEL_APPROVAL'">
                    <button class="btn ui--btn-apv ui--btn-apv-approve on" type="button">
                      {{ $t('sdl.approval.label.PARALLEL_APPROVE') }}
                    </button>
                  </div>
                  <div class="ui--apv-flex" v-else-if="user.approvalType === 'PARALLEL_AGREEMENT'">
                    <button class="btn ui--btn-apv ui--btn-apv-approve on" type="button">
                      {{ $t('sdl.approval.label.PARALLEL_AGREEMENT') }}
                    </button>
                  </div>
                  <div class="ui--apv-flex" v-else>
                    <button
                      class="btn ui--btn-apv ui--btn-apv-approve"
                      :class="{ on: user.approvalType === 'APPROVAL' }"
                      @click="changeUserApprovalType(user, 'APPROVAL')"
                      type="button"
                    >
                      {{ $t('sdl.approval.label.APPROVE') }}
                    </button>
                    <button
                      class="btn ui--btn-apv ui--btn-apv-agreement"
                      :class="{ on: user.approvalType === 'AGREEMENT' }"
                      @click="changeUserApprovalType(user, 'AGREEMENT')"
                      type="button"
                    >
                      {{ $t('sdl.approval.label.AGREEMENT') }}
                    </button>
                    <button
                      class="btn ui--btn-apv ui--btn-apv-notice"
                      :class="{ on: user.approvalType === 'NOTIFICATION' }"
                      @click="changeUserApprovalType(user, 'NOTIFICATION')"
                      type="button"
                    >
                      {{ $t('sdl.approval.label.NOTIFY') }}
                    </button>
                  </div>
                  <span class="name"
                    >{{ user.userName }}/{{ user.deptName }}/{{ user.compName }}
                    <strong v-if="user.employeeStatus === 'V'" class="text-danger ms-1"
                      >({{ $t('sdl.approval.label.leaveOfAbsence') }})</strong
                    >
                    <strong v-if="user.employeeStatus === 'N'" class="text-danger ms-1"
                      >({{ $t('sdl.user.label.inactive') }})</strong
                    >
                  </span>
                  <div v-if="user.approvalType === 'DRAFTING'" class="ui--apv-right text-black-50">
                    {{ $t('sdl.common.label.requester') }}
                  </div>
                  <div class="ui--apv-right" v-else>
                    <button
                      class="btn ui--btn-icon-xs"
                      :class="{ on: user.routeModify }"
                      :title="$t('sdl.common.label.pathchange')"
                      @click.stop="approvalRouteModify(user)"
                      type="button"
                    >
                      <i class="bi bi-arrow-down-up"></i>
                    </button>
                    <button
                      class="btn ui--btn-icon-xs"
                      :class="{ on: user.bodyModify }"
                      :title="$t('sdl.approval.label.BODYMODIFY')"
                      @click.stop="approvalBodyModify(user)"
                      type="button"
                    >
                      <i class="bi bi-fonts"></i>
                    </button>
                    <button
                      class="btn ui--btn-icon-xs"
                      :class="{ on: user.arbitrary }"
                      :title="$t('sdl.approval.label.ARBITRARY')"
                      @click.stop="approvalArbitrary(user)"
                      type="button"
                    >
                      <i class="bi bi-pencil-square"></i>
                    </button>
                    <button
                      class="btn ui--btn-icon-sm float-end"
                      :title="$t('sdl.common.label.delete')"
                      @click.stop="deleteUserRightBtn(user)"
                      type="button"
                    >
                      <i class="bi bi-x"></i>
                    </button>
                  </div>
                </li>
              </ul>
              <!-- // file-list -->
            </div>
          </div>
        </div>
      </form>
      <br />
      <h4>2. {{ $t('sdl.approval.label.requiredApprovalUserList') }}</h4>
      <form class="needs-validation" novalidate="" @submit.prevent>
        <div>
          <div class="ui--approval-container">
            <div class="input-group">
              <input
                type="text"
                class="form-control"
                :placeholder="$t('sdl.common.label.payer')"
                aria-label="add User"
                v-model="searchReqUserNm"
                @keyup.esc="searchReqUserNm = ''"
                @keyup.enter.stop="openRequiredSearchUser()"
              />
              <button class="btn btn-outline-secondary" type="button" @click="openRequiredSearchUser">
                <i class="bi bi-search"></i>
              </button>
            </div>

            <div class="ui--approval-list">
              <ul>
                <li
                  v-for="user in requiredApprovalList"
                  :key="`${user.userId}_${user.stepIdx}`"
                  :class="{
                    selected: user.selected,
                    draft: user.approvalType === 'DRAFTING',
                    disabled: user.employeeStatus !== 'B',
                  }"
                  @click="selectedPath(user)"
                >
                  <span class="name"
                    >{{ user.userName }}/{{ user.deptName }}/{{ user.compName }}
                    <strong v-if="user.employeeStatus === 'V'" class="text-danger ms-1"
                      >({{ $t('sdl.approval.label.leaveOfAbsence') }})</strong
                    >
                    <strong v-if="user.employeeStatus === 'N'" class="text-danger ms-1"
                      >({{ $t('sdl.user.label.inactive') }})</strong
                    >
                  </span>
                  <div class="ui--apv-right">
                    <button
                      class="btn ui--btn-icon-sm float-end"
                      :title="$t('sdl.common.label.delete')"
                      @click.stop="deleteReqUserRightBtn(user)"
                      type="button"
                    >
                      <i class="bi bi-x"></i>
                    </button>
                  </div>
                </li>
              </ul>
              <!-- // file-list -->
            </div>
          </div>
        </div>
      </form>
    </div>
    <hr class="mb-4" />
    <div class="ui--button-container">
      <button class="btn btn-secondary btn-lg" type="button" @click="goBackToList">
        {{ $t('sdl.common.label.list') }}
      </button>
      <button class="btn btn-primary btn-lg" type="button" @click="onBeforeSave">
        {{ $t('sdl.common.label.save') }}
      </button>
    </div>

    <!--//Contents Area -->
  </div>
</template>

<script>
import axios from 'axios';
import { SDLUtil } from '@/utils';
import StoreParams from '@/mixin/StoreParams';

export default {
  data() {
    return {
      approvalStepList: [],
      apprPathShow: true,
      searchUserNm: '',
      searchReqUserNm: '',
      showRequired: true,
      apprPathList: [],
      approvalType: 'APPROVAL',
      selectedDocTypeCode: '',
      checkParallesGroup: {},
      requiredApprovalList: [],
      approvalPathStatus: [
        { code: 'DRAFTING', label: 'sdl.approval.label.REQUEST' },
        { code: 'APPROVAL', label: 'sdl.approval.label.APPROVE' },
        { code: 'CANCEL', label: 'sdl.approval.label.CANCELLED' },
        { code: 'AGREEMENT', label: 'sdl.approval.label.AGREEMENT' },
        { code: 'NOTIFICATION', label: 'sdl.approval.label.NOTIFY' },
        { code: 'EX_POST_APPROVAL', label: 'sdl.approval.label.SKIP' },
        { code: 'PARALLEL_AGREEMENT', label: 'sdl.approval.label.PARALLEL_AGREEMENT' },
        { code: 'PARALLEL_APPROVAL', label: 'sdl.approval.label.PARALLEL_APPROVE' },
        { code: 'REJECT', label: 'sdl.approval.label.REJECTED' },
      ],
      internalApproval: false,
    };
  },
  mixins: [StoreParams],
  methods: {
    init() {
      // console.log(this.$route.params.docId);
      this.searchUserNm = '';
      if (this.$route.params.docType) {
        this.getApprovalPath();
        this.getRequiredApprovalList();
      }
      if (this.$route.query.internalApproval) {
        this.internalApproval = JSON.parse(this.$route.query.internalApproval);
      }
    },
    onBeforeSave() {
      SDLUtil.confirm({
        msg: 'sdl.common.message.doSave',
        title: 'sdl.common.label.save',
        onOkEvt: () => {
          this.onSave();
        },
      });
    },
    onSave() {
      SDLUtil.showLoadingBar(true);
      axios
        .all([
          axios.post(
            `${SDLUtil.API_URL}/approval/dynamic-approval-paths/${this.$route.params.docType}`,
            this.getApprovalList(),
          ),
          axios.post(
            `${SDLUtil.API_URL}/approval/required-approval-users/${this.$route.params.docType}`,
            this.getReqApprovalList(),
          ),
        ])
        .then(
          axios.spread(() => {
            // Loading bar hidden
            SDLUtil.showLoadingBar(false);
          }),
        )
        .catch(error => {
          SDLUtil.showLoadingBar(false);
          console.log(error);
          SDLUtil.errorAlert(error);
        });
    },
    getRequiredApprovalList() {
      // Loading bar execution
      SDLUtil.showLoadingBar(true);
      axios
        .get(`${SDLUtil.API_URL}/approval/required-approval-users/${this.$route.params.docType}`)
        .then(response => {
          this.approvalStepList = response.data;
          this.setRequiredApprovalList();
          // Loading bar hidden
          SDLUtil.showLoadingBar(false);
        })
        .catch(error => {
          SDLUtil.showLoadingBar(false);
          console.log(error);
        });
    },
    /**
     * param:
     * return:
     * exception:
     * Description : When you take the approval list from the inside,
     */
    getReqApprovalList() {
      const rtnList = [];
      Object.keys(this.requiredApprovalList).forEach(idx => {
        const apprLine = this.requiredApprovalList[idx];
        rtnList.push({
          approvalStepSequence: apprLine.stepIdx,
          parallelProcess: apprLine.parallel,
          approvalStepType: apprLine.approvalType,
          bodyModify: apprLine.bodyModify,
          routeModify: apprLine.routeModify,
          arbitrary: apprLine.arbitrary,
          userId: apprLine.userId,
          userName: apprLine.userName,
          grdName: apprLine.grdName,
          deptName: apprLine.deptName,
          compName: apprLine.compName,
        });
      });
      return rtnList;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : When receiving approval list as props from outside
     */
    setRequiredApprovalList() {
      this.requiredApprovalList.splice(0);
      Object.keys(this.approvalStepList).forEach(idx => {
        const apprLine = this.approvalStepList[idx];
        this.requiredApprovalList.push({
          stepIdx: apprLine.approvalStepSequence,
          parallel: apprLine.parallelProcess,
          approvalType: apprLine.approvalStepType,
          required: false,
          hasError: false,
          approverChangeAllowed: true,
          bodyModify: apprLine.bodymodify,
          routeModify: apprLine.routemodify,
          arbitrary: apprLine.arbitrary,
          userId: apprLine.user.userId,
          userName: apprLine.user.userName,
          grdName: apprLine.user.grdName,
          deptName: apprLine.user.deptName,
          compName: apprLine.user.compName,
          employeeStatus: apprLine.employeeStatus,
        });
      });
    },
    getApprovalPath() {
      // Loading bar execution
      SDLUtil.showLoadingBar(true);
      axios
        .get(`${SDLUtil.API_URL}/approval/dynamic-approval-paths/${this.$route.params.docType}`)
        .then(response => {
          this.approvalStepList = response.data;
          this.setApprovalList();
          // Loading bar hidden
          SDLUtil.showLoadingBar(false);
        })
        .catch(error => {
          SDLUtil.showLoadingBar(false);
          console.log(error);
        });
    },
    /**
     * param:
     * return:
     * exception:
     * Description : When receiving approval list as props from outside
     */
    setApprovalList() {
      this.apprPathList.splice(0);
      Object.keys(this.approvalStepList).forEach(idx => {
        const apprLine = this.approvalStepList[idx];
        this.apprPathList.push({
          stepIdx: apprLine.approvalStepSequence,
          parallel: !!(
            apprLine.approvalStepType === 'PARALLEL_APPROVAL' || apprLine.approvalStepType === 'PARALLEL_AGREEMENT'
          ),
          approvalType: apprLine.approvalStepType,
          required: false,
          hasError: false,
          approverChangeAllowed: true,
          bodyModify: apprLine.bodymodify,
          routeModify: apprLine.routemodify,
          arbitrary: apprLine.arbitrary,
          userId: apprLine.user.userId,
          userName: apprLine.user.userName,
          grdName: apprLine.user.grdName,
          deptName: apprLine.user.deptName,
          compName: apprLine.user.compName,
          employeeStatus: apprLine.employeeStatus,
        });
      });
    },
    /**
     * param:
     * return:
     * exception:
     * Description : When you take the approval list from the inside,
     */
    getApprovalList() {
      const rtnList = [];
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        const apprLine = this.apprPathList[i];
        rtnList.push({
          approvalStepSequence: apprLine.stepIdx,
          parallelProcess: apprLine.parallel,
          approvalStepType: apprLine.approvalType,
          bodymodify: apprLine.bodyModify,
          routemodify: apprLine.routeModify,
          arbitrary: apprLine.arbitrary,
          userId: apprLine.userId,
          userName: apprLine.userName,
          grdName: apprLine.grdName,
          deptName: apprLine.deptName,
          compName: apprLine.compName,
        });
      }
      return rtnList;
    },
    /**
     * param: user -> json
     * return:
     * exception:
     * Description : Body can be modified
     */
    approvalBodyModify(user) {
      if (user.employeeStatus !== 'B') return;

      user.bodyModify = !user.bodyModify;
      this.apprPathList.splice(this.apprPathList.indexOf(user), 1, user);
    },
    /**
     * param: user -> json
     * return:
     * exception:
     * Description : Is the approval path changed
     */
    approvalRouteModify(user) {
      if (user.employeeStatus !== 'B') return;

      user.routeModify = !user.routeModify;
      this.apprPathList.splice(this.apprPathList.indexOf(user), 1, user);
    },
    /**
     * param: user -> json
     * return:
     * exception:
     * Description : Is the final decision for approval
     */
    approvalArbitrary(user) {
      if (user.employeeStatus !== 'B') return;

      user.arbitrary = !user.arbitrary;
      this.apprPathList.splice(this.apprPathList.indexOf(user), user);
    },
    /**
     * param: parallel -> Boolean
     * return:
     * exception:
     * Description : parallel approval setting
     */
    setApprovalParallel(parallel) {
      if (this.checkRequired()) {
        // Required Approval Check
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return;
      }
      const selectedRows = [];
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (this.apprPathList[i].selected) {
          if (this.apprPathList[i].approvalType === 'NOTIFICATION') {
            // Notification does not pay in parallel
            SDLUtil.alert('sdl.approval.message.notifyCannotBeParallel');
            return;
          }
          if (this.apprPathList[i].approvalType === 'EX_POST_APPROVAL') {
            // No parallel payment for the latter decision
            SDLUtil.alert('sdl.approval.message.skipCannotBeParallel');
            return;
          }
          selectedRows.push(this.apprPathList[i]);
        }
      }

      if (selectedRows.length < 2) {
        // Select more than one parallel approval
        SDLUtil.alert('sdl.approval.message.parallelRequiresTwoOrMore');
        return;
      }

      if (this.checkApprovalStepsParallelPosition(selectedRows, parallel, false)) {
        return;
      }

      Object.keys(selectedRows).forEach(idx => {
        const user = selectedRows[idx];
        if (user.selected && user.approvalType !== 'NOTIFICATION' && user.approvalType !== 'EX_POST_APPROVAL') {
          user.parallel = parallel;
          if (parallel) {
            if (user.approvalType === 'PARALLEL_APPROVAL' || user.approvalType === 'PARALLEL_AGREEMENT') return;
            if (user.approvalType === 'APPROVAL') {
              user.approvalType = 'PARALLEL_APPROVAL';
            } else {
              user.approvalType = 'PARALLEL_AGREEMENT';
            }
          } else if (user.approvalType === 'PARALLEL_APPROVAL') {
            user.approvalType = 'APPROVAL';
          } else if (user.approvalType === 'PARALLEL_AGREEMENT') {
            user.approvalType = 'AGREEMENT';
          }
        }
        this.apprPathList.splice(this.apprPathList.indexOf(user), user);
      });

      // console.log(this.apprPathList);
      this.resetApprovalSeq();
    },
    /**
     * param: selectOptions -> array
     * param: parallel -> true/false(Boolean)
     * param: submit -> true/false(Boolean)
     * return:
     * exception:
     * Description : Check if parallel approval is possible
     */
    checkApprovalStepsParallelPosition(selectOptions, parallel, submit) {
      const paralles = [];
      let retStatus = true;

      // console.log('checkParallesGroup:', this.checkParallesGroup);
      selectOptions.filter(opt => opt.parallel).forEach(opt => {
        if (typeof this.checkParallesGroup[opt.stepIdx] === 'undefined') {
          const checkParalles = [];
          checkParalles.push(opt);
          this.checkParallesGroup[opt.stepIdx] = checkParalles;
        } else {
          this.checkParallesGroup[opt.stepIdx].push(opt);
        }
      });

      if (submit) {
        // Select more than one parallel approval
        Object.keys(this.checkParallesGroup).some(index => {
          if (this.checkParallesGroup[index].length === 1) {
            SDLUtil.alert('sdl.approval.message.parallelRemainTwoOrMore');
            return true;
          }
          return false;
        });
        retStatus = false;
      } else {
        selectOptions.filter(opt => opt.selected && opt.approvalType !== 'NOTIFICATION').forEach(opt => {
          paralles.push(opt);
        });

        for (let i = 1; i < paralles.length; i += 1) {
          const diff = paralles[i - 1].stepIdx - paralles[i].stepIdx;
          if (diff === 1 || diff === -1 || diff === 0) {
            if (!parallel && paralles[i - 1].parallel !== paralles[i].parallel) {
              SDLUtil.alert('sdl.approval.message.notMattchParallele');
              return true;
            }
            retStatus = false;
          } else {
            SDLUtil.alert('sdl.approval.message.linked');
            return true;
          }
        }
        // When releasing parallel payment, only one parallel approval step must be left.
        // If you select 3 parallel payments and replace the two parallel ones with the approval.
        if (!parallel && paralles.length > 0) {
          const opt = paralles[0];
          const opts = this.checkParallesGroup[opt.stepIdx];
          if (opts != null && opts.length - paralles.length === 1) {
            SDLUtil.alert('sdl.approval.message.parallelRemainTwoOrMore');
            return true;
          }
        }
      }
      return retStatus;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : Required Approval Check
     */
    checkRequired() {
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (this.apprPathList[i].selected) {
          if (this.apprPathList[i].required) return true;
        }
      }
      return false;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : open user search popup
     */
    openSearchUser() {
      if (this.searchUserNm) {
        if (this.searchUserNm.length < 2) {
          SDLUtil.alert('sdl.common.message.enterMoreThan2CharForSearchTerms');
          return;
        }
      }
      SDLUtil.openUserPopup({
        searchColumn: 'userName',
        searchTxt: this.searchUserNm,
        rtnFunc: this.getUserList,
        knoxSearch: !this.internalApproval,
      });
    },
    /**
     * param:
     * return:
     * exception:
     * Description : open user search popup
     */
    openRequiredSearchUser() {
      if (this.searchReqUserNm) {
        if (this.searchReqUserNm.length < 2) {
          SDLUtil.alert('sdl.common.message.enterMoreThan2CharForSearchTerms');
          return;
        }
      }
      SDLUtil.openUserPopup({
        searchColumn: 'userName',
        searchTxt: this.searchReqUserNm,
        rtnFunc: this.getReqUserList,
        knoxSearch: !this.internalApproval,
      });
    },
    /**
     * param: list -> array
     * return:
     * exception:
     * Description : return user search result
     */
    getUserList(list) {
      // console.log(list);
      const n = this.apprPathList.length;
      let dupFlag = false;

      Object.keys(list).forEach(i => {
        const userInfo = list[i];
        for (let j = 0; j < this.requiredApprovalList.length; j += 1) {
          if (userInfo.userId === this.requiredApprovalList[j].userId) {
            dupFlag = true;
            return;
          }
        }
      });
      if (dupFlag) {
        SDLUtil.alert('sdl.approval.label.dupRequiredApprovalUser');
        return;
      }
      // Double-payer check
      Object.keys(list).forEach(i => {
        const userInfo = list[i];
        for (let j = 0; j < this.apprPathList.length; j += 1) {
          if (userInfo.userId === this.apprPathList[j].userId) {
            dupFlag = true;
            return;
          }
        }
      });
      if (dupFlag) {
        SDLUtil.alert('sdl.approval.message.duplicateApprover');
        return;
      }
      Object.keys(list).forEach(i => {
        const userInfo = list[i];

        this.apprPathList.push({
          stepIdx: parseInt(n, 10) + parseInt(i, 10),
          parallel: false,
          approvalType: this.approvalType,
          required: false,
          hasError: false,
          approverChangeAllowed: true,
          bodyModify: false,
          routeModify: false,
          arbitrary: false,
          departmentName: userInfo.deptName,
          positionName: userInfo.grdName,
          companyName: userInfo.compName,
          positionCode: userInfo.grdCode,
          departmentCode: userInfo.deptCode,
          companyCode: userInfo.compCode,
          requiredUser: userInfo.requiredUser,
          userId: userInfo.userId,
          userName: userInfo.userName,
          grdName: userInfo.grdName,
          deptName: userInfo.deptName,
          compName: userInfo.compName,
          employeeStatus: 'B',
        });
      });

      this.resetApprovalSeq();
      this.searchUserNm = '';
    },
    /**
     * param: list -> array
     * return:
     * exception:
     * Description : return user search result
     */
    async getReqUserList(list) {
      const n = this.requiredApprovalList.length;
      let dupFlag = false;

      // Double-payer check
      Object.keys(list).forEach(i => {
        const userInfo = list[i];
        for (let j = 0; j < this.requiredApprovalList.length; j += 1) {
          if (userInfo.userId === this.requiredApprovalList[j].userId) {
            dupFlag = true;
            return;
          }
        }
      });
      if (dupFlag) {
        SDLUtil.alert('sdl.approval.message.duplicateApprover');
        return;
      }

      Object.keys(list).forEach(i => {
        const userInfo = list[i];
        for (let j = 0; j < this.apprPathList.length; j += 1) {
          if (userInfo.userId === this.apprPathList[j].userId) {
            dupFlag = true;
            return;
          }
        }
      });
      if (dupFlag) {
        SDLUtil.alert('sdl.approval.message.dupApprovalPath');
        return;
      }
      Object.keys(list).forEach(i => {
        const userInfo = list[i];

        this.requiredApprovalList.push({
          stepIdx: parseInt(n, 10) + parseInt(i, 10),
          parallel: false,
          approvalType: this.approvalType,
          required: false,
          hasError: false,
          approverChangeAllowed: true,
          bodyModify: false,
          routeModify: false,
          arbitrary: false,
          departmentName: userInfo.deptName,
          positionName: userInfo.grdName,
          companyName: userInfo.compName,
          positionCode: userInfo.grdCode,
          departmentCode: userInfo.deptCode,
          companyCode: userInfo.compCode,
          requiredUser: userInfo.requiredUser,
          userId: userInfo.userId,
          userName: userInfo.userName,
          grdName: userInfo.grdName,
          deptName: userInfo.deptName,
          compName: userInfo.compName,
          employeeStatus: 'B',
        });
      });

      this.searchReqUserNm = '';
    },
    /**
     * param: user -> Object
     * return:
     * exception:
     * Description : select approval path
     */
    selectedPath(user) {
      if (user.employeeStatus !== 'B') return;
      user.selected = !user.selected;

      this.apprPathList.splice(this.apprPathList.indexOf(user), user);
    },
    /**
     * param: approvalType -> String
     * return:
     * exception:
     * Description : click top button(APPROVAL, AGREEMENT, NOTIFICATION)
     */
    changeApprovalType(approvalType) {
      // Approval person cannot be modified
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (!this.apprPathList[i].approverChangeAllowed) {
          SDLUtil.alert('sdl.approval.message.approverNotAllowedToChange');
          return;
        }
      }

      if (this.checkRequired()) {
        // Required payer Check
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return;
      }

      this.approvalType = approvalType;

      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (this.apprPathList[i].selected) {
          this.apprPathList[i].approvalType = approvalType;
          this.apprPathList.splice(i, 1, this.apprPathList[i]);
        }
      }
    },
    /**
     * param: user -> Object
     * param: approvalType -> String
     * return:
     * exception:
     * Description : click left button(APPROVAL, AGREEMENT, NOTIFICATION)
     */
    changeUserApprovalType(user, approvalType) {
      // The authorized person cannot be modified
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (!this.apprPathList[i].approverChangeAllowed) {
          SDLUtil.alert('sdl.approval.message.approverNotAllowedToChange');
          return;
        }
      }

      if (this.checkRequired()) {
        // Required payer Check
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return;
      }

      user.approvalType = approvalType;
      this.apprPathList.splice(this.apprPathList.indexOf(user), 1, user);
    },
    /**
     * param:
     * return:
     * exception:
     * Description : click top delete button
     */
    deleteUserTopBtn() {
      if (this.checkRequired()) {
        // Required payer Check
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return;
      }

      const checkParallesGroup = {};
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        const opt = this.apprPathList[i];
        if (opt.parallel) {
          if (typeof checkParallesGroup[opt.stepIdx] === 'undefined') {
            const checkParalles = [];
            checkParalles.push(opt);
            checkParallesGroup[opt.stepIdx] = checkParalles;
          } else {
            checkParallesGroup[opt.stepIdx].push(opt);
          }
        }
      }

      // Check if it is parallel
      let paralleChkFlag = false;
      Object.keys(checkParallesGroup).forEach(i => {
        let n = 0;
        const opt = checkParallesGroup[i];
        Object.keys(opt).forEach(j => {
          if (opt[j].selected) {
            n += 1;
          }
        });
        if (n !== opt.length) paralleChkFlag = true;
      });

      if (paralleChkFlag) {
        SDLUtil.alert('sdl.common.message.possibleToDeleteAfterParallelPayment');
        return;
      }

      const selectedPathList = [];
      this.apprPathList.forEach(path => { if (path.selected) selectedPathList.push(path); });
      selectedPathList.forEach(selectedPath => {
        this.apprPathList.forEach((apprPath, idx) => { if (selectedPath === apprPath) this.apprPathList.splice(idx, 1); });
      });
      this.resetApprovalSeq();
    },
    /**
     * param: user -> Object
     * return:
     * exception:
     * Description : click right delete button
     */
    deleteUserRightBtn(user) {
      // Check if it is parallel
      if (user.parallel) {
        SDLUtil.alert('sdl.common.message.possibleToDeleteAfterParallelPayment');
        return;
      }
      this.apprPathList.splice(this.apprPathList.indexOf(user), 1);

      this.resetApprovalSeq();
    },
    deleteReqUserRightBtn(user) {
      this.requiredApprovalList.splice(this.requiredApprovalList.indexOf(user), 1);
    },
    /**
     * param:
     * return:
     * exception:
     * Description : reset approval sequence numbering
     */
    resetApprovalSeq() {
      let stepIdx = 0;
      let prevIsParallel = false;
      // let preIndex = -1;
      let preSelected = false;
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        const opt = this.apprPathList[i];
        if (!prevIsParallel || !opt.parallel) {
          stepIdx += 1;
        } else if (preSelected !== opt.selected) {
          stepIdx += 1;
        }
        // preIndex = opt.stepIdx;
        prevIsParallel = opt.parallel;
        opt.stepIdx = stepIdx;
        preSelected = opt.selected;

        this.apprPathList.splice(i, 1, opt);
      }
    },
    chkSelectDocType() {
      if (this.selectedDocTypeCode === '') {
        SDLUtil.alert('sdl.approval.message.selectApprovalDocType');
        return false;
      }
      return true;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : Move to Top
     */
    stepTopUp() {
      while (this.stepUp());
    },
    /**
     * param:
     * return:
     * exception:
     * Description : Move up
     */
    stepUp() {
      if (this.checkRequired()) {
        // Check required approver
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return false;
      }

      const checkParallesGroup = {};
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        const opt = this.apprPathList[i];
        if (opt.parallel) {
          if (typeof checkParallesGroup[opt.stepIdx] === 'undefined') {
            const checkParalles = [];
            checkParalles.push(opt);
            checkParallesGroup[opt.stepIdx] = checkParalles;
          } else {
            checkParallesGroup[opt.stepIdx].push(opt);
          }
        }
      }

      // Check if it is parallel
      let paralleChkFlag = false;
      Object.keys(checkParallesGroup).forEach(i => {
        let n = 0;
        const opt = checkParallesGroup[i];
        Object.keys(opt).forEach(j => {
          if (opt[j].selected) {
            n += 1;
          }
        });
        if (n > 0 && n !== opt.length) {
          paralleChkFlag = true;
        }
      });

      if (paralleChkFlag) {
        SDLUtil.alert('sdl.common.message.parallelPaymentCanOnlyBeTransferred');
        return false;
      }

      let flag = false;
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        if (this.apprPathList[i].selected) {
          if (i === 0) {
            return false;
          }
          const tmpItem = this.apprPathList[i];
          const parallelFlag = this.apprPathList[i - 1].parallel;
          this.apprPathList.splice(i, 1, this.apprPathList[i - 1]);
          this.apprPathList.splice(i - 1, 1, tmpItem);
          if (i - 2 >= 0 && this.apprPathList[i - 2].parallel && parallelFlag) {
            this.stepUp();
          }
          flag = true;
        }
      }
      this.resetApprovalSeq();
      return flag;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : Move down
     */
    stepDown() {
      if (this.checkRequired()) {
        // Check required approver
        SDLUtil.alert('sdl.approval.message.cannotChangeRequiredSteps');
        return false;
      }

      const checkParallesGroup = {};
      for (let i = 0; i < this.apprPathList.length; i += 1) {
        const opt = this.apprPathList[i];
        if (opt.parallel) {
          if (typeof checkParallesGroup[opt.stepIdx] === 'undefined') {
            const checkParalles = [];
            checkParalles.push(opt);
            checkParallesGroup[opt.stepIdx] = checkParalles;
          } else {
            checkParallesGroup[opt.stepIdx].push(opt);
          }
        }
      }

      // Check if it is parallel
      let paralleChkFlag = false;
      Object.keys(checkParallesGroup).forEach(i => {
        let n = 0;
        const opt = checkParallesGroup[i];
        Object.keys(opt).forEach(j => {
          if (opt[j].selected) {
            n += 1;
          }
        });
        if (n > 0 && n !== opt.length) {
          paralleChkFlag = true;
        }
      });

      if (paralleChkFlag) {
        SDLUtil.alert('sdl.common.message.parallelPaymentCanOnlyBeTransferred');
        return false;
      }

      let flag = false;
      for (let i = this.apprPathList.length - 1; i >= 0; i -= 1) {
        if (this.apprPathList[i].selected) {
          if (i === this.apprPathList.length - 1) {
            return false;
          }
          const tmpItem = this.apprPathList[i];
          const parallelFlag = this.apprPathList[i + 1].parallel;
          this.apprPathList.splice(i, 1, this.apprPathList[i + 1]);
          this.apprPathList.splice(i + 1, 1, tmpItem);
          if (i + 2 < this.apprPathList.length && this.apprPathList[i + 2].parallel && parallelFlag) {
            this.stepDown();
          }
          flag = true;
        }
      }
      this.resetApprovalSeq();
      return flag;
    },
    /**
     * param:
     * return:
     * exception:
     * Description : Move to the bottom
     */
    stepBottomDown() {
      while (this.stepDown());
    },
  },
  created() {
    this.init();
  },
};
</script>

<style scoped></style>
