<script lang="ts" setup>
import { get } from "@/common/http/request";
import type { TreeInstance } from "element-plus";

const props = defineProps({
  title: String,
  data: Array,
  url: String,
  param: URLSearchParams,
  selectUrl: String,
  showCheckbox: { default: false },
});
const treeCheck = defineModel<number[]>();
const treeSelect = defineModel("current-node");
const treeData = ref();
const treeRef = ref<TreeInstance>();

const loadData = async () => {
  if (props.url !== undefined) {
    const rawUrlData = await get(props.url, props.param).then(res => res.data);
    treeData.value = rawUrlData;
  }
  if (props.data !== undefined && treeData.value === undefined) {
    treeData.value = props.data;
  }
  // 树数据加载完成后，如果有选中的值，使用 setCheckedKeys 设置选中状态
  // 因为 default-checked-keys 只在组件初始化时生效
  nextTick(() => {
    if (treeRef.value && treeCheck.value !== undefined && treeCheck.value.length > 0) {
      treeRef.value.setCheckedKeys(treeCheck.value);
    }
  });
};

const clearSelect = () => {
  treeRef.value?.setCheckedKeys([]);
};

const defaultProps = {
  children: "children",
  label: "label",
};

const checkHandle = (checkedNode: any, treeStatus: any) => {
  // 将字符串类型的 id 转换为数字类型
  treeCheck.value = treeStatus.checkedKeys.map((id: string | number) => (typeof id === "string" ? Number(id) : id));
};

const clickHandle = (clickNode: any, nodeAttr: any, treeNode: any, event: any) => {
  treeSelect.value = clickNode;
};

const initSelect = (newV: number[]) => {
  if (treeRef.value && newV !== undefined && newV.length > 0) {
    treeRef.value.setCheckedKeys(newV);
  }
};

watch(treeCheck, (newV: number[] | undefined) => {
  if (newV === undefined || newV.length === 0) return;
  initSelect(newV);
});

onMounted(loadData);

defineExpose({
  clear: clearSelect,
});
</script>
<template>
  <div>
    <p v-if="title !== undefined">{{ title }}</p>
    <el-tree
      ref="treeRef"
      :props="defaultProps"
      :data="treeData"
      node-key="id"
      default-expand-all
      highlight-current
      :show-checkbox="showCheckbox"
      :default-checked-keys="treeCheck"
      check-strictly
      @check="checkHandle"
      @node-click="clickHandle"
    />
  </div>
</template>

<style scoped>
:deep(.el-tree) {
  font-size: 14px;
}

:deep(.el-tree-node__content) {
  height: 32px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

:deep(.el-tree-node__content:hover) {
  background-color: var(--el-fill-color-light);
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  color: var(--el-color-primary);
  background-color: var(--el-color-primary-light-9);
}

:deep(.el-tree-node__expand-icon) {
  color: var(--el-text-color-secondary);
}

:deep(.el-tree-node__expand-icon.is-leaf) {
  color: transparent;
}

p {
  padding-left: 8px;
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  border-left: 3px solid var(--el-color-primary);
}
</style>
