<template>
  <a-card :class="$style.treewrap">
    <div :class="$style['model-table-button']">
      <a-space>
        <a-button type="primary" @click="addDoc">添加</a-button>
        <a-button @click="deleteDoc">删除</a-button>
      </a-space>
    </div>

    <a-spin v-if="spinning" :spinning="spinning" :class="$style.spin" />

    <template v-else>
      <a-tree
        v-if="treeData.length > 0"
        :key="updateKey"
        v-model="checkedKeys"
        checkable
        :block-node="true"
        :tree-data="treeData"
        :default-expanded-keys="defaultExpandedKeys"
        :load-data="onLoadTreeData"
      >
      </a-tree>
      <a-empty v-else />
    </template>

    <a-modal
      v-model="visible"
      :title="'设置[' + depInfo.name + ']菜单个性化'"
      destroy-on-close
      v-bind="{ width: 800 }"
      :mask-closable="false"
      :confirm-loading="confirmLoading"
    >
      <div slot="footer" :class="$style.footer">
        <a-checkbox v-model="includeAuth">
          包括已下放的角色权限
        </a-checkbox>
        <div>
          <a-button
            @click="
              () => {
                visible = false
                $emit('closed')
              }
            "
            >取消</a-button
          >
          <a-button type="primary" @click="save">确定</a-button>
        </div>
      </div>
      <a-spin v-if="spinningAdd" :spinning="spinningAdd" :class="$style.spin" />
      <a-tree
        :key="updateKey"
        v-model="checkedKeysAdd"
        checkable
        :block-node="true"
        :tree-data="treeDataAdd"
        :default-expanded-keys="defaultExpandedKeysAdd"
        :load-data="onLoadTreeDataAdd"
        @check="check"
      >
      </a-tree>
    </a-modal>
  </a-card>
</template>

<script>
import { message, Modal } from 'ant-design-vue'
import OrgService from './org-service'
import components from './_import-components/sd-org-hiera-menu-import'

