<template>
  <div id='leftTree' ref='parameterLeftTree' class='leftTree'>
    <div class='closeRightMenu' @click='closeRightMenu' @mousewheel='closeRightMenu'>
      <!-- Tree Start -->
      <a-spin
          :delay='delayTime'
          :spinning='treeLoading'
          :tip='spinTip'>
        <a-tree
            v-if='treeData && treeData.length > 0'
            key='leftTree'
            :autoExpandParent='autoExpandParent'
            :blockNode='true'
            :expandedKeys='expandedKeys'
            :replaceFields='replaceFields'
            :selected-keys='[]'
            :tree-data='treeData'
            @expand='expand'
            @rightClick='contextmenu'
            @select='nodeClick'>
          <template slot='treeDataSlot' slot-scope='node'>
            <a :id="'paramLeftTreeNode' + node.id" :class='getStruTypeCodeClass(node)'>
                            <span>
                                <span>{{ '\xa0' }}</span>
                                <span v-if="node.struTypeCode === '01'"
                                      :id="'paramLeftTreeNodeName' + node.id"
                                      :title='node.name'>
<!--                                <a-icon type="apartment" />-->
                                    <span v-if='node.connectId' class='iconfont'>&#xe778;</span>
                                    <span v-else class='iconfont'>&#xe671;</span>
                                    <span>{{ '\xa0' }}</span>
                                    {{ node.name }}
                                </span>
                                <span v-if="node.struTypeCode === '99'"
                                      :id="'paramLeftTreeNodeName' + node.id"
                                      :title='node.name'>
                                    <a-icon type='deployment-unit'/>
                                    {{ node.name }}
                                </span>
                            </span>
            </a>
          </template>
        </a-tree>
      </a-spin>
      <!-- Tree End -->

      <!-- 模态框 Start -->
      <DragModal
          :footer='null'
          :title='title'
          :visible='modalVisible'
          :width='1000'
          destroy-on-close
          @cancel='modalVisible = false'>
        <!-- 添加结构 -->
        <AddStructure
            v-if="actionName === 'addStructure'"
            ref='addStruModel'
            :addType='addType'
            :checkedNode='checkedNode'
            :struTypeCode='struTypeCode'
            @closeModal='closeModal'
            @initLeftTree='initLeftTree'/>
      </DragModal>
      <!-- 模态框 End -->

      <!-- 右键菜单 Start -->
      <div v-show='menuVisible'
           ref='contextmenu'
           class='contextmenu'
           @mouseleave='closeRightMenu'
           @mousedown.stop='menuVisible != menuVisible'>
        <a v-for='(item, index) in menuList'
           :key='index'
           @click='menuAction(item)'>
          <i :class="'iconfont ' + item.icon"></i>
          {{ $t('' + item.label + '') }}
        </a>
      </div>
      <!-- 右键菜单 End -->
    </div>
  </div>
</template>
<script>

import {addClass, getViewPortOffset, removeClass, toggleClass} from '@/utils';
import DragModal from '@/components/DragModal/index.vue';
import AddStructure from '../../../../AddModal/AddStructurel.vue';
import {arrayToTree} from '@/utils/tree';

