<template>
  <span>
    <!-- 选择部门 -->
    <a-select
      v-model="depvalue"
      :options="depOptions"
      :class="$style.depselect"
      @change="changedep"
    >
    </a-select>
    <a-spin ref="scroll" :spinning="false" :class="$style.spin">
      <a-empty v-if="empty" />
      <a-dropdown
        v-else
        v-model="showMenu"
        :get-popup-container="() => this.$refs.scroll.$el"
        :trigger="['contextmenu']"
        :disabled="single"
        @visibleChange="menuVisibleChange"
      >
        <div>
          <a-tree
            :key="key"
            ref="auditMattersTree"
            v-model="checkedKeys"
            :show-icon="true"
            :show-line="true"
            :check-strictly="true"
            :checkable="checkable"
            :draggable="draggable"
            :tree-data="treeData"
            :replace-fields="replaceFields"
            :selected-keys="defaultSelectedKeys"
            :expanded-keys="expandedKeys"
            :default-expanded-keys="defaultTreeExpandedKeys"
            :load-data="onLoadData"
            @click.native="treeClickNative"
            @select="treeSelect"
            @check="treeCheck"
            @rightClick="treeRightClick"
            @contextmenu.native.capture="treeRightClickNative"
            @expand="onExpand"
          >
            <!-- 如果已配置负责人，则展示用户图标 -->
            <template slot="showMatters" slot-scope="item">
              <a-icon type="file-ppt" @click="showMatters(item)" />
            </template>
          </a-tree>
        </div>

        <a-menu slot="overlay" @click="menuClick">
          <a-menu-item key="1" :disabled="!selectedNodeHasSelectableChild">
            <a-icon type="check" />选中下一级节点
          </a-menu-item>
          <a-menu-item key="2" :disabled="!selectedNodeHasSelectableChild">
            <a-icon type="close" />取消下一级节点
          </a-menu-item>
        </a-menu>
      </a-dropdown>
    </a-spin>
  </span>
</template>

