<template>
  <div>
    <el-tree ref="treeRef" :data="routeData" node-key="name" :props="defaultProps" show-checkbox default-expand-all :filter-node-method="filterNode" :expand-on-click-node="false" :default-checked-keys="checkedName" highlight-current @check-change="handleCheckChange" />
  </div>
</template>

<script setup>
const props = defineProps({
  modelValue: String,
  extraName: String
})
const emits = defineEmits(['update:modelValue']);

const treeRef = ref(null);
const defaultProps = {
  children: "children",
  label: "label"
};

const checkedName = $ref([]);
watch(
  () => props.modelValue,
  (val) => {
    if (val) {
      if (checkedName.length == 0) {
        checkedName = val.split(",");
      }
    } else {
      checkedName = [];
    }
  }
);

watch(
  () => props.extraName,
  (val) => {
    initTreeItem(val);
  }
);

const modules = import.meta.glob("~/router/routes/manage/*.ts", {
  eager: true,
});
const constantRoutes = [];
const asyncRoutes = [];
Object.keys(modules).forEach((path) => {
  const arr = path.split("/");
  const filename = arr[arr.length - 1];
  if (filename?.startsWith("_")) constantRoutes.push(modules[path].default);
  else asyncRoutes.push(modules[path].default);
});
const asyncFilteredRoutes = [...asyncRoutes];
const allRoutes = computed(() => {
  const routes = asyncFilteredRoutes;
  return routes.sort((a, b) => a.meta.sort - b.meta.sort);
});

const routeData = ref([]);
// 权限
function initTree() {
  routeData.value = [];
  allRoutes.value.map((val) => {
    const obj = handleItem(val);
    routeData.value.push(obj);
  });
}
initTree();

function handleItem(item) {
  const returnObj = {
    label: item.meta.title,
    name: item.name,
  };
  if (Array.isArray(item.children)) {
    const arr = [];
    const child = [];
    init(item.children, arr, child);
    if (arr.length > 0)
      returnObj.children = arr;
    if (child.length > 0)
      returnObj.child = child;
  }
  return returnObj;
}

function init(arg, arr, child) {
  arg.map((val) => {
    const obj = handleItem(val);
    if (!val.meta.hidden) {
      arr.push(obj);
    } else {
      child.push(obj);
    }
    if (val.children) {
      init(val.children, arr, child);
    }
  });
}

function initTreeItem(val, init) {
  if (val) {
    let arr = val.split(",");
    treeRef.value?.filter(arr);
  } else if (!init) {
    initTree();
  }
}

const handleCheckChange = async (data, checked) => {
  if (!data.children) {
    initCheck(data, checked);
  }

  let nameStr = checkedName.join();
  emits("update:modelValue", nameStr);
};

const initCheck = (data, checked) => {
  if (data.children) {
    data.children.map(item => {
      initCheck(item);
    })
  } else {
    let index = checkedName.indexOf(data.name);
    if (checked && index == -1)
      checkedName.push(data.name);
    else if (!checked && index != -1)
      checkedName.splice(index, 1);

    if (data.child) {
      data.child.map(item => {
        let index1 = checkedName.indexOf(item.name);
        if (checked && index1 == -1)
          checkedName.push(item.name);
        else if (!checked && index1 != -1)
          checkedName.splice(index1, 1);
      })
    }
  }
}

const filterNode = (value, data) => {
  if (!value) return true
  return !value.includes(data.name)
}

onMounted(() => {
  initTreeItem(props.extraName, true);
})
</script>

<style>
</style>