<template>
  <div>
    <a-input-search
        class="netLeftTreeInput"
        v-model="fuzzyName"
        :placeholder="$t('functional-analysis.net.please-select-a-structure')"
        allowClear
        @click="clickInput"
        @blur="blur"
        @search="onSearch"
    >
      <a-button type="primary" slot="enterButton" id="netDropLeftTreeSearch">
        <a-icon type="search"/>
      </a-button>
    </a-input-search>
    <div ref="netDropLeftTree" class="netDropLeftTree">
      <a-list :data-source='[]' v-if='isDropEmpty'/>
      <ul id="netDropLeftTree" class="ztree"/>
    </div>
    <!-- Tree Start -->
    <div ref="netLeftTree" :style="{height: netLeftTreeHeight, overflow: 'hidden auto'}">
      <a-list :data-source='[]' v-if='isEmpty'/>
      <ul id="netLeftTree" class="ztree"/>
    </div>
    <!-- Tree End -->
    <!-- 模态框 Start -->
    <DragModal
        :visible="modalVisible"
        :title="title"
        :width="1000"
        :destroyOnClose="true"
        :maskClosable="false"
        @cancel="modalVisible = false"
        :footer="null"
    >
      <!-- 失效 -->
      <AddFault
          v-if="actionName === 'addFault'"
          :struTypeCode="struTypeCode"
          :checkedNode="checkedNode"
          @closeModal="closeModal"
          @initTree="initTree"
      />
    </DragModal>
    <!-- 模态框 End -->
  </div>
</template>
<script>

import DragModal from "@/components/DragModal";
import AddFault from "../AddModal/AddFault";
import {buildNodes, filterNode} from "@/utils/netTree";
import AntSpinDot from "@/components/AntSpinDot/index.vue";
import {fuzzySearch} from '@/utils/fuzzysearch.js';

