<template>
  <span>
    <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
            ref="auditMattersTree"
            v-model="checkedKeys"
            :show-icon="true"
            :show-line="true"
            :check-strictly="true"
            :expanded-keys="expandedKeys"
            :default-expanded-keys="defaultTreeExpandedKeys"
            :checkable="checkable"
            :tree-data="treeData"
            :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 cloneDeep from 'lodash.clonedeep'
import { getUserInfo } from '@/common/store-mixin'
import icTreeService from '../ic-tree-service'
import components from './_import-components/iam-item-tree-import'
// 判断是否已经选择
function isChecked(selectedKeys, eventKey) {
  return selectedKeys.indexOf(eventKey) === -1
}
export default {
  name: 'IamItemTree',
  metaInfo: {
    title: 'IamItemTree',
  },
  components,
  props: {
    /**
     * <p>获取数据的回调，获取根节点时，parentId为undefined</p>
     * <pre>(parentId,parent) => childrenItems</pre>
     */
    loadTreeData: {
      type: Function,
      required: true,
    },
    // 默认选中节点
    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: undefined,
    },
    // 是否显示隐藏按钮
    showPrimary: {
      type: Boolean,
      default: true,
    },
    // 地址树是否单选
    single: {
      type: Boolean,
      default: false,
    },
    refreshKey: {
      type: Number,
      default: 0,
    },
    treeDataType: {
      type: String,
      default: '',
    },
    types: {
      type: String,
      default: 'NK',
    },
    versionId: {
      type: String,
      default: '',
    },
    orgId: {
      type: String,
      default: '',
    },
    orgName: {
      type: String,
      default: '',
    },
    selecttype: {
      type: String,
      default: 'control',
    },
    optionValue: {
      type: String,
      default: 'id',
    },
    /**
     * @ignore
     */
    optionLabel: {
      type: String,
      default: 'name',
    },
    isAbandonment: {
      type: String,
      default: 'NO',
    },
  },
  data() {
    return {
      defaultTopNodeId: -1,
      treeData: [],
      checkedKeys: {
        checked: [],
        halfChecked: [],
      }, // 选中的节点数据
      dataList: [], // 数组dataList，搜索要用
      spinning: true,
      empty: false,
      icontype: 'left',
      fold: false,
      // replaceFields: {
      //   title: 'text',
      //   key: 'code',
      // },
      openId: [], // 已经打开过的id
      defaultTreeExpandedKeys: ['-1'],
      expandedKeys: ['-1'],
      defaultTopNodeText: '根节点',
      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() {
    this.initTreeData()
  },
  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
    },
    // 选中当前节点下的所有节点
    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  当前选中的节点信息
      const params = {
        auditOrgId: parseInt(this.orgId),
        versionId: parseInt(this.versionId),
        isAbandonment: this.isAbandonment,
      }
      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.isEnd === '1') return
        this.$emit('checking', true)
        if (this.selecttype === 'cross') {
          icTreeService
            .getCategoryTree(echecked.node.dataRef.id, params, this.types)
            .then((res) => {
              res.data.forEach((item) => {
                item.title = item.text
                item.code = item.id.toString()
                if (item.props.isEnd === '0') {
                  item.isLeaf = false
                  item.cat = true
                } else {
                  item.cat = false
                  this.isendids.push(item.id.toString())
                }
              })
              this.onCheckedLoadData(echecked.node, res.data)
            })
        } else {
          icTreeService.getMeasureTree(echecked.node.dataRef.id, params, this.types).then((res) => {
            res.data.forEach((item) => {
              item.title = item.text
              item.code = item.id.toString()
              if (item.props.disabled) {
                item.isLeaf = false
                item.cat = true
              } else {
                item.cat = false
              }
            })
            this.onCheckedLoadData(echecked.node, res.data)
          })
        }
      }
      // 判断当前节点是否选中，选中的话，就把下级节点也一并选中，否则都去掉
      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, checkable, selectable, isLeaf, ...rest } = d
        return {
          ...rest,
          checkable: checkable ?? true,
          selectable: selectable ?? false,
          isLeaf: isLeaf ?? true,
          key: d[this.optionValue],
          children: children && this.transformData(children),
          originalValue: rest,
          code: rest.code,
        }
      })
    },

    // 点击地址树展开时调用
    onLoadData(treeNode) {
      const params = {
        auditOrgId: parseInt(this.orgId),
        versionId: parseInt(this.versionId),
        isAbandonment: this.isAbandonment,
      }
      if (this.selecttype === 'cross') {
        if (treeNode.dataRef.children !== null && treeNode.dataRef.children.length > 0) {
          console.log('有子节点，不请求')
          return new Promise((resolve) => {
            resolve()
          })
        } else {
          return icTreeService
            .getCategoryTree(treeNode.dataRef.id, params, this.types)
            .then((res) => {
              res.data.forEach((item) => {
                item.title = item.text
                item.code = item.id.toString()
                if (item.props.isEnd === '0') {
                  item.isLeaf = false
                  item.cat = true
                } else {
                  item.cat = false
                  this.isendids.push(item.id.toString())
                }
              })
              treeNode.dataRef.children = this.transformData(res.data)
              this.treeData = [...this.treeData]
            })
        }
      } else {
        if (treeNode.dataRef.children !== null && treeNode.dataRef.children.length > 0) {
          console.log('有子节点，不请求')
          return new Promise((resolve) => {
            resolve()
          })
        } else {
          return icTreeService
            .getMeasureTree(treeNode.dataRef.id, params, this.types)
            .then((res) => {
              res.data.forEach((item) => {
                item.title = item.text
                item.code = item.id.toString()
                if (item.props.disabled) {
                  item.isLeaf = false
                  item.cat = true
                } else {
                  item.cat = false
                }
              })
              treeNode.dataRef.children = this.transformData(res.data)
              this.treeData = [...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])
    },
    transformCheckData(data) {
      data = data || []
      data.forEach((d) => {
        const checkid = this.checkedKeys.checked
        if (!checkid.includes(d.id + '')) {
          this.checkedKeys.checked.push(d.id + '')
        }

        const { children } = d
        this.transformCheckData(children)
      })
    },
    initTreeData(depId) {
      const params = {
        auditOrgId: parseInt(this.orgId),
        versionId: parseInt(this.versionId),
      }
      this.defaultTopNodeText = this.orgName
      icTreeService.getCategoryTree(this.defaultTopNodeId, params, this.types).then((res1) => {
        this.spinning = false
        res1.data.forEach((item) => {
          item.title = item.text
          item.code = item.id.toString()
          item.key = item.id.toString()
          item.cat = true
          item.isLeaf = false
        })
        const treeNode = [
          {
            id: this.defaultTopNodeId,
            text: this.defaultTopNodeText,
            code: this.defaultTopNodeId.toString(),
            isLeaf: false,
            props: {
              isroot: true,
            },
            title: this.defaultTopNodeText,
            children: res1.data,
            cat: true,
          },
        ]
        if (this.selecttype === 'cross') {
          treeNode.forEach((i) => {
            if (i.children) {
              i.children.forEach((c) => {
                if (c.props.isEnd === '0') {
                  c.isLeaf = false
                  c.cat = true
                } else {
                  c.cat = false
                  this.isendids.push(c.id.toString())
                }
              })
            }
          })
        }
        this.treeData = this.transformData(treeNode)
        this.expandedKeys = this.defaultTreeExpandedKeys
        this.$emit('checking', false)
        this.dataLoaded = true
      })
    },
    // 刷新树方法
    refreshTree() {
      this.key++
    },
    onExpand(expandedKeys) {
      // 用户点击展开时，取消自动展开效果
      this.expandedKeys = expandedKeys
      this.autoExpandParent = false
    },
  },
}
</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>