export default {
  name: 'ParameterLeftTree',
  components: {
    DragModal,
    AddStructure
  },
  data() {
    return {
      /** 用于改名时 ecs 退出会触发input blur，esc不能触发blur */
      ecsFlag: false,
      /** 展开/折叠状态 */
      exp: false,
      /** 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段 */
      replaceFields: {key: 'id', title: 'name'},
      /** (受控)展开指定的树节点 */
      expandedKeys: [],
      /** 所有节点 */
      allNode: [],
      /** 是否自动展开父节点   */
      autoExpandParent: false,
      /** tree数据 */
      treeData: [],
      /** 右键菜单状态 */
      menuVisible: false,
      /** 模态框状态 */
      modalVisible: false,
      /** 模态框唯一Key */
      actionName: '',
      /** 模态框标题 */
      title: '',
      /** 节点类型CODE */
      struTypeCode: '',
      /** 右键菜单列表 */
      menuList: [],
      /** 选中节点 */
      checkedNode: '',
      /** tree加载中状态 */
      treeLoading: false,
      /** 延迟显示加载效果的时间（防止闪烁）*/
      delayTime: 300,
      /** 自定义Loading描述文案 */
      // spinTip: "加载中...",
      spinTip: '',
      tabKey: '',
      addType: '',
      moveNodeFlag: true
    };
  },
  watch: {
  },
  mounted() {
    this.initLeftTree();
  },
  methods: {
    /**
     * 初始化结构树
     */
    async initLeftTree() {
      let _that = this;
      _that.treeLoading = true;
      await _that.$api.getBoundaryStruTree({
        fmeaId: _that.$store.getters.rfmeaId
      }).then((res) => {
        if (res.flag) {
          let targetNode = res.data.mfmeaStruTreeModels.filter((item) => {
            return item.pid === '00000000000000000000000000000000';
          })[0];
          let struList = res.data.mfmeaStruTreeModels.map(function (item) {
            if (item => item.deep != 1) {
              return item.id;
            }
          });
          this.$store.dispatch('fmeaTree/set', {
            key: 'boundaryStruIdList',
            value: struList
          });
          let treeData = arrayToTree(targetNode, res.data.mfmeaStruTreeModels);
          _that.treeData = _that.addScopedSlots(treeData);
          // 默认展开全部节点
          _that.defaultExpandedAllKeys(treeData);
        } else {
          _that.$message.error(res.message, 1);
        }
      }).finally(() => {
        _that.treeLoading = false;
        _that.moveNodeFlag = true;
      });
    },
    /**
     * 默认展开全部节点
     */
    defaultExpandedAllKeys(treeData) {
      let _that = this;
      for (let i = 0; i < treeData.length; i++) {
        _that.expandedKeys.push(treeData[i].id);
        if (treeData[i].children && treeData[i].children.length > 0) {
          _that.defaultExpandedAllKeys(treeData[i].children);
        }
      }
    },
    /**
     * 添加插槽
     */
    addScopedSlots(data) {
      for (var i in data) {
        this.allNode.push(data[i]);
        // 通过vue 自带的$set 给每条数据加上一个名为scopedSlots，值为{title: 'node'}，的插槽
        this.$set(data[i], 'scopedSlots', {title: 'treeDataSlot'});
        if (data[i].children && data[i].children.length > 0) {
          this.addScopedSlots(data[i].children);
        }
      }
      return data;
    },
    /**
     * 图标展开/收起节点时触发
     */
    expand(expandedKeys, e) {
      this.expandedKeys = expandedKeys;
      this.autoExpandParent = false;
      this.exp = e.expanded;
    },
    /**
     * 单级折叠/展开
     */
    collapseExpand(exp) {
      let _that = this;
      let arry = this.expandedKeys;
      if (_that.$store.getters.parameterCheckedNode) {
        if (exp) {
          arry.filter((item, index) => {
            if (item === _that.$store.getters.parameterCheckedNode.id) {
              arry.splice(index, 1);
            }
          });
          this.exp = !exp;
        } else {
          this.exp = !exp;
          arry.push(_that.$store.getters.parameterCheckedNode.id);
        }
      }
    },
    /**
     * 全部折叠/展开
     */
    collapseExpandAll(exp) {
      let _that = this;
      let select = [];
      let arry = this.allNode;
      if (_that.$store.getters.parameterCheckedNode) {
        if (exp) {
          arry.filter((item, index) => {
            if (item.deep === _that.$store.getters.parameterCheckedNode.deep) {
            } else {
              select.push(item.id);
            }
          });
          this.expandedKeys = select;
          this.exp = !exp;
        } else {
          arry.filter((item, index) => {
            this.expandedKeys.push(item.id);
          });
          this.exp = !exp;
        }
      }
    },
    /**
     * 节点单击事件
     * 参数：selectedKeys, e:{selected: bool, selectedNodes, node, event}
     */
    nodeClick(selectedKeys, e) {
      // 展开/折叠状态
      this.exp = e.node.expanded;
      // 存储当前节点信息
      // this.storeCheckedNode(e.node.dataRef);
      this.setParameterNode(e.node.dataRef);
      // 高亮当前节点
      this.highLightNode(e.node.dataRef);
    },
    /**
     * 右键事件
     */
    contextmenu({event, node}) {
      // 展开/折叠状态
      this.exp = node.expanded;
      // 存储当前节点信息
      this.storeCheckedNode(node.dataRef);
      // 高亮当前节点
      this.highLightNode(node.dataRef);
      // 过滤菜单按钮
      this.filterMenuBtn();
      // 右键菜单位置
      this.contextMenuDistance(event);
    },
    /**
     * 菜单
     */
    filterMenuBtn() {
      // 选中节点
      let checkedNode = this.$store.getters.parameterCheckedNode;
      // 复制剪切的节点
      let lastCopyOrCutNode = this.$store.getters.lastCopyOrCutNode;
      // 复制剪切的标识位：copy、cut
      // let lastCopyOrCut = this.$store.getters.lastCopyOrCut;
      let cNodeMenus = this.getCurrentNodeMenus(checkedNode);
      console.log(cNodeMenus);
      this.menuList = [];
      console.log('filterMenuBtn');
      this.$store.getters.pLeftTreeMenus.forEach((item) => {
        if (cNodeMenus.indexOf(item.key) !== -1) {
          switch (item.key) {
            case 'addStructure':
              if (checkedNode.struTypeCode === '99') {
                return false;
              }
              break;
            case 'cut':
            case 'delete':
            case 'copy':
              if (checkedNode.deep === 1) {
                return false;
              }
              break;
            case 'paste':
              if (checkedNode.deep === 1) {
                return false;
              }
              if (!lastCopyOrCutNode) {
                return false;
              }
              break;
            default:
              break;
          }
          // 追加菜单项
          this.menuList.push(item);
        }
      });
      this.menuVisible = true;
    },
    //父结构是否为接口
    parentIsApi(node) {
      let parent = this.$store.getters.boundaryStruIdList.filter((item) => item.id === node.pid);
      if (parent.length > 0) {
        if (parent[0].struTypeCode === '99') {
          return false;
        } else {
          return this.parentIsApi(parent[0]);
        }
      }
      return false;
    },
    //子结构是否为接口
    childIsApi(node) {
      if (node.children.length > 0) {
        for (let i = 0; i < node.children.length; i++) {
          //子结构中有接口
          if (node.children[i].struTypeCode === '99') {
            return true;
          }
          return this.childIsApi(node.children[i]);
        }
      }
      return false;
    },
    /**
     * 取得当前节点的右键菜单项
     * @param checkNode 选中节点
     */
    getCurrentNodeMenus(checkNode) {
      let nodeTypeDict = Object.values(this.$store.getters.nodeTypeDict.structureAnalysis).filter((item) => {
        return item.key === checkNode.struTypeCode;
      })[0];
      // 1：只读，2：编制
      let readOnly = this.$api.isLook;
      // 只读
      if (readOnly === '1') {
        return nodeTypeDict.leftMenuReadOnly;
      } else {
        return nodeTypeDict.leftMenu;
      }
    },
    /**
     * 菜单事件
     */
    menuAction(actionInfo) {
      console.log(actionInfo);
      this.checkedNode = this.$store.getters.checkedLeftNode;
      this.actionName = actionInfo.key;
      let checkedNode = this.$store.getters.parameterCheckedNode;
      this.closeRightMenu();
      switch (actionInfo.key) {
        case 'addStructure': // 添加结构
          this.addType = 'struTree';
          this.clearHighLightCopyCutNode();
          this.handleAddModal(checkedNode, actionInfo.key);
          this.modalVisible = true;
          break;
        case 'copy': // 复制
          this.setHighLightCopyCutNode('copy');
          break;
        case 'cut': // 剪切
          this.setHighLightCopyCutNode('cut');
          break;
        case 'paste': // 粘贴
          this.paste();
          break;
        case 'delete': // 删除
          this.clearHighLightCopyCutNode();
          this.deleteNode(checkedNode);
          break;
      }
    },
    /**
     * 处理添加
     * @param node 节点
     * @param menuKey 菜单标识
     */
    handleAddModal(node, menuKey) {
      let name = node.name;
      let adds = this.$store.getters.nodeTypeDict.addModals;
      for (let i = 0, len = adds.length; i < len; i++) {
        if (adds[i].menuKey === menuKey) {
          this.title = this.$t('' + adds[i].title + '') + name;
          this.struTypeCode = adds[i].struTypeCode;
          this.tab = this.$t('' + adds[i].label + '');
          return;
        }
      }
    },
    /**
     * 处理评审意见Modal逻辑
     * @param node 节点
     */
    handleReviewCommentsModal(node) {
      let name = '14,07'.indexOf(node.struTypeCode) !== -1 ? '' : node.name;
      let reviewComments = this.$store.getters.nodeTypeDict.reviewCommentsModals;
      for (let i = 0, len = reviewComments.length; i < len; i++) {
        if ('09,10'.indexOf(node.struTypeCode) !== -1
            && reviewComments[i].key === node.curOptTypeCode) {
          this.title = reviewComments[i].title + name;
          return;
        }
        if (reviewComments[i].key === node.struTypeCode) {
          this.title = reviewComments[i].title + name;
          return;
        }
      }
    },
    /**
     * 右键菜单位置
     */
    contextMenuDistance(event) {
      let viewAreaWH = getViewPortOffset();
      this.$refs.contextmenu.style.left = event.clientX + 'px';
      let headerAndBtnH = 70;
      let menuH = this.menuList.length * 29.5;
      this.$refs.contextmenu.style.top = event.clientY - headerAndBtnH
          - (viewAreaWH.h < event.clientY + menuH ? event.clientY + menuH - viewAreaWH.h : 0) + 'px';
      event.preventDefault ? event.preventDefault() : (event.returnValue = false);
    },

    /**
     * 键盘松开事件
     */
    keyup(e, node) {
      if (e.keyCode === 13) { // Enter
        document.getElementById('paramLeftTreeNodeInput' + node.id).blur();
      } else if (e.keyCode === 27) {  // Ecs
        this.ecsFlag = true;
        let leftTreeNodeName = document.getElementById('paramLeftTreeNodeName' + node.id);
        let leftTreeNodeInput = document.getElementById('paramLeftTreeNodeInput' + node.id);
        toggleClass(leftTreeNodeName, 'hide');
        toggleClass(leftTreeNodeInput, 'hide');
        this.keyListenerChange(false);
      }
    },
    /**
     * 修改名称
     */
    updateNodeName(node) {
      let _that = this;
      if (this.ecsFlag) return;
      let leftTreeNodeName = document.getElementById('paramLeftTreeNodeName' + node.id);
      let leftTreeNodeInput = document.getElementById('paramLeftTreeNodeInput' + node.id);
      let newName = leftTreeNodeInput.value;
      // input框值为空、new与old名称一样时，不调接口
      if (!newName || newName === node.name) {
        toggleClass(leftTreeNodeName, 'hide');
        toggleClass(leftTreeNodeInput, 'hide');
        _that.keyListenerChange(false);
        return;
      }

      // 调接口改变值
      _that.$api.updateNodeName({
        fmeaId: _that.$store.getters.rfmeaId,
        struId: node.id,
        struName: newName
      }).then((res) => {
        if (res.flag) {
          _that.$message.success(res.message, 1);
          node.name = newName;
          // 修改treeData节点数据（名称）
          _that.updateTreeDataNode(_that.treeData, node);
          _that.initLeftTree();
        } else {
          _that.$message.error(res.message, 1);
        }
      }).catch((error) => {
        _that.$message.error(error.response.data.message, 1);
      }).finally(() => {
        toggleClass(leftTreeNodeName, 'hide');
        toggleClass(leftTreeNodeInput, 'hide');
        _that.keyListenerChange(false);
      });
    },
    /**
     * 修改treeData节点数据（名称）
     * @param treeData
     * @param targetNode 目标节点
     */
    updateTreeDataNode(treeData, targetNode) {
      for (let i = 0, len = treeData.length; i < len; i++) {
        if (treeData[i].id === targetNode.id) {
          treeData[i].name = targetNode.name;
          return true;
        }
        if (treeData[i].children && treeData[i].children.length > 0) {
          let result = this.updateTreeDataNode(treeData[i].children, targetNode);
          if (result) return true;
        }
      }
      return false;
    },
    /**
     * 粘贴节点
     */
    paste() {
      let _that = this;
      // 判断是复制还是剪切，并调用接口
      _that.$api.rdfmPdPaste({
        optType: _that.$store.getters.lastCopyOrCut === 'copy' ? 1 : 2, // 1:表示复制，2:表示剪切
        sourceStruId: _that.$store.getters.lastCopyOrCutNode.id,
        targetStruId: _that.$store.getters.parameterCheckedNode.id,
        fmeaId: _that.$store.getters.rfmeaId
      }).then((res) => {
        if (res.flag) {
          _that.$emit('initParameterData', _that.$store.getters.parameterCheckedNode.id);
        } else {
          _that.$message.error(res.message, 1);
        }
      }).finally(() => {
        // 清除：复制/剪切时，节点高亮
        this.clearHighLightCopyCutNode();
      });
    },
    /**
     * 删除节点
     */
    deleteNode(node) {
      let _that = this;
      this.$confirm({
        title: this.$t('global-message.warn'),
        content: this.$t('global-message.warn.delete-p-chart'),
        icon: 'warning', //图标，不想用就随便写一个
        okText: this.$t('global-btn.confirm'),
        cancelText: this.$t('global-btn.cancel'),
        onOk() {
          _that.$api.rdfmPdDel({
            fmeaId: _that.$store.getters.rfmeaId,
            struId: node.id
          }).then((res) => {
            if (res.flag) {
              _that.$emit('initParameterData', _that.$store.getters.parameterCheckedNode.id);
            } else {
              _that.$message.error(res.message, 1);
            }
          });
        },
        onCancel() {
        }
      });
    },
    /**
     * 高亮节点
     */
    highLightNode(node) {
      let className = 'leftTree-node-selected';
      let arr = document.getElementsByClassName(className);
      // 清除其他高亮节点
      if (arr[0]) arr[0].classList.remove(className);
      if (node) {
        addClass(
            document.getElementById('paramLeftTreeNode' + node.id),
            className
        );
      }
    },
    /**
     * 选中节点时，存储当前节点信息
     */
    storeCheckedNode(node) {
      this.$store.dispatch('fmeaTree/set', {
        key: 'checkedLeftNode',
        value: node
      });
      this.$store.dispatch('fmeaTree/set', {
        key: 'parameterCheckedNode',
        value: node
      });
      this.$store.dispatch('fmeaTree/set', {
        key: 'lastCheckedNodeTree',
        value: 'struTree'
      });
    },
    /**
     * 设置：复制/剪切时，节点高亮
     */
    setHighLightCopyCutNode(cutCopy) {
      console.log('setHighLightCopyCutNode===', cutCopy);
      console.log(this.$store.getters.parameterCheckedNode);
      console.log(this.$store.getters.lastCopyOrCutNode);
      this.clearHighLightCopyCutNode();
      this.$store.dispatch('fmeaTree/set', {
        key: 'lastCopyOrCutNode',
        value: this.$store.getters.parameterCheckedNode
      });
      // 存储操作类型：复制=copy or 剪切=cut
      this.$store.dispatch('fmeaTree/set', {
        key: 'lastCopyOrCut',
        value: cutCopy
      });
      addClass(
          document.getElementById('paramLeftTreeNode' + this.$store.getters.lastCopyOrCutNode.id),
          'copy-cut'
      );
    },
    /**
     * 清除：复制/剪切时，节点高亮
     */
    clearHighLightCopyCutNode() {
      if (!this.$store.getters.lastCopyOrCutNode) return;
      removeClass(
          document.getElementById('paramLeftTreeNode' + this.$store.getters.lastCopyOrCutNode.id),
          'copy-cut'
      );
      this.$store.dispatch('fmeaTree/clearCopyOrCut');
    },
    /**
     * 关闭弹窗
     */
    closeModal() {
      this.modalVisible = false;
    },
    /**
     * 隐藏右键菜单
     */
    closeRightMenu() {
      this.menuVisible = false;
    },
    /**
     * 监听快捷键
     * @param flag true、false
     */
    keyListenerChange(flag) {
      this.$emit('keyListenerChange', flag);
    },
    /**
     * 处理属性Modal逻辑
     * @param node 节点
     * @param tabKey 选项卡Key
     */
    handlePropertyModal(node, tabKey = '') {
      let name = '14,07'.indexOf(node.struTypeCode) !== -1 ? '' : node.name;
      let merges = this.$store.getters.nodeTypeDict.propertyModals;
      let merge = {};
      for (let i = 0; i < merges.length; i++) {
        if ('09,10'.indexOf(node.struTypeCode) !== -1
            && merges[i].key === node.curOptTypeCode) {
          merge = merges[i];
          break;
        }
        if (merges[i].key === node.struTypeCode) {
          merge = merges[i];
          break;
        }
      }
      this.actionName = merge.action;
      this.title = merge.title + name;
      this.tabKey = tabKey;
    },
    getStruTypeCodeClass(node) {
      let typeClass = '';
      if (node.struTypeCode === '99') {
        typeClass += ' apiClass';
      }
      return typeClass;
    },
    setParameterNode(node) {
      this.$store.dispatch("fmeaTree/set", {
        key: "parameterCheckedNode",
        value: node
      });
    }
  }
};
</script>
<style lang='less' scoped>
.closeRightMenu {
  min-width: 400px;
  max-height: calc(100vh - 40px);
}

