<script lang="ts" setup>
import type { DeptResp, DeptTree, Role } from '#/api/system/role/model';

import { defineEmits, ref } from 'vue';

import { useVbenDrawer, useVbenForm } from '@vben/common-ui';

import { ElTree } from 'element-plus';

import {
  getDeptTree,
  getRoleDetail,
  updateRolePerms,
} from '#/api/system/role/role';

import { permissionDrawerSchema } from './config-data';

const emit = defineEmits<{ reload: [] }>();

// 定义侧拉里面的表单
const [Form, formApi] = useVbenForm({
  showDefaultActions: false,
  layout: 'horizontal',
  schema: permissionDrawerSchema(),
});
const defaultProps = {
  children: 'children',
  label: 'label',
};
const deptRef = ref<DeptResp>({ checkedKeys: [], depts: [] });
const roleRef = ref<Role>({ roleId: -1 });
// 定义侧拉容器
const [Drawer, drawerApi] = useVbenDrawer({
  // 打开角色侧拉监听
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      return;
    }
    try {
      drawerApi.drawerLoading(true);
      const roleData = drawerApi.getData();
      roleRef.value = await getRoleDetail(roleData.roleId);
      await formApi.setValues(roleData);
      deptRef.value = await getDeptTree(roleData.roleId);
      if (roleData.dataScope === '2') {
        // 设置属性节点选中回显
        treeRef.value!.setCheckedKeys(deptRef.value.checkedKeys, false);
      }
    } catch (error) {
      console.error(error);
    } finally {
      drawerApi.drawerLoading(false);
    }
  },
  async onClosed() {
    // 重置表单
    await formApi.resetForm();
  },
  // 确认提交角色
  async onConfirm() {
    try {
      drawerApi.drawerLoading(true);
      const { valid } = await formApi.validate();
      if (!valid) {
        return;
      }
      const data = await formApi.getValues<Role>();
      // 是否是否关联
      data.deptCheckStrictly = roleRef.value.deptCheckStrictly;
      if (data.dataScope === '2') {
        // 获取全选节点
        const checkedKeys = treeRef.value!.getCheckedKeys(false);
        // 获取半选节点
        const halfCheckKeys = treeRef.value!.getHalfCheckedKeys();
        // 组装
        checkedKeys.unshift(...halfCheckKeys);
        data.deptIds = checkedKeys;
      } else {
        data.deptIds = [];
      }
      // 调用数据权限更新接口
      await updateRolePerms(data);
      // 发射刷新列表
      emit('reload');
      drawerApi.close();
    } catch (error) {
      console.error(error);
    } finally {
      drawerApi.drawerLoading(false);
    }
  },
});
// 展开/收起
const treeRef = ref<InstanceType<typeof ElTree>>();
function isExpendTree(val: boolean) {
  const tree = treeRef.value;
  if (val) {
    if (tree) {
      const nodes = tree.store._getAllNodes(); // 获取所有节点
      nodes.forEach((node: any) => {
        node.expanded = true; // 设置展开状态
      });
    }
  } else {
    if (tree) {
      const nodes = tree.store._getAllNodes();
      nodes.forEach((node: any) => {
        node.expanded = false;
      });
    }
  }
}
// 递归收集所有节点 ID
const getAllKeys = (treeData: DeptTree[]) => {
  const keys: number[] = []; // 或 number[]，根据你的 node-key 类型
  for (const node of treeData) {
    keys.push(node.id);
    if (node.children) {
      keys.push(...getAllKeys(node.children));
    }
  }
  return keys;
};
// 全选/全不选
function isAllSelect(val: boolean) {
  const tree = treeRef.value;
  if (val) {
    const allKeys = getAllKeys(deptRef.value.depts);
    tree!.setCheckedKeys(allKeys, false);
  } else {
    tree!.setCheckedKeys([], false);
  }
}
// 是否子父关联
function isChildParent(val: boolean) {
  roleRef.value.deptCheckStrictly = val;
}
</script>
<template>
  <Drawer title="分配数据权限">
    <Form>
      <template #checkboxGroup>
        <el-checkbox label="展开/折叠" @change="isExpendTree" />
        <el-checkbox label="全选/全不选" @change="isAllSelect" />
        <el-checkbox
          v-model="roleRef.deptCheckStrictly"
          checked
          label="父子联动"
          @change="isChildParent"
        />
      </template>
      <template #permTree>
        <ElTree
          class="w-screen rounded-lg border"
          ref="treeRef"
          :data="deptRef.depts"
          show-checkbox
          node-key="id"
          highlight-current
          :check-strictly="!roleRef.deptCheckStrictly"
          :props="defaultProps"
        />
      </template>
    </Form>
  </Drawer>
</template>
