<template>
  <a-card
    :class="[
      $style.treewrap,
      $style.ywlxtree,
      { [$style.collapse]: fold, [$style.single]: single },
    ]"
  >
    <!-- 选择部门 -->
    <!-- <a-select v-show="isSelectDep" v-model="depvalue" :options="depOptions" @change="changedep">
    </a-select> -->
    <a-form-model>
      <a-form-model-item :label="null" prop="orgValue">
        <AuditGroupPicker
          ref="unitNames"
          v-model="orgValue"
          :single="true"
          :read-only="false"
          :selectall="true"
          :top-node-text="'审计机构库'"
          :treeparams="{
            formId: 'IAM_ORG',
            idColumnId: 'id',
            nameColumnId: 'org_name',
            parentColumnId: 'parent_id',
            otherColumnId: ['org_id', 'creation_time'],
            configId: '11',
            type: 'SJ',
          }"
          @change="changedep"
        />
      </a-form-model-item>
    </a-form-model>
    <a-spin :spinning="spinning" :class="$style.spin" />
    <a-empty v-if="empty" />
    <a-tree
      v-else
      :key="key"
      ref="auditMaintainCatalogTree"
      v-model="checkedKeys"
      :block-node="false"
      :show-icon="true"
      :show-line="showLine"
      :check-strictly="true"
      :checkable="false"
      :draggable="draggable"
      :tree-data="treeData"
      :replace-fields="replaceFields"
      :selected-keys="defaultSelectedKeys"
      :expanded-keys="expandedKeys"
      :default-expanded-keys="defaultTreeExpandedKeys"
      :load-data="onLoadData"
      @select="treeSelect"
      @check="treeCheck"
      @expand="onExpand"
      @drop="onDrop"
    >
    </a-tree>
  </a-card>
</template>

<script>
import { Message } from 'ant-design-vue'
import { getUserInfo } from '@/common/store-mixin'
import AuditGroupPicker from '../../components/picker/audit-group-picker.vue'
import auditMaintainService from './audit-maintain-service'
import components from './_import-components/audit-maintain-catalog-tree-import'

