<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    destroyOnClose
    showFooter
    :title="getTitle"
    width="500px"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm" name="EditForm">
      <template #menu="{ model, field }">
        <BasicTree
          v-model:value="model[field]"
          :treeData="treeData"
          :fieldNames="{ title: 'title', key: 'key' }"
          @check="onChecked"
          checkable
          toolbar
          title="权限分配"
        />
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from './user.data';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { BasicTree, TreeItem } from '/@/components/Tree';

import * as AuthorityApi from '/@/api/system/authorityApi';
import * as UserApi from '/@/api/system/userApi';
import { allHierarchy2tree } from "@/utils";
import dayjs from "dayjs";

const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const entity = ref();
const treeData = ref<TreeItem[]>([]);
const halfKeys = ref([]);

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

const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  await resetFields();
  setDrawerProps({ confirmLoading: false });
  // 需要在setFieldsValue之前先填充treeData，否则Tree组件可能会报key not exist警告
  if (unref(treeData).length === 0) {
    let auths = await AuthorityApi.all({ authorityId: 0, orderByClause: 'sort_order asc' });
    const mapName2Title = (auth: any) => {
      return { key: auth.id, title: auth.name, ...auth };
    };
    auths = auths.map(mapName2Title);
    auths = allHierarchy2tree(auths, 'parentId');
    treeData.value = auths as any as TreeItem[];
  }
  isUpdate.value = !!data?.isUpdate;
  if (isUpdate.value) {
    entity.value = data.record;
  }

  if (data.record) {
    if (data.record.authorityList.length) {
      const halfArr = [] as any;
      const keyArr = [] as any;
      const roleAuthTree = allHierarchy2tree(data.record.authorityList, 'parentId');
      const collectChildren = (auth: any) => {
        if (auth.children && auth.children.length > 0) {
          halfArr.push(auth.id);
          auth.children.forEach(collectChildren);
        } else {
          keyArr.push(auth.id);
        }
      };
      roleAuthTree.forEach(collectChildren);
      data.record.menu = keyArr;
      halfKeys.value = halfArr;
    } else {
      data.record.menu = [];
      halfKeys.value = [];
    }
  }

  if (unref(isUpdate)) {
    await setFieldsValue({
      ...data.record,
    });
  }
});

const onChecked = (checkedKeys, { halfCheckedKeys }) => {
  halfKeys.value = halfCheckedKeys;
};

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

async function handleSubmit() {
  try {
    const values = await validate();
    setDrawerProps({ confirmLoading: true });
    const { menu = [], ...rest } = values;
    const role = { ...rest, authorityList: [ ...menu, ...halfKeys.value ].map(id => ({ id })) }
    if (unref(isUpdate)) {
      await UserApi.update({ ...unref(entity), ...role, updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss') });
    } else {
      await UserApi.add(role);
    }
    closeDrawer();
    emit('success');
  } catch {} finally {
    setDrawerProps({ confirmLoading: false });
  }
}
</script>

<style lang="scss" scoped src="@/assets/custom.scss" />
