<template>
  <BasicDrawer v-bind="$attrs" @register="registerDrawer" showFooter :title="getTitle" width="500px" @ok="handleSubmit">
    <BasicForm @register="registerForm">
      <template #menu>
        <Spin :spinning="spinning"></Spin>
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref, nextTick } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema, KeysTypeEnum, RoleMenuDictEnum } from './role.data';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { BasicTree, TreeItem } from '/@/components/Tree';
import { useMessage } from '/@/hooks/web/useMessage';
const { t } = useI18n(); //加载国际化
// 加载菜单数据
import { getMenuList } from '/@/api/sys/menu';
import { useI18n } from '/@/hooks/web/useI18n';
import { MenuRecord } from '/@/api/sys/model/menuModel';
import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
import { findDictItemByCode } from '/@/api/system/dict';
import { RoleEnum } from '/@/enums/roleEnum';
import { Spin } from 'ant-design-vue';
import { useUserStore } from '/@/store/modules/user';
import { session } from '/@/utils/Memory';
import { v4 as uuidv4 } from 'uuid';


type TreeData = MenuRecord & TreeItem;

export default defineComponent({
  name: 'RoleDrawer',
  components: { BasicDrawer, BasicForm, BasicTree, Spin },
  emits: ['success', 'register'],
  setup(_, { emit }) {
    const isUpdate = ref<boolean>(true);
    const treeData = ref<TreeData[]>([]);
    const roleMenus = ref<string[]>([]);
    const roleId = ref<string>('');
    const checked = ref<string[]>([]); //需要选中的节点
    const spinning = ref(false);
    var nowRole = null;

    const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
      labelWidth: 100,
      schemas: formSchema,
      showActionButtonGroup: false,
    });

    const transformName = (data: TreeData[]) => {
      return data.map((item) => {
        item.name = t(item.name);
        if (item.children && item.children.length) {
          item.children = transformName(item.children as unknown as TreeData[]);
        }
        return item;
      });
    };

    const userStore = useUserStore();
    const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
      resetFields();
      roleId.value = '';
      // 在打开弹窗时清除所有选择的菜单
      isUpdate.value = data.isUpdate;
      const roleType = data?.record?.roleType || userStore.getRoleList.at(0);

      try {
        spinning.value = true;
        // 需要在setFieldsValue之前先填充treeData，否则Tree组件可能会报key not exist警告

        if (!unref(treeData).length) {
          // 获取全部的菜单
          const menuListModel = await getMenuList();
          treeData.value = transformName(menuListModel as unknown as TreeData[]);
        }

        const keys = await getPermissionByRole(roleType);
        const { keyType } = RoleMenuDictEnum[roleType];
        treeData.value = getPermissionTreeData(
          unref(treeData) as unknown as TreeData[],
          keys,
          keyType
        );
        // 更新
        if (unref(isUpdate)) {
          checked.value = [];
          roleId.value = data.record.id;
          nowRole = data.record;
          setFieldsValue(data.record);
        } else {
        }
      } catch (error) {
        throw error;
      } finally {
        spinning.value = false;
      }
    });

    const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));

    async function handleSubmit() {
      setDrawerProps({ confirmLoading: true });
      const { createMessage } = useMessage();
      try {
        const values = await validate();
        const req = {
          groupName: values.groupName,
          sort: values.sort
        };
        if (unref(isUpdate)) {
          if (nowRole) {
            req.updateuser = session.getItem("userInfo").EMPLOYEE.EMPLOYEE_ID;
            req.groupid = nowRole.groupid;
          }
        } else {
          req.groupid = uuidv4()
        }
        saveOrUpdateRoleInfoWithMenu(req).then(() => {
          closeDrawer();
          emit('success');
          nowRole = null;
          createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
        });
      } finally {
        setTimeout(() => {
          setDrawerProps({ confirmLoading: false });
        }, 300);
      }
    }

    const getPermissionByRole = async (roleType: RoleEnum) => {
      try {
        const { key } = RoleMenuDictEnum[roleType];
        const res = await findDictItemByCode({ dictCode: key });
        return res.map((item) => item.itemValue);
      } catch (error) { }
      return [];
    };

    const getPermissionTreeData = (
      data: MenuRecord[],
      permissionKeys: string[],
      keysType: KeysTypeEnum
    ) => {
      const setDisabled = (data: MenuRecord[], flag: boolean) => {
        return data.map((item) => {
          item.name = t(item.name);
          if (item.children && item.children.length) {
            item.children = setDisabled(item.children, flag);
          }
          return {
            ...item,
            disabled: flag,
            icon: item.meta.icon,
          } as TreeData;
        });
      };

      const permissionCompare = (
        data: MenuRecord[],
        permissionKeys: string[],
        keysType: KeysTypeEnum
      ) => {
        return data.map((item) => {
          item.name = t(item.name);
          const findFlag = permissionKeys.includes(item.permission);
          if (findFlag) item.isDictCompareDisabled = true;
          const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
          item.disabled = disabledFlag;

          if (item.isDictCompareDisabled && item.children && item.children.length) {
            setDisabled(item.children, disabledFlag);
          } else {
            if (item.children && item.children.length) {
              item.children = permissionCompare(item.children, permissionKeys, keysType);
              item.disabled = item.children.every((temp) => temp.disabled);
            }
          }
          return {
            ...item,
            icon: item.meta.icon,
          } as TreeData;
        });
      };

      const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
        if (item.children && item.children.length) {
          const rootDisabledFlag = item.children.every((temp) => temp.disabled);
          item.disabled = rootDisabledFlag;
        }
        return item;
      });

      return result;
    };

    return {
      spinning,
      registerDrawer,
      registerForm,
      getTitle,
      handleSubmit,
      treeData,
      roleMenus,
    };
  },
});
</script>

<style scoped lang="less">
:deep(.vben-basic-tree) {
  width: 100% !important;
}

:deep(.is-unflod) {
  display: none !important;
}

:deep(.is-flod) {
  display: none !important;
}
</style>