export default {
  name: "NetLeftTree",
  components: {
    AntSpinDot,
    DragModal,
    AddFault,
  },
  props: {
    dropTreeData: {
      type: Array,
      default: []
    },
    checkedNodes: {
      type: Array,
      default: []
    },
    directFlag: {
      type: Number,
      default: 0 // 0：左侧；1：右侧
    }
  },
  watch: {
    fuzzyName(val) {
      if (!val) {
        this.dropTreeClickNodeId = '';
        this.initTree();
      }
    },
  },
  data() {
    return {
      /** 右键菜单字典 */
      faultNetMenuDict: {
        edit: [
          {
            key: "addFault",
            icon: "iconimage_0",
            label: this.$t('global-constant.contextmenu.failure')
          },
          {
            key: "delete",
            icon: "iconshanchu",
            label: this.$t('global-constant.contextmenu.delete')
          },
          {
            key: "allCollapseExpand",
            icon: "iconzhedie111",
            label: this.$t('global-constant.contextmenu.collapse-expand-all')
          },
        ],
        look: [
          {
            key: "allCollapseExpand",
            icon: "iconzhedie111",
            label: this.$t('global-constant.contextmenu.collapse-expand-all')
          },
        ]
      },
      /** 模态框状态 */
      modalVisible: false,
      /** 模态框唯一Key */
      actionName: "",
      /** 模态框标题 */
      title: "",
      /** 节点类型CODE */
      struTypeCode: "",
      /** 选中节点 */
      checkedNode: "",
      /** 加载对象 */
      loader: undefined,
      /** 空数据标识 */
      isEmpty: true,
      /** 下拉空数据标识 */
      isDropEmpty: true,
      /** 检索输入 */
      fuzzyName: undefined,
      /** 高度 */
      netLeftTreeHeight: '',
      /** 下拉选中ID */
      dropTreeClickNodeId: '',
      /** zTree 配置项 */
      setting: {
        data: {
          key: {
            title: "description"
          },
          simpleData: {
            enable: true,
            idKey: 'id',
            pIdKey: 'pid',
          }
        },
        check: {
          /** 设置 zTree 的节点上是否显示 checkbox / radio */
          enable: true,
          /** 不会有任何自动关联勾选的操作 */
          chkboxType: { "Y": "", "N": "" }
        },
        view: {
          /** 显示 / 不显示 连线 */
          showLine: true,
          /** 显示 / 隐藏 提示信息 */
          showTitle: true,
          /** 支持 / 不支持 HTML 脚本 */
          nameIsHTML: true,
          /** 显示 / 隐藏 图标 */
          showIcon: false,
          /** 双击节点 切换 / 不切换 展开状态 */
          dblClickExpand: false,
          /** 是否允许同时选中多个节点 */
          selectedMulti: false,
          /** 是否允许可以选择 zTree DOM 内的文本 */
          txtSelectedEnable: true,
          /** 显示动画效果 */
          expandSpeed: 'fast'
        },
        callback: {
          beforeRightClick: this.beforeRightClick,
          onCheck: this.onCheck,
          onDblClick: this.onDblClick,
          onRename: this.onRename,
        }
      },
      /** zTree 配置项 */
      dropSetting: {
        data: {
          key: {
            title: "description"
          },
          simpleData: {
            enable: true,
            idKey: 'id',
            pIdKey: 'pid',
          }
        },
        view: {
          /** 显示 / 不显示 连线 */
          showLine: true,
          /** 显示 / 隐藏 提示信息 */
          showTitle: true,
          /** 支持 / 不支持 HTML 脚本 */
          nameIsHTML: true,
          /** 显示 / 隐藏 图标 */
          showIcon: false,
          /** 双击节点 切换 / 不切换 展开状态 */
          dblClickExpand: false,
          /** 是否允许同时选中多个节点 */
          selectedMulti: false,
          /** 是否允许可以选择 zTree DOM 内的文本 */
          txtSelectedEnable: true,
          /** 显示动画效果 */
          expandSpeed: 'fast'
        },
        callback: {
          onClick: this.onDropTreeClick,
        }
      }
    };
  },
  methods: {
    // 初始化tree
    initTree(tabName) {
      let _that = this;
      _that.showHideLoading(true);
      _that.$api.getFaultNetTree({
        fmeaId: _that.$store.getters.rfmeaId,
        struId: _that.$store.getters.lastCheckedNetNode.id,
        selectStruId: _that.dropTreeClickNodeId,
        directFlag: _that.directFlag,
      }).then((res) => {
        if (res.flag) {
          let resData = res.data.rdfmStruTreeModels || [];
          _that.isEmpty = resData.length <= 0;
          // 过滤变体节点
          const filterNodes = filterNode(resData, _that.$store.getters.variantFilterNodes);
          const settings = $.extend({}, this.setting);
          const nodes = buildNodes(filterNodes);
          nodes.forEach(v => {
            v.chkDisabled = this.$api.isLook === '1';
            v.checked = this.checkedNodes.includes(v.id);
            v.nocheck = v.struTypeCode !== '06';
            v.description = this.getNodeName(v);
            v.name = this.getNodeIcon(v) + this.getNodeName(v);
          });
          settings.view.fontCss = this.setFontCss;
          _that.setTreeHeight();
          const zTreeObj = $.fn.zTree.init($('#netLeftTree'), settings, nodes);
          zTreeObj.expandAll(true);
          if (tabName === 'leftFunctionNet') _that.$parent.netLeftTreeFunctionNetNodes = nodes;
        } else {
          _that.$message.error(res.message, 1);
        }
      }).finally(() => {
        _that.showHideLoading(false);
      });
    },
    // 节点数据
    getNodes() {
      const zTreeObj = $.fn.zTree.getZTreeObj('netLeftTree');
      return zTreeObj.getNodes();
    },
    // 设置tree高度
    setTreeHeight() {
      const headerH = document.querySelector('.ant-modal-header').offsetHeight;
      const tabsH = document.querySelector('.ant-tabs-bar').offsetHeight;
      const inputH = document.querySelector('.ant-input').offsetHeight;
      this.netLeftTreeHeight = window.innerHeight - headerH - tabsH - inputH - 70 + 'px';
    },
    // 下拉tree高度
    getDropTreeHeight() {
      const headerH = document.querySelector('.ant-modal-header').offsetHeight;
      const tabsH = document.querySelector('.ant-tabs-bar').offsetHeight;
      const inputH = document.querySelector('.ant-input').offsetHeight;
      return window.innerHeight - headerH - tabsH - inputH - 270 + 'px';
    },
    // 点击输入框
    clickInput() {
      const display = $('.netDropLeftTree').css('display');
      if (display && display === 'none') {
        const inputW = document.querySelector('.netLeftTreeInput').offsetWidth;
        const height = this.getDropTreeHeight();
        $('.netDropLeftTree').css({
          display: 'block',
          position: 'absolute',
          background: '#fff',
          borderRadius: '4px',
          boxShadow: '0 2px 8px rgba(0,0,0,.15)',
          width: inputW + 'px',
          height: height,
          zIndex: '1',
          overflow: 'hidden auto',
        });
        this.initDropTree();
      }
    },
    // 失去焦点
    blur(event) {
      if (event?.relatedTarget && event.relatedTarget?.id && event.relatedTarget.id.includes('netDropLeftTree')) {
        $('.netLeftTreeInput input').focus();
      } else {
        $('.netDropLeftTree').css('display', 'none');
      }
    },
    // 检索
    onSearch(value, event) {
      if (!value) return this.initDropTree();
      fuzzySearch('netDropLeftTree', value, false, true);
      this.setIsDropEmpty();
    },
    // 设置空数据
    setIsDropEmpty() {
      let zTreeObj = $.fn.zTree.getZTreeObj('netDropLeftTree');
      const showNodes = zTreeObj.getNodesByParam('isHidden', false) || [];
      this.isDropEmpty = showNodes.length <= 0;
    },
    // 下拉tree点击
    onDropTreeClick(event, treeId, treeNode) {
      $('.netDropLeftTree').css('display', 'none');
      $('.netLeftTreeInput input').blur();
      this.fuzzyName = treeNode.name;
      this.dropTreeClickNodeId = treeNode.id;
      this.initTree();
    },
    // 初始化下拉tree
    initDropTree() {
      // 过滤变体节点
      const filterNodes = filterNode(this.dropTreeData, this.$store.getters.variantFilterNodes);
      const nodes = buildNodes(filterNodes);
      nodes.forEach(v => v.open = v.deep < 4);
      const settings = $.extend({}, this.dropSetting);
      this.isDropEmpty = nodes.length <= 0;
      $.fn.zTree.init($('#netDropLeftTree'), settings, nodes);
    },
    // 显示、隐藏 -- 加载Loading
    showHideLoading(flag) {
      if (flag) {
        if (this.loader) this.loader.hide();
        this.loader = this.$loading.show({
          container: this.$refs.netLeftTree,
          color: '#1890FF',
        }, {
          // 自定义加载动画组件
          default: this.$createElement('ant-spin-dot'),
        });
      } else {
        this.loader.hide();
      }
    },
    // 设置节点颜色
    setFontCss(treeId, treeNode) {
      const nodeColor = {
        "02": {'color': 'rgb(66, 167, 94)'},
        "04": {'color': '#5b9bd5'},
        "05": {'color': '#5b9bd5'},
        "06": {'color': 'rgb(200, 77, 60)'},
      };
      return nodeColor[treeNode.struTypeCode];
    },
    // 获取右键菜单项
    getMenuBtn(node) {
      // 取得当前节点的右键菜单项
      let cNodeMenus;
      if ("01,99".indexOf(node.struTypeCode) !== -1) { // 结构、接口
        cNodeMenus = ["allCollapseExpand"];
      } else if ("02,04,05".indexOf(node.struTypeCode) !== -1) { // 功能、产品特性、要求
        cNodeMenus = ["addFault", "allCollapseExpand"];
      } else if ("06".indexOf(node.struTypeCode) !== -1) { // 失效
        cNodeMenus = ["delete"];
      }
      let menuBtn = {};
      let functionNetMenuDict = this.$api.isLook === '1' ?
          this.faultNetMenuDict.look : this.faultNetMenuDict.edit;
      functionNetMenuDict.forEach((item) => {
        if (cNodeMenus.indexOf(item.key) !== -1) {
          // 追加菜单项
          let menuObj = {name: item.label, icon: "fas iconfont " + item.icon};
          // 全部展开/折叠，增加分割线。
          if (this.$api.isLook !== '1'
              && "01,99".indexOf(node.struTypeCode) === -1
              && item.key === 'allCollapseExpand') {
            menuBtn['sep'] = "---------";
          }
          menuBtn['' + item.key + ''] = menuObj;
        }
      });
      return menuBtn;
    },
    // 右键菜单位置
    handleContextMenu(node, items) {
      let _that = this;
      let selector = '#' + node.tId + '_a';
      jQuery.contextMenu('destroy', selector); // 销毁所有菜单。
      jQuery.contextMenu({
        selector: selector,
        autoHide: true,
        zIndex: 10,
        items: items,
        callback: function (itemKey, opt) {
          let actionInfo = {key: itemKey};
          _that.menuAction(actionInfo, node);
        },
      });
    },
    // 右键菜单事件
    menuAction(actionInfo, node) {
      this.actionName = actionInfo.key;
      switch (actionInfo.key) {
        case "addFault": // 失效
          this.handleAddModal(this.checkedNode, actionInfo.key);
          this.modalVisible = true;
          break;
        case "delete": // 删除
          this.deleteNode(this.checkedNode);
          break;
        case "allCollapseExpand": // 全部展开/折叠
          this.allCollapseExpand(node);
          break;
      }
    },
    // 处理添加
    handleAddModal(node, menuKey) {
      let name = node.description;
      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;
        }
      }
    },
    // 节点名称
    getNodeName(node) {
      return this.buildLinkName(node) + this.buildNodeName(node);
    },
    // 构建节点名称
    buildNodeName(node) {
      return node.name + (node.suffix ? "\xa0\xa0" + node.suffix : node.suffix);
    },
    // 构建连线名称
    buildLinkName(node) {
      return node.linkName ? (node.linkName + "\xa0\xa0") : '';
    },
    // 节点图标
    getNodeIcon(node) {
      let iconClass = "iconfont ";
      switch (node.struTypeCode) {
        case '02': // 功能
          iconClass += this.$store.getters.treeIcons.function + this.getNodeColor(node);
          break;
        case '04': // 产品特性
          iconClass += this.$store.getters.treeIcons.productFeature + this.getNodeColor(node);
          break;
        case '05': // 要求
          iconClass += this.$store.getters.treeIcons.require + this.getNodeColor(node);
          break;
        case '06': // 失效
          iconClass += this.$store.getters.treeIcons.fault + this.getNodeColor(node);
          break;
        default:
          iconClass = '';
          break;
      }
      return iconClass ? '\xa0<i class="' + iconClass + '"></i>' : '';
    },
    // 节点颜色
    getNodeColor(node) {
      let color = " ";
      let obj = this.$store.getters.nodeTypeDict.color.filter(item => item.key === node.struTypeCode)[0]
      if (obj) color += obj.value;
      return color;
    },
    // 右击
    beforeRightClick(treeId, treeNode) {
      if (!treeNode) return;
      let treeObj = $.fn.zTree.getZTreeObj(treeId);
      let node = treeObj.getNodeByParam("id", treeNode?.id, null);
      if (node) treeObj.selectNode(node);
      this.checkedNode = treeNode;
      let bthMenuBtn = this.getMenuBtn(treeNode);
      if (Object.keys(bthMenuBtn).length > 0) {
        // 右键菜单位置
        this.handleContextMenu(treeNode, bthMenuBtn);
      }
    },
    // 复选框勾选
    onCheck(event, treeId, treeNode) {
      if (this.$api.isLook === '1') return;
      if (treeNode.checked) {
        this.addNetNode(treeNode);
      } else {
        this.deleteNetNode(treeNode);
      }
    },
    // 双击
    onDblClick(event, treeId, treeNode) {
      if (!treeNode) return;
      if (this.$api.isLook === '1') return;
      if (['01', '99', '02', '04', '05'].includes(treeNode?.struTypeCode)) return;
      let treeObj = $.fn.zTree.getZTreeObj(treeId);
      treeNode.name = treeNode.oldName;
      treeObj.editName(treeNode);
    },
    // 重命名
    onRename(event, treeId, treeNode, isCancel) {
      let _that = this;
      let treeObj = $.fn.zTree.getZTreeObj(treeId);
      // 非空
      if (!treeNode.name) treeNode.name = treeNode.oldName;
      // 存在差异，更改
      if (treeNode.name !== treeNode.oldName) {
        if (treeNode.name.length > 500) {
          _that.$message.warn(_that.$t('global-message.warn.node-name-length'));
          treeNode.name = treeNode.oldName;
        } else {
          // 调接口
          _that.$api.updateNodeName({
            fmeaId: _that.$store.getters.rfmeaId,
            struId: treeNode.id,
            struName: treeNode.name,
          }).then((res) => {
            if (res.flag) {
              _that.initTree();
              _that.$message.success(res.message, 1);
            } else {
              _that.$message.error(res.message, 1);
            }
          }).catch((error) => {
            _that.$message.error(error.response.data.message);
          });
        }
      }
      _that.updateFaultNetNode({id: treeNode.id, name: _that.getNodeName(treeNode)});
      treeNode.description = _that.getNodeName(treeNode);
      treeNode.name = _that.getNodeIcon(treeNode) + _that.getNodeName(treeNode);
      treeObj.updateNode(treeNode);
    },
    // 全部折叠/展开
    allCollapseExpand(node) {
      let treeObj = $.fn.zTree.getZTreeObj('netLeftTree');
      let nodes = treeObj.getNodesByParam("level", node.level, null);
      let expandFlag = node?.open;
      for (let i = 0, len = nodes.length; i < len; i++) {
        treeObj.expandNode(nodes[i], !expandFlag, true, node.id === nodes[i].id);
      }
    },
    // 恢复选中节点
    restoreCheckNode(node) {
      let treeObj = $.fn.zTree.getZTreeObj('netLeftTree');
      node.checked = true;
      treeObj.updateNode(node);
    },
    // 关闭模态框
    closeModal() {
      this.modalVisible = false;
    },
    // 添加网节点
    addNetNode(node) {
      this.$emit("addNetNode", this.directFlag, node);
    },
    // 删除网节点
    deleteNetNode(node) {
      this.$emit("deleteNetNode", this.directFlag, node);
    },
    // 删除节点
    deleteNode(node) {
      this.$emit("deleteNode", node);
    },
    // 修改失效网节点
    updateFaultNetNode(node) {
      this.$emit("updateFaultNetNode", node);
    },
  }
}
;
</script>
<style lang="less" scoped>
/deep/ .ztree li a {
  width: calc(100% - 34px) !important;
}

.netDropLeftTree {
  display: none;
}
</style>
