<script setup lang="ts">
import { ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, listToTree } from '@vben/utils';

import { useVbenForm } from '#/adapter/form';
import { menuAdd, menuInfo, menuList, menuUpdate } from '#/api/system/menu';
import { getDictOptions } from '#/utils/dict';

import { menuTypeOptions, yesNoOptions } from './table-data';

const emit = defineEmits<{ reload: [] }>();
const currentSource = ref<number>(0); // 默认PC端
// 侧拉内置容器 Form表单的配置项
// 动态生成图标组件配置
const getIconComponentConfig = () => {
  return {
    component: currentSource.value === 1 ? 'Input' : 'IconPicker',
    componentProps: currentSource.value === 1 ? {
      maxlength: 50,
    } : {
      prefix: 'carbon',
    },
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'icon',
    label: $t('menus.icon'),
  };
};

// 定义表单schema
const formSchema = ref([
  {
    component: 'Input',
    fieldName: 'menuId',
    dependencies: {
      show: () => false,
      triggerFields: [''],
    },
  },
  {
    component: 'ApiTreeSelect',
    componentProps: {
      api: async () => {
        const menuArray = await menuList();
        // support i18n
        menuArray.forEach((item) => {
          item.menuName = $t(item.menuName);
        });
        // const folderArray = menuArray.filter((item) => item.menuType === 'M');
        /**
         * 这里需要过滤掉按钮类型
         * 不允许在按钮下添加数据
         */
        const filteredList = menuArray.filter(
          (item) => item.menuType !== 'F',
        );
        const menuTree = listToTree(filteredList, {
          id: 'menuId',
          pid: 'parentId',
        });
        const fullMenuTree = [
          {
            menuId: 0,
            menuName: $t('menu.root'),
            children: menuTree,
          },
        ];
        addFullName(fullMenuTree, 'menuName', ' / ');
        return fullMenuTree;
      },
      getPopupContainer,
      labelField: 'menuName',
      valueField: 'menuId',
      childrenField: 'children',
      checkStrictly: true,
    },
    defaultValue: 0,
    rules: 'selectRequired',
    fieldName: 'parentId',
    label: $t('menus.parentId'),
  },
  {
    component: 'RadioGroup',
    fieldName: 'menuType',
    label: $t('menus.menu-type'),
    defaultValue: 'M',
    componentProps: {
      buttonStyle: 'solid',
      isButton: true,
      options: menuTypeOptions,
      optionType: 'button',
    },
  },
  getIconComponentConfig(),
  {
    component: 'Input',
    fieldName: 'menuName',
    componentProps: {
      maxlength: 50,
    },
    label: $t('menus.menu-name'),
    rules: 'required',
  },
  {
    component: 'InputNumber',
    fieldName: 'orderNum',
    componentProps: {
      max: 9999,
    },
    defaultValue: 0,
    label: $t('menus.order-num'),
    rules: 'required',
  },
  {
    component: 'Input',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F' && currentSource.value !== 1;
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'path',
    componentProps: {
      maxlength: 200,
    },
    label: $t('menus.path'),
    rules: currentSource.value !== 1 ? 'required' : '',
  },
  {
    component: 'Input',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F' && currentSource.value !== 1;
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'query',
    componentProps: {
      maxlength: 200,
      placeholder: '请输入路由参数',
    },
    label: $t('menus.query'),
  },
  {
    component: 'Input',
    dependencies: {
      show: (values) => {
        return values.menuType === 'C';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'component',
    componentProps: {
      maxlength: 255,
    },
    label: $t('menus.component'),
    rules: 'required',
  },
  {
    component: 'Input',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'M';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'perms',
    componentProps: {
      maxlength: 100,
    },
    label: $t('menus.perms'),
  },
  {
    component: 'RadioGroup',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'isFrame',
    label: $t('menus.is-frame'),
    defaultValue: '1',
    componentProps: {
      buttonStyle: 'solid',
      isButton: true,
      options: yesNoOptions,
      optionType: 'button',
    },
  },
  {
    component: 'RadioGroup',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'visible',
    label: $t('menus.is-visible'),
    defaultValue: '0',
    componentProps: {
      buttonStyle: 'solid',
      isButton: true,
      options: getDictOptions(DictEnum.SYS_SHOW_HIDE),
      optionType: 'button',
    },
  },
  {
    component: 'RadioGroup',
    dependencies: {
      show: (values) => {
        return values.menuType !== 'F';
      },
      triggerFields: ['menuType'],
    },
    fieldName: 'status',
    label: $t('menus.status'),
    defaultValue: '0',
    componentProps: {
      buttonStyle: 'solid',
      isButton: true,
      options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE),
      optionType: 'button',
    },
  },
]);

const [Form, FormApi] = useVbenForm({
  // 不显示提交和重置按钮
  showDefaultActions: false,
  // 垂直布局，label和input在不同行，值为vertical
  // 水平布局，label和input在同一行
  layout: 'horizontal',
  schema: formSchema,
});
interface ModalProps {
  id?: number | string;
  update: boolean;
  source: number; // 添加source字段
}
// 新增还是修改的标识
const isUpdate = ref<boolean>(false);


const [Drawer, DrawerApi] = useVbenDrawer({
  // 点击侧拉的确定按钮执行逻辑
  async onConfirm() {
    try {
      DrawerApi.drawerLoading(true);
      const { valid } = await FormApi.validate();
      if (!valid) {
        return;
      }
      const data = await FormApi.getValues();
      await (isUpdate.value
        ? menuUpdate({
            ...data,
            source: currentSource.value, // 添加source参数
          })
        : menuAdd({
            ...data,
            source: currentSource.value, // 添加source参数
          }));
      emit('reload');
      DrawerApi.close();
      await FormApi.resetForm();
    } catch (error) {
      console.error(error);
    } finally {
      DrawerApi.drawerLoading(false);
    }
  },
  // 调用drawApi.setData方法的时候会触发
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    const { id, update, source } = DrawerApi.getData() as ModalProps;
    isUpdate.value = update;
    currentSource.value = source; // 保存当前source值
    
    // 重新生成完整的表单schema以更新所有字段的配置
    formSchema.value = [
      {
        component: 'Input',
        fieldName: 'menuId',
        dependencies: {
          show: () => false,
          triggerFields: [''],
        },
      },
      {
        component: 'ApiTreeSelect',
        componentProps: {
          api: async () => {
            const menuArray = await menuList();
            // support i18n
            menuArray.forEach((item) => {
              item.menuName = $t(item.menuName);
            });
            /**
             * 这里需要过滤掉按钮类型
             * 不允许在按钮下添加数据
             */
            const filteredList = menuArray.filter(
              (item) => item.menuType !== 'F',
            );
            const menuTree = listToTree(filteredList, {
              id: 'menuId',
              pid: 'parentId',
            });
            const fullMenuTree = [
              {
                menuId: 0,
                menuName: $t('menu.root'),
                children: menuTree,
              },
            ];
            addFullName(fullMenuTree, 'menuName', ' / ');
            return fullMenuTree;
          },
          getPopupContainer,
          labelField: 'menuName',
          valueField: 'menuId',
          childrenField: 'children',
          checkStrictly: true,
        },
        defaultValue: 0,
        rules: 'selectRequired',
        fieldName: 'parentId',
        label: $t('menus.parentId'),
      },
      {
        component: 'RadioGroup',
        fieldName: 'menuType',
        label: $t('menus.menu-type'),
        defaultValue: 'M',
        componentProps: {
          buttonStyle: 'solid',
          isButton: true,
          options: menuTypeOptions,
          optionType: 'button',
        },
      },
      getIconComponentConfig(),
      {
        component: 'Input',
        fieldName: 'menuName',
        componentProps: {
          maxlength: 50,
        },
        label: $t('menus.menu-name'),
        rules: 'required',
      },
      {
        component: 'InputNumber',
        fieldName: 'orderNum',
        componentProps: {
          max: 9999,
        },
        defaultValue: 0,
        label: $t('menus.order-num'),
        rules: 'required',
      },
      {
        component: 'Input',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'F' && currentSource.value !== 1;
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'path',
        componentProps: {
          maxlength: 200,
        },
        label: $t('menus.path'),
        rules: currentSource.value !== 1 ? 'required' : '',
      },
      {
        component: 'Input',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'F' && currentSource.value !== 1;
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'query',
        componentProps: {
          maxlength: 200,
          placeholder: '请输入路由参数',
        },
        label: $t('menus.query'),
      },
      {
        component: 'Input',
        dependencies: {
          show: (values) => {
            return values.menuType === 'C';
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'component',
        componentProps: {
          maxlength: 255,
        },
        label: $t('menus.component'),
        rules: 'required',
      },
      {
        component: 'Input',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'M';
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'perms',
        componentProps: {
          maxlength: 100,
        },
        label: $t('menus.perms'),
      },
      {
        component: 'RadioGroup',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'F' && currentSource.value !== 1;
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'isFrame',
        label: $t('menus.is-frame'),
        defaultValue: '1',
        componentProps: {
          buttonStyle: 'solid',
          isButton: true,
          options: yesNoOptions,
          optionType: 'button',
        },
      },
      {
        component: 'RadioGroup',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'F';
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'visible',
        label: $t('menus.is-visible'),
        defaultValue: '0',
        componentProps: {
          buttonStyle: 'solid',
          isButton: true,
          options: getDictOptions(DictEnum.SYS_SHOW_HIDE),
          optionType: 'button',
        },
      },
      {
        component: 'RadioGroup',
        dependencies: {
          show: (values) => {
            return values.menuType !== 'F';
          },
          triggerFields: ['menuType'],
        },
        fieldName: 'status',
        label: $t('menus.status'),
        defaultValue: '0',
        componentProps: {
          buttonStyle: 'solid',
          isButton: true,
          options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE),
          optionType: 'button',
        },
      },
    ];
    
    if (id) {
      await FormApi.setFieldValue('parentId', id);
      if (update) {
        const record = await menuInfo(id);
        await FormApi.setValues(record);
      }
    }
  },
});
</script>
<template>
  <Drawer :title="isUpdate ? $t('common.modify') : $t('common.add')">
    <Form />
  </Drawer>
</template>
<style scoped lang="scss">
:deep(.el-input-number) {
  width: 100%;
}

:deep(button) {
  width: 100%;
}
</style>