<script>
import { getUserInfo } from '@/common/store-mixin'
import auditMattersTreeService from './audit-matters-tree-service'
import components from './_import-components/audit-matters-tree-import'
// 判断是否已经选择
function isChecked(selectedKeys, eventKey) {
  return selectedKeys.indexOf(eventKey) === -1
}
export default {
  name: 'AuditMattersTree',
  metaInfo: {
    title: 'AuditMattersTree',
  },
  components,
  props: {
    // 默认选中节点
    selectedKeys: {
      type: Array,
      default: function() {
        return []
      },
    },

    // 是否显示复选框
    checkable: {
      type: Boolean,
      default: true,
    },
    // 是否可以拖拽
    draggable: {
      type: Boolean,
      default: false,
    },
    // 是否显示连线
    showLine: {
      type: Boolean,
      default: false,
    },
    // 根节点名称
    topNodeText: {
      type: String,
      default: '根节点',
    },
    // 地址树接口数据源
    treeparams: {
      type: Object,
      default: () => {
        return {}
      },
    },
    // 默认展开节点id
    defaultExpandedKeys: {
      type: Array,
      default: () => {
        return ['0']
      },
    },

    // 是否显示隐藏按钮
    showPrimary: {
      type: Boolean,
      default: true,
    },
    // 地址树是否单选
    single: {
      type: Boolean,
      default: false,
    },
    refreshKey: {
      type: Number,
      default: 0,
    },

    treeDataType: {
      type: String,
      default: '',
    },
    /**
     * 是否是审计框架拷贝事项
     */
    isFrameCopy: {
      type: Boolean,
      default: false,
    },
    // frameId
    frameId: {
      type: Number,
      default: -1,
    },
  },
  data() {
    return {
      treeData: [],
      defaultTreeExpandedKeys: ['0'],
      defaultSelectedKeys: ['0'],
      checkedKeys: {
        checked: [],
        halfChecked: [],
      }, // 选中的节点数据
      dataList: [], // 数组dataList，搜索要用
      spinning: true,
      empty: false,
      icontype: 'left',
      fold: false,
      replaceFields: {
        title: 'text',
        key: 'id',
      },
      openId: [], // 已经打开过的id
      expandedKeys: ['0'],
      backupsExpandedKeys: [],
      autoExpandParent: false,
      defaultTopNodeText: '根节点',
      defaultTopNodeId: '0',
      key: 0,
      newtree: [],
      depOptions: [], // 部门下拉框列表值
      edit: true, // 当前节点是否可编辑
      depvalue: [], // 选择的组织数据
      selectedNode: undefined,
      showMenu: false,
      setAllChecking: false,
    }
  },
  computed: {
    selectedNodeHasSelectableChild() {
      return this.selectedNode?.dataRef.children?.some((item) => !item.disabled)
    },
  },
  created() {
    // 如果有默认展开节点，则赋值
    if (this.defaultExpandedKeys) {
      this.defaultTreeExpandedKeys = [...this.defaultExpandedKeys]
    }
    // 如果有传根节点名称，则赋值
    if (this.topNodeText) {
      this.defaultTopNodeText = this.topNodeText
    }
    // 如果有传默认选中节点，则赋值
    if (this.selectedKeys.length > 0) {
      this.defaultSelectedKeys = [...this.selectedKeys]
    }
    // this.initTreeData()
    this.initDeptList('iamAuditMatters')
  },
  methods: {
    treeRightClickNative(evt) {
      // 右键如果没有点击到树节点，不触发右键菜单
      if (this.single) return
      if (evt.target.nodeName !== 'SPAN') evt.stopPropagation()
    },
    treeClickNative() {
      // 点击树的其他区域，隐藏菜单
      if (this.single) return
      this.hideContextMemu()
    },
    menuClick(menu) {
      this.selectedNode.dataRef.children?.forEach((item) => {
        if (!item.disabled) this.itemSelect(item.id, menu.key === '1')
      })
      this.hideContextMemu()
    },
    itemSelect(key, checked) {
      if (checked) {
        if (!this.checkedKeys.checked.includes(key)) {
          this.checkedKeys.checked.push(key)
        }
      } else {
        this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(key), 1)
      }
    },
    hideContextMemu() {
      this.showMenu = false
      this.menuVisibleChange(false)
    },
    menuVisibleChange(visible) {
      if (!visible) this.selectedNode = undefined
    },
    treeRightClick({ node }) {
      // 记录当前点击的节点
      if (this.single) return
      this.selectedNode = node
    },
    // 初始化部门下拉 分级授权获取部门下拉列表  维护权限
    initDeptList(formId) {
      auditMattersTreeService.getManagedHierarchyOrg(formId).then((res) => {
        res.data.editNodes.forEach((item) => {
          this.depOptions.push({
            label: item.text,
            value: item.id,
            text: item.text,
            edit: true,
          })
        })
        // 取编辑和查看节点并集
        res.data.viewNodes.forEach((item, index) => {
          const node = this.depOptions.find((nodeinfo) => {
            return nodeinfo.value === item.id
          })
          if (!node) {
            this.depOptions.push({
              label: item.text,
              value: item.id,
              text: item.text,
              edit: false,
            })
          }
        })

        // 部门下拉框列表值赋值

        if (this.depOptions.length > 0) {
          this.depvalue = this.depOptions[0].value
          // 加载默认值
          this.defaultTopNodeId = this.depOptions[0].value
          this.defaultTopNodeText = this.depOptions[0].text + this.topNodeText
          this.defaultTreeExpandedKeys = [this.depOptions[0].value]
          this.defaultSelectedKeys = [this.depOptions[0].value]
          this.edit = this.depOptions[0].edit
          this.initTreeData(this.depOptions[0].value)
        } else {
          this.defaultTopNodeId = null
          this.defaultTopNodeText = null
          this.defaultTreeExpandedKeys = []
          this.defaultSelectedKeys = []
          this.spinning = false
          this.empty = true
        }
      })
    },
    setIsItem(data) {
      for (let i = 0; i < data.length; i++) {
        const node = data[i]
        const props = node.props
        if (node.isLeaf !== true && !this.isFrameCopy) {
          node.disabled = true
        }
        // 用来判断此几点是否已经配置了用户，需要后台返回标识位进行判断
        if (props && props.isItem) {
          data[i].scopedSlots.icon = 'showMatters'
          if (!data[i].id.toString().includes('-item')) {
            data[i].id = data[i].id + '-item'
          }
        }
        if (node.children) {
          this.setIsItem(node.children)
        }
      }
    },
    /**
     * 显示事项
     */
    showMatters(item) {
      this.$emit('showMatters', item)
    },
    // 选中当前节点下的所有节点
    checkAllNode(nodeinfo, checked) {
      if (nodeinfo.children) {
        nodeinfo.children.forEach((node) => {
          if (checked) {
            if (isChecked(this.checkedKeys.checked, node.id)) {
              this.checkedKeys.checked.push(node.id)
            }
          } else {
            if (this.checkedKeys.checked.indexOf(node.id) !== -1) {
              this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(node.id), 1)
            }
          }
          // 下级节点也要处理
          if (node.children) {
            this.checkAllNode(node, checked)
          }
        })
      }
    },
    /***
     * 选中复选框时的事件
     */
    treeCheck(allKeys, echecked) {
      // echecked.checkedNodes 选中的所有节点信息为数组   .data.props 获取详细信息
      // echecked.node.dataRef  当前选中的节点信息
      if (this.single) {
        this.checkedKeys.checked = []
        this.checkedKeys.checked = [echecked.node.dataRef.id]
      }
      // 勾选复选框，则直接获取下级数据
      if (this.checkedKeys.checked.includes(echecked.node.dataRef.id)) {
        // 如果是事项，则不取下级
        if (echecked.node.dataRef.props.isItem) return
        this.$emit('checking', true)
        auditMattersTreeService
          .getAllNodeInfo(echecked.node.dataRef.id, this.frameId)
          .then((res) => {
            this.onCheckedLoadData(echecked.node, res.data.children)
          })
          .catch(() => {})
      }
      // 判断当前节点是否选中，选中的话，就把下级节点也一并选中，否则都去掉
      if (allKeys.checked.includes(echecked.node.dataRef.id)) {
        this.checkAllNode(echecked.node.dataRef, true)
      } else {
        this.checkAllNode(echecked.node.dataRef, false)
      }
      this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
    },
    // 点击树
    treeSelect(selectedKeys, info) {
      this.defaultSelectedKeys = selectedKeys
      if (this.single) {
        this.checkedKeys = []
        this.checkedKeys = [info.node.dataRef.id]
      } else {
        if (isChecked(this.checkedKeys.checked, info.node.dataRef.id)) {
          this.checkedKeys.checked.push(info.node.dataRef.id)
        } else {
          this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(info.node.dataRef.id), 1)
        }
        this.checkedKeys.checked = [...new Set(this.checkedKeys.checked)]
      }
      // 判断当前节点是否选中，选中的话，就把下级节点也一并选中，否则都去掉
      if (this.checkedKeys.checked.includes(info.node.dataRef.id)) {
        this.checkAllNode(info.node.dataRef, true)
      } else {
        this.checkAllNode(info.node.dataRef, false)
      }
      this.$emit('treeSelect', [...selectedKeys, ...this.checkedKeys.checked], info)
    },

    transformData(data) {
      return data.map((d) => {
        const { children, ...rest } = d
        return {
          ...rest,
          scopedSlots: { title: 'title' },
          children: children && this.transformData(children),
        }
      })
    },
    mmTree() {
      Object.assign(this.newtree, this.treeData)
      this.bindTree(this.newtree[0])
      this.getTree(this.newtree[0])
    },
    getTree(node) {
      const removeIndex = []
      node.id = (node.id + '').replace(/-item/g, '')
      node.children.forEach((item, index) => {
        if (item.hidden === true) {
          removeIndex.push(index)
        } else {
          if (item.children) {
            this.getTree(item)
          } else {
            item.id = (item.id + '').replace(/-item/g, '')
            item.children = []
          }
        }
      })
      if (node.children === null) {
        node.children = []
      } // 删除元素
      removeIndex.forEach((oneindex, index) => {
        node.children.splice(oneindex - index, 1)
      })
    },
    // 判断当前树需要展示的节点信息
    bindTree(nodeinfo) {
      const checklist = this.checkedKeys.checked
      nodeinfo.disabled = false
      if (nodeinfo.children) {
        this.bindTree(nodeinfo.children)
        const hiddenItem = nodeinfo.children.find((item, index) => {
          return item.hidden !== true
        })
        // 判断当前进节点是否隐藏
        if (!hiddenItem && checklist.indexOf(nodeinfo.id) === -1) {
          nodeinfo.hidden = true
        }
        // 如果显示但是没有在选择列表，则不可选中
        if (!nodeinfo.hidden && checklist.indexOf(nodeinfo.id) === -1) {
          nodeinfo.disabled = true
        }
      } else {
        nodeinfo.forEach((node, nodeindex) => {
          if (node.children) {
            // 判断子节点是否有选中的节点
            this.bindTree(node.children)
            const hiddenItem = node.children.find((item, index) => {
              return item.hidden !== true
            })
            // 判断当前进节点是否隐藏
            if (!hiddenItem && checklist.indexOf(node.id) === -1) {
              node.hidden = true
            }
            // 如果显示但是没有在选择列表，则不可选中
            if (!node.hidden && checklist.indexOf(node.id) === -1) {
              node.disabled = true
            }
          } else {
            if (checklist.indexOf(node.id) === -1) {
              node.hidden = true
            }
            // 如果显示但是没有在选择列表，则不可选中
            if (!node.hidden && checklist.indexOf(node.id) === -1) {
              node.disabled = true
            }
          }
        })
      }
    },

    onExpand(expandedKeys) {
      // 用户点击展开时，取消自动展开效果
      this.expandedKeys = expandedKeys
      this.autoExpandParent = false
    },

    // 点击地址树展开时调用
    onLoadData(treeNode) {
      const id = parseInt(treeNode.dataRef.id)
      if (!this.openId.includes(id)) {
        this.openId.push(id)
      }
      const orgId = this.depvalue
      return auditMattersTreeService
        .findIamAuditMattersTree(orgId, id, this.treeDataType)
        .then((res) => {
          if (res.data !== null) {
            // 没有打开过的节点，才进行赋值
            if (
              (treeNode.dataRef.children === null) |
              (treeNode.dataRef.children === undefined) |
              (treeNode.dataRef.children?.length === 0)
            ) {
              treeNode.dataRef.children = res.data
            }
          }
          // 如果根节点是选中状态，则展开式将下级节点也选中
          if (this.checkedKeys.checked.includes(id)) {
            res.data
              .map((item) => {
                if (item.props.isItem) return item.id + '-item'
                return item.id
              })
              .forEach((id) => {
                if (!this.checkedKeys.checked.includes(id)) {
                  this.checkedKeys.checked.push(id)
                }
              })
          }
          this.treeData = this.transformData([...this.treeData])
          this.setIsItem(this.treeData)
        })
    },
    // 点击地址树前复选框时候调用
    onCheckedLoadData(treeNode, children) {
      const id = parseInt(treeNode.dataRef.id)
      if (!this.openId.includes(id)) {
        this.openId.push(id)
      }
      if (children !== null) {
        treeNode.dataRef.children = [...children]
      }
      // 如果根节点是选中状态，则将下级节点也选中
      if (this.checkedKeys.checked.includes(id)) {
        this.transformCheckData(children)
        setTimeout(() => {
          this.$emit('checking', false)
        }, 1000)
      }
      this.treeData = this.transformData([...this.treeData])
      this.setIsItem(this.treeData)
    },
    transformCheckData(data) {
      data = data || []
      data.forEach((d) => {
        const checkid = this.checkedKeys.checked
        if (!checkid.includes(d.id)) {
          if (d.props.isItem) {
            this.checkedKeys.checked.push(d.id + '-item')
          } else {
            this.checkedKeys.checked.push(d.id)
          }
        }

        const { children } = d
        this.transformCheckData(children)
      })
    },
    // 初始化地址树
    initTreeData(depId) {
      const topDepId = depId === null ? 0 : depId
      auditMattersTreeService
        .findIamAuditMattersTree(topDepId, topDepId, this.treeDataType)
        .then((res) => {
          // this.mmInitTreeData(res)
          this.spinning = false
          const treeNode = [
            {
              id: this.defaultTopNodeId,
              text: this.defaultTopNodeText,
              isLeaf: false,
              props: {},
              children: [],
              key: this.defaultTopNodeId,
              disabled: this.isFrameCopy,
            },
          ]
          if (res.data.length) {
            treeNode.children = res.data
          }
          this.treeData = this.transformData(treeNode)
          this.setIsItem(this.treeData)
          this.expandedKeys = this.defaultTreeExpandedKeys
          this.empty = false
          this.$emit('checking', false)
        })
    },

    mmInitTreeData(res) {
      this.spinning = false
      if (res.data.length) {
        this.treeData = this.transformData(res.data)

        // this.expandedKeys = this.defaultTreeExpandedKeys
        this.expandedKeys = [res.data[0].id]
        this.empty = false
      } else {
        this.empty = true
      }
    },

    // 刷新树方法
    refreshTree() {
      this.key++
    },

    // 组织下拉框change时触发
    changedep(value, option) {
      this.key++
      this.defaultTreeExpandedKeys = [value]
      this.defaultSelectedKeys = [value]
      this.defaultTopNodeId = value
      this.defaultTopNodeText = option.data.props.text + this.topNodeText
      this.initTreeData(value)
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.depselect {
  width: 200px;
}
.spin {
  width: 100%;
  line-height: 30;
}
.ywlxtree {
  :global(.ant-tree-title) {
    display: inline-block;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  :global(.ant-input-search) {
    margin: 8px 0;
    overflow: hidden;
  }
  .active {
    color: $primary-color;
  }
  :global(.ant-select) {
    width: 100%;
    overflow: hidden;
  }
}
.treewrap {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 20%;
  min-height: 100%;
  margin-right: $padding-lg;
  transition: width 0.2s;
  .fold {
    position: absolute;
    top: calc(50% - 30px);
    right: -15px;
    z-index: 2;
    width: 15px;
    height: 75px;
    padding: 0;
    border-radius: 0 10px 10px 0;
  }
  :global(.ant-tree) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  :global(.ant-card-body) {
    background: $white;
  }
}
.collapse {
  width: 0;
  :global(.ant-card-body) {
    background: transparent;
    :global(.ant-empty) {
      display: none;
    }
  }
}
// 单选样式
.single {
  :global .ant-tree-checkbox {
    .ant-tree-checkbox-inner {
      border-radius: 100px;
      &::after {
        position: absolute;
        top: 3px;
        left: 3px;
        display: table;
        width: 8px;
        height: 8px;
        content: ' ';
        background-color: $primary-color;
        border: 0;
        border-radius: 8px;
        opacity: 0;
        transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
        transform: scale(0);
      }
    }
    &.ant-tree-checkbox-checked {
      &::after {
        position: absolute;
        top: 16.67%;
        left: 0;
        width: 100%;
        height: 66.67%;
        content: '';
        border: 1px solid #1890ff;
        border-radius: 50%;
        animation: antRadioEffect 0.36s ease-in-out;
        animation-fill-mode: both;
      }
      .ant-tree-checkbox-inner {
        background-color: $white;
        &::after {
          opacity: 1;
          transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
          transform: scale(1);
        }
      }
    }
  }
}
</style>
