<template>
  <el-drawer :title="title" v-model="drawerOpened" @close="clear">
    <el-form label-position="right" label-width="80px" :model="formData" :rules="formRules" ref="formInstance">
      <el-form-item label="角色名称" prop="roleName">
        <el-input placeholder="角色名称" v-model="formData.roleName" />
      </el-form-item>

      <el-form-item label="角色权限">
        <!-- <PermissioTreeCard title="平台入口权限" :tree-data="menuPermTreeData" ref="menuCardInstance" /> -->
        <PermissioTreeCard title="菜单权限" :tree-data="menuPermTreeData" ref="menuCardInstance" />
        <PermissioTreeCard title="功能权限" :tree-data="funcPermTreeData" ref="funcCardInstance" />
      </el-form-item>

      <el-form-item label="备注" prop="remark">
        <el-input type="textarea" placeholder="备注" v-model="formData.remark" />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="reset">重置</el-button>
      <el-button type="primary" @click="submit">提交</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
  import { reactive, ref, computed, toRaw } from 'vue';
  import PermissioTreeCard from './PermissionTreeCard.vue';
  import { RoleForm, Role, AssignedPermissions } from '@/types/role/type';
  import { FormRules, FormInstance, ElMessage } from 'element-plus';
  import useMenuPermTree from '../hooks/useMenuPermissionTree';
  import useFuncPermTree from '../hooks/useFunctionPermissionTree';
  import { createRole, editRole, getAssignedPerms } from '@/api/system/role';

  defineProps<{
    title: string;
  }>();

  const emits = defineEmits<{
    (e: 'submitted'): void; // 提交之后触发的事件
  }>();

  const { menuPermTreeData } = useMenuPermTree();
  const { funcPermTreeData } = useFuncPermTree();

  const drawerOpened = ref(false);
  const menuCardInstance = ref<InstanceType<typeof PermissioTreeCard>>();
  const funcCardInstance = ref<InstanceType<typeof PermissioTreeCard>>();

  let initialPermissions: AssignedPermissions | null = null;
  const emptyValue = {
    id: null,
    roleName: '',
    remark: '',
    menuIds: [],
    permIds: [],
  };
  // 表单相关
  let defaultFormData: RoleForm = { ...emptyValue };
  let formData = reactive<RoleForm>(defaultFormData);
  const formRules: FormRules = {
    roleName: { required: true, trigger: 'blur', message: '请填写角色名称' },
    remark: {},
  };
  const formInstance = ref<FormInstance>();

  const isEditing = computed(() => formData.id != null);

  /**
   * 打开 drawer。如果未传递 roleId，表示创建角色；反之，表示编辑角色
   * @param roleId 可选
   */
  const open = (role?: Role) => {
    if (role) {
      defaultFormData.id = role.id;
      defaultFormData.roleName = role.roleName;
      defaultFormData.remark = role.remark;
      formData.id = role.id;
      formData.roleName = role.roleName;
      formData.remark = role.remark;
      getAssignedPermissions(role.id);

      // TODO: 获取已拥有的权限
    } else {
      formData.id = null;
      formData.roleName = '';
      formData.remark = '';
      defaultFormData = { ...emptyValue };
      menuCardInstance.value?.setAssignedPermissions([]);
      funcCardInstance.value?.setAssignedPermissions([]);
    }
    drawerOpened.value = true;
  };

  /**
   * 获取当前角色已分配的权限数据，并更新相应的权限数
   */
  const getAssignedPermissions = async (roleId: number) => {
    try {
      initialPermissions = await getAssignedPerms(roleId);
      displayAssignedPermissions(initialPermissions);
    } catch (e) {
      console.error(e);
    }
  };

  const displayAssignedPermissions = (result: AssignedPermissions | null) => {
    if (!result) {
      menuCardInstance.value?.setAssignedPermissions([]);
      funcCardInstance.value?.setAssignedPermissions([]);
      return;
    }
    if (result?.menuIds?.length) {
      menuCardInstance.value?.setAssignedPermissions(result.menuIds);
    } else {
      menuCardInstance.value?.setAssignedPermissions([]);
    }

    if (result?.permIds?.length) {
      funcCardInstance.value?.setAssignedPermissions(result.permIds);
    } else {
      funcCardInstance.value?.setAssignedPermissions([]);
    }
  };

  /**
   * 重置表单,恢复为修改之前的默认值
   */
  const reset = () => {
    formInstance.value?.resetFields();
    Object.assign(formData, defaultFormData);
    displayAssignedPermissions(initialPermissions!);
  };

  const clear = () => {
    formInstance.value?.resetFields();
    formData = Object.assign(formData, emptyValue);
    displayAssignedPermissions(null);
  };

  /**
   * 提交。创建和编辑统一
   */
  const submit = async () => {
    formData.menuIds = menuCardInstance.value!.getSelectedPermissions();
    formData.permIds = funcCardInstance.value!.getSelectedPermissions();

    const api = isEditing.value ? editRole : createRole;
    try {
      await formInstance.value?.validate();
      await api(toRaw(formData));
      drawerOpened.value = false;
      ElMessage.success('提交成功');
      // 让父组件更新列表
      emits('submitted');
    } catch (e) {
      console.error(e);
    }
  };

  defineExpose({ open });
</script>
