<script setup lang="ts">
import { onMounted, ref, defineEmits, watch, nextTick } from "vue";
import { getSystemRoleDeptTree } from "@/api/system/role";
import { type CheckboxValueType } from "element-plus";

onMounted(() => {
  getDeptList();
  console.log(model.value);
});

const emit = defineEmits(["update:modelValue"]);

const deptList = ref([]);
const getDeptList = async () => {
  let res = await getSystemRoleDeptTree("2");
  deptList.value = res.depts;
};

const model = defineModel();

watch(
  model,
  (value: number[]) => {
    nextTick(() => {
      setCheckedKeys(value, true);
      const allKeys = getAllKeys(deptList.value);
      menuNodeAll.value = value.length === allKeys.length;
      isIndeterminate.value = value.length > 0 && value.length < allKeys.length;
    });
  },
  { immediate: true, deep: true }
);

const menuRef = ref(null);

const menuCheckStrictly = ref(true);
const menuNodeAll = ref(false);
const menuExpand = ref(false);
const isIndeterminate = ref(false);
const handleCheckedTreeExpand = (value: CheckboxValueType) => {
  // 递归展开
  for (let i = 0; i < deptList.value.length; i++) {
    menuRef.value.store.nodesMap[deptList.value[i].id].expanded = value;
  }
};

const handleCheckedTreeNodeAll = (value: CheckboxValueType) => {
  menuRef.value.setCheckedNodes(value ? deptList.value : []);
  isIndeterminate.value = false;
  const allKeys = getAllKeys(deptList.value);
  model.value = value ? allKeys : [];
  console.log(model.value);
  console.log(menuNodeAll.value);
};

const handleTreeCheck = (_: any, checkedState: any) => {
  const allKeys = getAllKeys(deptList.value);
  const checkedCount = checkedState.checkedKeys.length;
  menuNodeAll.value = checkedCount === allKeys.length;
  isIndeterminate.value = checkedCount > 0 && checkedCount < allKeys.length;
  model.value = checkedState.checkedKeys;
  emit("update:modelValue", checkedState.checkedKeys);
};

// 递归获取所有节点key
const getAllKeys = (data: any) => {
  return data.reduce((keys: any, node: any) => {
    keys.push(node.id);
    if (node.children && menuCheckStrictly) {
      keys.push(...getAllKeys(node.children));
    }
    return keys;
  }, []);
};

const setCheckedKeys = (keys: number[], leafOnly: boolean) => {
  return menuRef.value.setCheckedKeys(keys, leafOnly);
};
</script>

<template>
  <div style="width: 100%">
    <el-row type="flex" justify="space-between" align="middle">
      <el-col :span="4">
        <el-checkbox
          v-model="menuExpand"
          @change="handleCheckedTreeExpand($event)"
          >全部展开/折叠
        </el-checkbox>
      </el-col>
      <el-col :span="4">
        <el-checkbox
          v-model="menuNodeAll"
          :indeterminate="isIndeterminate"
          @change="handleCheckedTreeNodeAll($event)"
          >全选/全不选
        </el-checkbox>
      </el-col>
      <el-col :span="4">
        <el-checkbox v-model="menuCheckStrictly">级联下级 </el-checkbox>
      </el-col>
    </el-row>
    <el-tree
      ref="menuRef"
      class="tree-border"
      :data="deptList"
      show-checkbox
      node-key="id"
      empty-text="加载中，请稍后"
      :check-strictly="!menuCheckStrictly"
      @check="handleTreeCheck"
    />
  </div>
</template>

<style scoped lang="scss">
/* tree border */
.tree-border {
  width: 100%;
  margin-top: 5px;
  border: 1px solid #e5e6e7;
  background: #ffffff none;
  border-radius: 4px;
}
</style>
