<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';
import type { SysMenuApi } from '#/api/auth/menu';
import type { SysRoleApi } from '#/api/auth/role';

import { computed, nextTick, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';

import { useVbenForm } from '#/adapter/form';
import { apiMenuTreeSelect } from '#/api/auth/menu';
import { apiAdd, apiUpdate, getRoleDetail } from '#/api/auth/role';
import { MenuSelectTable } from '#/components/tree';
import { getDictOptions } from '#/utils/dict';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

type MenuOption = SysMenuApi.MenuOption;

const emit = defineEmits<{
  success: [];
}>();
const formData = ref<SysRoleApi.Role>({});

const formSchema: VbenFormSchema[] = [
  {
    component: 'Input',
    fieldName: 'name',
    label: '角色名称',
    rules: 'required',
  },
  {
    component: 'Input',
    fieldName: 'roleKey',
    help: '如: test simpleUser等',
    label: '权限标识',
    rules: 'required',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      optionType: 'button',
      options: getDictOptions(DictEnum.SYS_COMMON_STATUS, true),
    },
    defaultValue: 1,
    fieldName: 'status',
    label: '状态',
    rules: 'required',
  },
  // {
  //   component: 'Input',
  //   fieldName: 'dataScope',
  //   label: '数据范围',
  //   rules: 'required',
  // },
  {
    component: 'Input',
    fieldName: 'remark',
    label: '备注',
    // 占满三列空间 基线对齐
    formItemClass: 'col-span-2',
    // rules: 'required',
  },
  {
    component: 'Radio',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
    defaultValue: true,
    fieldName: 'menuCheckStrictly',
    label: '菜单权限',
  },
  {
    component: 'Input',
    defaultValue: [],
    fieldName: 'menuIds',
    label: '菜单权限',
    formItemClass: 'col-span-2',
  },
];

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
    },
    formItemClass: 'col-span-1',
    // labelWidth: 90,
  },
  layout: 'vertical',
  schema: formSchema,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2 gap-x-4',
});

async function customFormValueGetter() {
  const v = await defaultFormValueGetter(formApi)();
  // 获取勾选信息
  const menuIds = menuSelectRef.value?.getCheckedKeys?.() ?? [];
  const mixStr = v + menuIds.join(',');
  return mixStr;
}

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: customFormValueGetter,
    currentGetter: customFormValueGetter,
  },
);

const [Drawer, drawerApi] = useVbenDrawer({
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: onSubmit,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number };
    let checkedKeys: number[] = [];
    if (id) {
      const data = await getRoleDetail(id);
      checkedKeys = data.menuIds;
      formData.value = data;
      await formApi.setValues(formData.value);
    }
    await setupMenuTree(checkedKeys);
    await markInitialized();

    drawerApi.drawerLoading(false);
  },
});

const menuSelectRef = ref<InstanceType<typeof MenuSelectTable>>();

const menuTree = ref<MenuOption[]>([]);

async function setupMenuTree(menuIds: number[]) {
  // if (id) {
  //   const resp = await roleMenuTreeSelect(id);
  //   // const menus = resp.menus;
  //   // 设置菜单信息
  //   menuTree.value = resp.menus;
  //   // keys依赖于menu 需要先加载menu
  //   await nextTick();
  //   await formApi.setFieldValue('menuIds', resp.checkedKeys);
  // } else {
  const resp = await apiMenuTreeSelect({});
  // 设置菜单信息
  menuTree.value = resp;
  // keys依赖于menu 需要先加载menu
  await nextTick();
  // console.log('[menuIds]', menuIds, formApi.form.values.menuCheckStrictly);
  await formApi.setFieldValue('menuIds', menuIds);
  // }
}

async function onSubmit() {
  const { valid } = await formApi.validate();
  if (valid) {
    drawerApi.lock();
    const menuIds = menuSelectRef.value?.getCheckedKeys?.() ?? [];
    const data = await formApi.getValues<SysRoleApi.Role>();
    data.menuIds = menuIds;
    try {
      await (formData.value?.id
        ? apiUpdate({ id: formData.value.id, ...data })
        : apiAdd(data));
      // await saveRole({
      //   sysRole: { id: formData.value.id || 0, ...data },
      //   menuIds,
      // });
      resetInitialized();
      emit('success');
      drawerApi.close();
    } finally {
      drawerApi.unlock();
    }
  }
}

async function handleClosed() {
  await formApi.resetForm();
  resetInitialized();
}

const getDrawerTitle = computed(() =>
  formData.value?.id ? '修改角色' : '新增角色',
);

/**
 * 通过回调更新 无法通过v-model
 * @param value 菜单选择是否严格模式
 */
function handleMenuCheckStrictlyChange(value: boolean) {
  formApi.setFieldValue('menuCheckStrictly', value);
}
</script>
<template>
  <Drawer class="w-[800px]" :title="getDrawerTitle">
    <BasicForm>
      <template #menuIds="slotProps">
        <div class="h-[600px] w-full">
          <!-- association为readonly 不能通过v-model绑定 -->
          <MenuSelectTable
            ref="menuSelectRef"
            :checked-keys="slotProps.value"
            :association="formApi.form.values.menuCheckStrictly"
            :menus="menuTree"
            @update:association="handleMenuCheckStrictlyChange"
          />
        </div>
      </template>
    </BasicForm>
  </Drawer>
</template>
