<template>
  <el-card style="width: 100%">
    <template #header>
      <section class="title">{{ title }}</section>
      <section>
        <el-checkbox label="全部展开 / 全部收起" @change="expandAll"  />
        <el-checkbox label="全选 / 全不选" @change="checkAll" />
      </section>
    </template>

    <el-tree
      ref="treeInstance"
      :data="treeData" 
      node-key="value" 
      show-checkbox
      :expand-on-click-node="false"
      @check="onNodeCheck"
    />
  </el-card>
</template>

<script setup lang="ts">
  import { ref, shallowRef } from 'vue';
  import { ElTree } from 'element-plus';
  import { PermissionViewTree, PermissionTreeKey } from '@/types/permission/type';

  defineProps<{
    title: string;
    treeData: PermissionViewTree;
  }>();
  
  const treeInstance = ref<InstanceType<typeof ElTree>>();
  const leafCheckedKeys = shallowRef<PermissionTreeKey[]>([]);

  /**
   * 当check树节点时，获取其下的所有leaf节点的值
   */
  const onNodeCheck = () => {
    leafCheckedKeys.value = treeInstance.value?.getCheckedKeys(true)!;
  };

  /**
   * 全部展开 / 全部收起
   * @param expanded 
   */
  const expandAll = (expanded: boolean) => {
    treeInstance.value?.store._getAllNodes().forEach(node => node.expanded = expanded);
  };

  
  /**
   * 全选 / 全不选
   * @param checked 
   */
  const checkAll = (checked: boolean) => {
    leafCheckedKeys.value = checked ? getAllLeafKeys() : [];
    treeInstance.value?.setCheckedKeys(leafCheckedKeys.value);
  };

  /**
   * 获取所有叶子节点的 node-key
   */
  const getAllLeafKeys = () => {
    return treeInstance.value?.store._getAllNodes()
      .filter(node => node.isLeaf)
      .map(node => node.data.value) as PermissionTreeKey[];
  };

  /**
   * 编辑角色时，勾选已分配的权限
   */
  const setAssignedPermissions = (keys: PermissionTreeKey[]) => {
    treeInstance.value?.setCheckedKeys(keys, true);
    leafCheckedKeys.value = keys;
  };

  
  /**
   * 返回选择的权限值.
   * 权限值可能是 相机ID、菜单ID、或 权限ID
   */
  const getSelectedPermissions = (): PermissionTreeKey[] => {
    return [ ...leafCheckedKeys.value ];
  };


  /**
   * 重置
   */
  const reset = () => {
    checkAll(false);
  }

  defineExpose({ getSelectedPermissions, reset, setAssignedPermissions });
</script>

<style scoped>
  .el-card + .el-card {
    margin-top: 10px;
  }

  :deep(.el-card__header) {
    padding: 10px;
  }

  .title:before {
    content: '';
    margin-right: 10px;
    border-left: 3px solid #1890ff;
  }
</style>