export default {
  name: 'AuditMaintainCatalogTree',
  metaInfo: {
    title: 'AuditMaintainCatalogTree',
  },
  components: {
    ...components,
    AuditGroupPicker,
  },
  props: {
    // 默认选中节点
    selectedKeys: {
      type: Array,
      default: function() {
        return []
      },
    },
    // 查看模式 manager维护权限 read查看权限
    managerType: {
      type: String,
      default: 'manager',
    },
    // 是否显示复选框
    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,
    },
    /**
     * 是否展示部门下拉列表
     */
    isSelectDep: {
      type: Boolean,
      default: false,
    },
    cate: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      treeData: [],
      defaultTreeExpandedKeys: ['0'],
      defaultSelectedKeys: ['0'],
      checkedKeys: [], // 选中的节点数据
      dataList: [], // 数组dataList，搜索要用
      spinning: true,
      empty: false,
      icontype: 'left',
      fold: false,
      replaceFields: {
        title: 'text',
        key: 'id',
      },
      expandedKeys: ['0'],
      backupsExpandedKeys: [],
      autoExpandParent: false,
      defaultTopNodeText: '审计事项分类',
      defaultTopNodeId: '0',
      key: 0,
      newtree: [],
      depOptions: [], // 部门下拉框列表值
      edit: true, // 当前节点是否可编辑
      depvalue: '', // 选择的组织数据
      orgValue: '',
      orgId: null,
    }
  },
  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('iamModelCategory')
  },
  methods: {
    // 刷新树节点
    refreshNode(nodeId) {
      this.key++
      this.parentId = nodeId
      this.refreshData(this.treeData[0])
    },
    // 刷新树节点
    refreshData(treeData) {
      if (treeData.id + '' === this.parentId + '') {
        return auditMaintainService
          .findIamAuditMaintainCategoryTree(treeData.id, treeData.id)
          .then((res) => {
            treeData.children = res.data
            if (res.data.length > 0) {
              treeData.isLeaf = false
              if (this.expandedKeys.indexOf(treeData.id) === -1) {
                this.expandedKeys = new Set(this.expandedKeys.push(treeData.id))
              }
            } else {
              treeData.isLeaf = true
            }
            return false
          })
      }
      if (treeData.children) {
        treeData.children.forEach((item) => {
          this.refreshData(item)
        })
      }
    },
    // 初始化部门下拉 分级授权获取部门下拉列表  维护权限
    initDeptList(formId) {
      auditMaintainService.getManagedHierarchyOrg(formId).then((res) => {
        res.data.editNodes.forEach((item) => {
          this.depOptions.push({
            label: item.text,
            value: item.id,
            text: item.text,
            edit: true,
          })
        })
        if (this.managerType !== 'manager') {
          // 取编辑和查看节点并集
          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 = 'o_' + this.depOptions[0].value
          this.defaultTopNodeText = this.depOptions[0].text + this.topNodeText
          this.defaultTreeExpandedKeys = ['o_' + this.depOptions[0].value]
          this.defaultSelectedKeys = ['o_' + this.depOptions[0].value]
          this.edit = this.depOptions[0].edit
          this.initTreeData(this.depOptions[0].value)
          this.$emit('depChanged', this.depOptions[0].value, this.depOptions[0])
          this.$emit('treeSelect', [this.depOptions[0].value], {
            selectedNodes: [
              {
                data: {
                  props: {
                    id: this.depOptions[0].value,
                    text: this.depOptions[0].text + this.topNodeText,
                    edit: this.depOptions[0].edit,
                  },
                },
              },
            ],
            node: {
              dataRef: {
                props: {
                  isroot: true,
                },
              },
            },
          })
        } else {
          this.defaultTopNodeId = null
          this.defaultTopNodeText = null
          this.defaultTreeExpandedKeys = []
          this.defaultSelectedKeys = []
          this.$emit('treeSelect', [9999999], {
            selectedNodes: [],
          })
          this.spinning = false
          this.empty = true
        }
      })
    },
    /***
     * 选中复选框时的事件
     */
    treeCheck(allKeys, echecked) {
      // echecked.checkedNodes 选中的所有节点信息为数组   .data.props 获取详细信息
      // echecked.node.dataRef  当前选中的节点信息
      if (this.single) {
        this.checkedKeys.checked = []
        this.checkedKeys.checked = [echecked.node.dataRef.id]
      }
      this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
    },
    // 点击树
    treeSelect(selectedKeys, info) {
      this.defaultSelectedKeys = selectedKeys
      this.$emit('treeSelect', selectedKeys, info)
    },
    transformData(data) {
      return data.map((d) => {
        const { children, ...rest } = d
        return {
          ...rest,
          children: children && this.transformData(children),
          scopedSlots: { title: 'title' },
        }
      })
    },

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

    // 点击地址树展开时调用
    onLoadData(treeNode) {
      let parentId
      if (treeNode.dataRef.props.isroot) {
        parentId = -1
      } else {
        parentId = parseInt(treeNode.dataRef.id)
      }
      return auditMaintainService
        .findIamAuditMaintainCategoryTree(parentId, this.depvalue)
        .then((res) => {
          treeNode.dataRef.children = res.data
          //  this.setDisabless(res.data)
          this.treeData = this.transformData([...this.treeData])
        })
    },
    // 添加是否可点击属性
    setDisabless(data) {
      return data.map((d) => {
        const props = d.props
        if (props && props.isEnd === '1') {
          //  置灰不可选
          d.disabled = true
        }
      })
    },

    // 初始化地址树
    initTreeData(depId) {
      const topDepId = depId === null || depId === undefined ? 0 : depId
      auditMaintainService.findIamAuditMaintainCategoryTree(topDepId, topDepId).then((res) => {
        // if (res.data) {
        //   this.defaultSelectedKeys = [res.data[0].id]
        // }

        // this.mmInitTreeData(res)
        this.spinning = false
        const treeNode = [
          {
            id: this.defaultTopNodeId,
            text: this.defaultTopNodeText,
            isLeaf: false,
            props: {
              isroot: true,
            },
            children: [],
            key: this.defaultTopNodeId,
          },
        ]
        if (res.data.length) {
          treeNode.children = res.data
        }
        this.treeData = this.transformData(treeNode)
        this.expandedKeys = this.defaultTreeExpandedKeys
        this.generateList(this.treeData)
        this.empty = false
      })
    },
    // 处理搜索用的dataList
    generateList(data) {
      for (let i = 0; i < data.length; i++) {
        const node = data[i]
        const key = node.id
        const title = node.text
        const props = node.props
        // 用来判断此几点是否已经配置了用户，需要后台返回标识位进行判断
        if (props.showuser) {
          data[i].scopedSlots.icon = 'hasuser'
        }
        this.dataList.push({ key, id: key, title: title, props })
        if (node.children) {
          this.generateList(node.children)
        }
      }
    },
    mmInitTreeData(res) {
      this.spinning = false
      if (res.data.length) {
        this.treeData = this.transformData(res.data)

        this.expandedKeys = this.defaultTreeExpandedKeys
        this.empty = false
      } else {
        this.empty = true
      }
    },

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

    // 组织下拉框change时触发
    changedep(value) {
      this.key++
      if (value.length === 0) {
        this.depvalue = 0
        this.defaultTreeExpandedKeys = ['0']
        this.defaultSelectedKeys = ['0']
        this.defaultTopNodeId = '0'
        this.defaultTopNodeText = this.topNodeText
      } else {
        this.depvalue = value[0].oldId
        this.defaultTreeExpandedKeys = ['o_' + value[0].oldId]
        this.defaultSelectedKeys = ['o_' + value[0].oldId]
        this.defaultTopNodeId = 'o_' + value[0].oldId
        this.defaultTopNodeText = value[0].text + this.topNodeText
        this.edit = true
      }
      this.initTreeData(this.depvalue)
      this.$emit('depChanged', this.depvalue, value[0])
      this.$emit(
        'treeSelect',
        { id: value[0].oldId },
        {
          selectedNodes: [
            {
              data: {
                props: {
                  id: this.defaultTopNodeId,
                  text: value[0].text + this.topNodeText,
                  edit: true,
                },
              },
            },
          ],
          node: {
            dataRef: {
              props: {
                isroot: true,
              },
            },
          },
        }
      )
    },

    // 拖拽节点方法
    onDrop(info) {
      // 被插入节点信息
      const dropKey = info.node.eventKey
      const dropNode = info.node.dataRef
      // 拖拽节点信息
      const dragKey = info.dragNode.eventKey
      const dragNode = info.dragNode.dataRef

      const dropPos = info.node.pos.split('-')
      // -1表示之前 0表示合并 1表示之后
      const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
      // 分类合并至事项内
      if (dropNode.props.isroot && (dropPosition === 1) | (dropPosition === -1)) {
        Message.info('不能将分类拖拽至与根节点同层级', 1)
        return false
      }

      const loop = (data, key, callback) => {
        data.forEach((item, index, arr) => {
          if (item.id === key) {
            return callback(item, index, arr)
          }
          if (item.children) {
            return loop(item.children, key, callback)
          }
        })
      }
      const data = this.treeData

      // Find dragObject
      let dragObj
      loop(data, dragKey, (item, index, arr) => {
        arr.splice(index, 1)
        dragObj = item
      })
      if (!info.dropToGap) {
        // Drop on the content
        loop(data, dropKey, (item) => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.push(dragObj)
        })
      } else if (
        (info.node.children || []).length > 0 && // Has children
        info.node.expanded && // Is expanded
        dropPosition === 1 // On the bottom gap
      ) {
        loop(data, dropKey, (item) => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.unshift(dragObj)
        })
      } else {
        let ar
        let i
        loop(data, dropKey, (item, index, arr) => {
          ar = arr
          i = index
        })
        if (dropPosition === -1) {
          ar.splice(i, 0, dragObj)
        } else {
          ar.splice(i + 1, 0, dragObj)
        }
      }
      this.treeData = data

      // 拖拽完成，调用接口
      const dragParams = {
        nodeId: dragNode.id,
        targetnodeType: dropNode.props.isroot ? 'root' : 'category', // category/root
        targetnodeId: dropNode.id,
        position: dropPosition, // -1 0 1  之前 合并 之后
      }

      auditMaintainService.dragNode(dragParams).then((res) => {
        if (!res) {
          Message.info(dropNode.text + '节点下存在相同分类编号，拖拽失败')
        }
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.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>