export default {
  name: 'SdOrgHieraMenu',
  metaInfo: {
    title: 'SdOrgHieraMenu',
  },
  components,
  inject: ['depInfo'],
  props: {
    unid: {
      type: String,
      default: function() {
        return null
      },
    },
  },

  data() {
    return {
      confirmLoading: false,
      spinning: true,
      treeData: [],
      defaultExpandedKeys: [],
      updateKey: 1,
      checkedKeys: [],

      visible: false,
      spinningAdd: true,
      treeDataAdd: [],
      checkedKeysAdd: [],
      defaultExpandedKeysAdd: [],
      halfCheckedKeysAdd: [],

      srcTreeDataAdd: [],
      includeAuth: false,
    }
  },

  methods: {
    init() {
      this.visible = false
      this.checkedKeys = []
      this.onLoadTreeData().then(() => {
        this.updateKey++
      })
    },
    addDoc() {
      this.visible = true
      this.checkedKeysAdd = []
      this.onLoadTreeDataAdd().then(() => {
        this.updateKey++
      })
    },
    check(keys, evt) {
      // console.log(evt.node)
      this.halfCheckedKeysAdd = evt.halfCheckedKeys
    },
    deleteDoc() {
      if (this.checkedKeys.length === 0) {
        message.error('请选择待删除菜单')
        return
      }
      Modal.confirm({
        title: '你确定删除这项内容吗？',
        content: '删除这条数据后，就无法恢复初始的状态。',
        okText: '删除',
        okType: 'danger',
        onOk: () => {
          this.spinning = true
          OrgService.deleteHieraMenu({ ids: this.checkedKeys.join(',') })
            .then((res) => {
              if (res.status === 200) {
                if (res.data.length === 0) {
                  message.success('删除成功')
                  this.init()
                } else {
                  message.error(res.data.join(''))
                }
              } else {
                message.error(res.data?.message || '删除失败')
              }
            })
            .catch((res) => {
              message.error(res?.response?.data?.message || '删除失败')
            })
            .finally(() => {
              this.spinning = false
            })
        },
      })
    },
    save() {
      if (this.checkedKeysAdd.length === 0) {
        message.error('请选择要授权的个性化菜单！')
        return
      }
      const keys = this.halfCheckedKeysAdd.concat(this.checkedKeysAdd)
      const addTree = this.filterTreeNode(this.srcTreeDataAdd[0].children, keys)
      this.spinningAdd = true

      this.confirmLoading = true
      return new Promise((resolve) => {
        OrgService.addOrgHieraMenu({
          groupId: parseInt(this.unid, 10),
          treeNodes: addTree,
          includeAuth: this.includeAuth,
        })
          .then((res) => {
            if (res.status === 200) {
              message.success('添加成功')
              this.init()
            } else {
              message.error(res.data?.message || '添加失败')
            }
          })
          .catch(() => message.error('添加失败'))
          .finally(() => {
            this.spinningAdd = false
            this.confirmLoading = false
            resolve()
          })
      })
    },
    filterTreeNode(nodes, keys) {
      return nodes.filter((item) => {
        const index = keys.indexOf(item.id)

        if (index !== -1) {
          if (item.children && item.children.length > 0) {
            keys.splice(index, 1)
            item.children = this.filterTreeNode(item.children, keys)
          }
        }

        return index !== -1
      })
    },
    onLoadTreeData(treeNode) {
      return new Promise((resolve) => {
        if (treeNode) {
          if (treeNode.dataRef.children) {
            resolve()
            return
          }
          OrgService.getOrgHieraMenuTree({ id: treeNode.dataRef.key }).then((deps) => {
            treeNode.dataRef.children = this.parseTreeData(deps.data)
            this.treeData = [...this.treeData]
            this.spinning = false
            resolve()
          })
        } else {
          OrgService.getOrgHieraMenuRoot({ id: this.unid }).then((deps) => {
            this.treeData = this.parseTreeData(deps.data).map((item) => {
              return { ...item, checkable: false }
            })

            // 默认展开第二层的节点
            OrgService.getOrgHieraMenuTree({ id: this.treeData[0].key }).then((deps) => {
              this.treeData[0].children = this.parseTreeData(deps.data)
              this.treeData = [...this.treeData]

              this.defaultExpandedKeys = [this.treeData[0].key].concat(
                this.treeData[0].children.map((item) => {
                  return item.key
                })
              )
              this.spinning = false
              resolve()
            })
          })
        }
      })
    },
    onLoadTreeDataAdd(treeNode) {
      return new Promise((resolve) => {
        if (treeNode) {
          if (treeNode) {
            resolve()
          }
        } else {
          OrgService.getOrgHieraMenu({ id: this.unid }).then((deps) => {
            // 设置部门节点key，避免id和导航菜单id重复
            deps.data[0].key = 'dep_' + deps.data[0].id
            this.srcTreeDataAdd = deps.data
            this.treeDataAdd = this.parseTreeDataAdd(deps.data)
            this.treeDataAdd[0].checkable = false
            this.defaultExpandedKeysAdd = [this.treeDataAdd[0].key].concat(
              this.treeDataAdd[0].children.map((item) => {
                return item.key
              })
            )

            this.spinningAdd = false
            resolve()
          })
        }
      })
    },
    parseTreeDataAdd(deps) {
      if (deps) {
        return deps.map((dep) => {
          return {
            key: dep.key || dep.id,
            title: dep.text,
            isLeaf: dep.leaf,
            children: this.parseTreeDataAdd(dep.children),
          }
        })
      } else {
        return []
      }
    },
    parseTreeData(deps) {
      return deps.map((dep) => {
        return {
          key: dep.id,
          title: dep?.props?.hierarchical === 'true' ? dep.text + '(已开启分级)' : dep.text,
          name: dep.text,
          isLeaf: dep.leaf,

          scopedSlots: {
            title: 'title',
          },
        }
      })
    },
    refresh() {
      this.init()
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;

.spin {
  position: absolute;
  width: 100%;
  line-height: 10;
}
.treewrap {
  height: 100%;
  :global(.ant-input-search) {
    overflow: hidden;
  }
  :global(.ant-tree) {
    // height: calc(100% - 2 * #{$padding-md});
    height: 100%;
    overflow: auto;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  :global(.ant-card-body) {
    height: 100%;
    background: $white;
  }
  .active {
    color: $primary-color;
  }
}
.footer {
  display: flex;
  justify-content: space-between;
}
</style>