.imgClass {
  margin-top: 5px;
  margin-right: 8px;
  margin-bottom: -4px;
}

.contextmenu {
  width: 180px;
  background: #FFF;
  //border: 1px solid #bebebe;
  display: inline-block;
  font-family: inherit;
  font-size: inherit;
  list-style-type: none;
  position: absolute;
  overflow: hidden;
  border-radius: 0.5em !important;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
  z-index: 2;

  a:hover {
    background-color: #1890FF !important;
    color: #FFF !important;
    cursor: pointer;
    border-radius: 0.5em !important;
  }

  a {
    display: block;
    //font-weight: 700;
    line-height: 24px;
    padding: 2px 12px;
  }
}

.min-width {
  min-width: 2000px;
}

.leftTree-node-selected {
  background-color: #9bf2eb;
  border-radius: 2px;
}

.apiClass {
  border: #4dd9d5 2px solid;
}
</style>

<style lang='less'>

.ant-tree li .ant-tree-node-content-wrapper {
  padding: 0 0 !important;
}
</style>

<style lang='less' scoped>
/deep/ .ant-tree li {
  padding: 5px 0;
}

/deep/ .ant-tree-title {
  a {
    width: 100%;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    display: inline-block;

    input {
      width: 80%;
      height: 20px;
      padding: 0px;
    }
  }
}

.copy-cut {
  border: 1px dashed red !important;
  border-radius: 2px;
}
</style>
