<!--
 Program: DeptListPopup.vue
 Author: SDL
 Description: popup page where you can view and select a list of department
-->
<template>
  <div class="modal-dialog modal-dialog-centered  modal-dialog-scrollable modal-lg">
    <div class="modal-content" style="height:744px;">
      <!-- contents -->
      <div class="modal-header">
        <h5 class="modal-title h4">{{ $t('sdl.department.label.departmentList') }}</h5>
        <button type="button" class="btn-close" data-dismiss="modal" aria-label="Close" @click="$emit('close')"></button>
      </div>
      <div class="modal-body">
        <!-- menu tree -->
        <div class="ui--box-tree">
          <sdl-tree
            ref="tree"
            class="ui--tree"
            :data="treeData"
            :showCheckbox="true"
            :multiple="true"
            :allowBatch="true"
            text-field-name="name"
            whole-row
            @item-toggle="treeItemToggle"
            drag-over-background-color="#e9ecef"
          />
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal" @click="$emit('close')">
          {{ $t('sdl.common.label.cancel') }}
        </button>
        <button type="button" class="btn btn-primary" @click="rtnData">{{ $t('sdl.common.label.confirm') }}</button>
      </div>
    </div>
  </div>
</template>
<script>
import axios from 'axios';
import _ from 'lodash';
import SDLUtil from '@/utils/SDLUtil';

export default {
  data() {
    return {
      treeData: [],
      selectedDeptList: [], // List of selected departments (including sub-departments)
    };
  },
  props: {
    rtnFunc: {
      type: Function,
    },
  },
  methods: {
    /**
     * param: nothing
     * return: nothing
     * exception: nothing
     * description: Query department information to create a tree structure(0,1 Depth Department)
     */
    getTopDepthTreeDeptList() {
      /**
       * Create a tree structure after invoking an API that retrieves 0,1 depth Knox department information
       */
      return axios.get(`${SDLUtil.API_URL}/admin/knox-department`).then(({ data }) => {
        // Create Tree Structure
        if (data.length !== 0) {
          this.makeTreeData_TopDepth(data);
        }
      });
    },
    /**
     * param: object
     * return: nothing
     * exception: nothing
     * description: Use the toggle trigger to prevent calls multiple times and call once
     */
    // eslint-disable-next-line func-names
    debouncedItemToggle: _.debounce(function (model) {
      if (model.existSubDepartment) {
        SDLUtil.showLoadingBar(true);
        // Query Knox department, and delete loading bar
        this.getBottomDepthTreeDeptList(model).then(() => SDLUtil.showLoadingBar(false));
      }
    }, 10),
    /**
     * param: object
     * return: nothing
     * exception: nothing
     * description: The toggle function is performed in the tree structure.
     */
    treeItemToggle(oriNode, oriItem) {
      this.debouncedItemToggle(oriItem);
    },
    /**
     * param: nothing
     * return: nothing
     * exception: nothing
     * description: Query department information to create a tree structure(2 Depth Department)
     */
    getBottomDepthTreeDeptList(deptObj) {
      // Bottem depth Knox department
      return axios.get(`${SDLUtil.API_URL}/admin/knox-department/${deptObj.deptCode}`).then(({ data }) => {
        // Create Tree Structure
        this.makeTreeData_BottomDepth(deptObj, data);
      });
    },
    /**
     * param: array
     * return: nothing
     * exception: nothing
     * description: Create Tree Structure(0,1 Depth Department)
     */
    makeTreeData_TopDepth(data) {
      const depts = data.map(dept => ({
        ...dept,
        id: dept.deptCode,
        name: dept.deptName,
      }));
      // Find Top Menu
      const root = depts.find(dept => dept.deptLevel === 0);

      root.opened = true;
      root.dragDisabled = true;
      root.name = 'Knox Department';

      // Top & 1 Depth Department Settings
      let children = depts.filter(dept => dept.upperDeptCode === root.deptCode);
      children = _.sortBy(children, ['deptSequence']);
      children.forEach(d => {
        d.dragDisabled = true;
        d.isFolder = d.existSubDepartment;
      });

      root.children = children;
      this.treeData = [root];
      this.$refs.tree.initializeData(this.treeData);
    },
    /**
     * param: string, array
     * return: nothing
     * exception: nothing
     * description: Create Tree Structure(Bottom Depth Department)
     */
    makeTreeData_BottomDepth(deptObj, data) {
      const { deptCode } = deptObj;
      const checkYn = deptObj.selected;

      let childDepts = data.map(dept => ({
        ...dept,
        id: dept.deptCode,
        name: dept.deptName,
      }));

      childDepts = _.sortBy(childDepts, ['deptSequence']);
      childDepts.forEach(d => {
        d.dragDisabled = true;
        d.opened = false;
        d.children = [];
        d.selected = checkYn;
        d.isFolder = d.existSubDepartment;
      });

      const addChild = (treeData, parantCode) => {
        treeData.forEach(treeItem => {
          if (treeItem.deptCode === deptCode) {
            treeItem.children = childDepts;
          } else {
            addChild(treeItem.children, parantCode);
          }
        });
      };

      addChild(this.treeData, deptCode);
      this.$refs.tree.initializeData(this.treeData);
    },
    /**
     * param: nothing
     * return: nothing
     * exception: nothing
     * description: Forward selected list to call page via function
     */
    rtnData() {
      this.$refs.tree.handleRecursionNodeChilds(this.$refs.tree, nodeItem => {
        if (nodeItem.model && nodeItem.model.selected) {
          this.selectedDeptList.push(nodeItem.model);
        }
      });

      this.rtnFunc(this.selectedDeptList);
      this.$emit('close');
    },
  },
  created() {
    // Launch Loading bar
    SDLUtil.showLoadingBar(true);
    // Call up department list lookup and tree structure generation functions
    this.getTopDepthTreeDeptList().then(() => SDLUtil.showLoadingBar(false));
  },
};
</script>
<style></style>
