<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    destroyOnClose
    :title="getTitle"
    width="50%"
    @ok="handleSubmit"
    @visible-change="
      () => {
        activeKey = '1';
      }
    "
  >
    <a-tabs v-model:activeKey="activeKey">
      <a-tab-pane key="1" :tab="t('菜单信息')">
        <BasicForm @register="registerForm" />
      </a-tab-pane>
      <a-tab-pane key="2" :tab="t('按钮信息')">
        <ButtonTable
          :menuId="rowId"
          :hasMetaFormId="hasMetaFormId"
          ref="buttonTable"
          v-if="activeKey"
        />
      </a-tab-pane>
      <a-tab-pane key="3" :tab="t('表格信息')">
        <ColumnTable :menuId="rowId" ref="columnTable" v-if="activeKey" />
      </a-tab-pane>
      <a-tab-pane key="4" :tab="t('表单信息')">
        <FormTable :menuId="rowId" ref="formTable" v-if="activeKey" />
      </a-tab-pane>
    </a-tabs>
  </BasicDrawer>
</template>
<script lang="ts">
  import { defineComponent, ref, computed } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicColumn } from '/@/components/Table';
  import { cloneDeep } from 'lodash-es';
  import ButtonTable from './ButtonTable.vue';
  import ColumnTable from './ColumnTable.vue';
  import FormTable from './FormTable.vue';
  import {
    getMenuTree,
    addMenu,
    updateMenu,
    getMenuButtonById,
    getMenuColumnById,
    getMenuFormById,
  } from '/@/api/system/menu';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { MenuButtonModel } from '/@/api/system/menuButton/model';
  import { getSubSystemList } from '/@/api/system/subSystem';

  import { usePermissionStore } from '/@/store/modules/permission';
  const { t } = useI18n();

  const isUpdate = ref<boolean>(false);
  const componentType = ref<number>(0);
  const hasMetaFormId = ref(false);
  export const formSchema: FormSchema[] = [
    {
      field: 'title',
      label: t('菜单名称'),
      component: 'Input',
      required: true,
    },
    {
      field: 'name',
      label: t('组件名称'),
      component: 'Input',
      required: true,
    },
    {
      field: 'code',
      label: t('编码'),
      component: 'Input',
      required: true,
    },
    {
      field: 'sortCode',
      label: t('排序'),
      component: 'InputNumber',
      required: true,
    },

    {
      field: 'parentId',
      label: t('上级菜单'),
      component: 'MenuSelect',
      colProps: { lg: 24, md: 24 },
    },
    {
      field: 'systemId',
      label: t('所属系统'),
      component: 'Select',
      componentProps: {
        fieldNames: {
          label: 'name',
          value: 'id',
        },
        getPopupContainer: () => document.body,
        allowClear: false,
      },
      colProps: { lg: 24, md: 24 },
      dynamicDisabled: ({ values }) => {
        return values.parentId ? true : false;
      },
    },
    {
      field: 'path',
      label: t('路由地址'),
      component: 'Input',
      colProps: { lg: 24, md: 24 },
      dynamicDisabled: ({ values }) => {
        return values.componentType === 1;
      },
      ifShow: ({ values }) => {
        return !(values.outLink === 1 && values.openMode === 'window');
      },
      dynamicRules: ({ values }) => {
        return [
          {
            required: true,
            validator: (_, value) => {
              if (!value) {
                return Promise.reject('请输入路由地址');
              } else if (values.menuType === 0) {
                if (value.indexOf('/') === 0) {
                  return Promise.resolve();
                } else {
                  return Promise.reject('父级菜单的路由地址首字符要是斜杠');
                }
              } else {
                return Promise.resolve();
              }
            },
          },
        ];
      },
    },
    {
      field: 'outLink',
      label: t('是否外链'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('是'), value: 1 },
          { label: t('否'), value: 0 },
        ],
      },
    },
    {
      field: 'icon',
      label: t('图标'),
      component: 'IconPicker',
    },
    {
      field: 'openMode',
      label: t('打开方式'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('iframe'), value: 'iframe' },
          { label: t('新窗口'), value: 'window' },
        ],
      },
      required: true,
      ifShow: ({ values }) => {
        return values.outLink === 1;
      },
    },
    {
      field: 'component',
      label: t('组件路径'),
      component: 'Input',
      colProps: { lg: 24, md: 24 },
      required: true,
      ifShow: ({ values }) => {
        return values.outLink === 0 && values.componentType === 0;
      },
    },
    {
      field: 'iframeSrc',
      label: t('外链地址'),
      component: 'Input',
      colProps: { lg: 24, md: 24 },
      required: true,
      helpMessage: '如果是外链内嵌，在此输入地址！',
      ifShow: ({ values }) => {
        return values.outLink === 1 && values.openMode === 'iframe';
      },
    },
    {
      field: 'windowUrl',
      label: t('新窗口地址'),
      component: 'Input',
      required: true,
      colProps: { lg: 24, md: 24 },
      dynamicDisabled: ({ values }) => {
        return values.componentType === 1;
      },
      ifShow: ({ values }) => {
        return values.outLink === 1 && values.openMode === 'window';
      },
    },
    {
      field: 'remark',
      label: t('备注'),
      component: 'InputTextArea',
      colProps: { lg: 24, md: 24 },
    },
    {
      field: 'menuType',
      label: t('页面/菜单'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('页面'), value: 1 },
          { label: t('菜单'), value: 0 },
        ],
      },
    },
    {
      field: 'enabledMark',
      label: t('状态'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('启用'), value: 1 },
          { label: t('禁用'), value: 0 },
        ],
      },
    },

    {
      field: 'display',
      label: t('是否显示'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('是'), value: 1 },
          { label: t('否'), value: 0 },
        ],
      },
    },
    {
      field: 'componentType', //隐藏组件
      label: t('是否自定义'),
      component: 'RadioButtonGroup',
      componentProps: {
        options: [
          { label: t('是'), value: 1 },
          { label: t('否'), value: 0 },
        ],
      },
      show: false,
    },
  ];

  export const columns: BasicColumn[] = [
    {
      title: t('按钮名称'),
      dataIndex: 'name',
      width: 100,
      align: 'left',
    },
    {
      title: t('编码'),
      dataIndex: 'code',
      width: 100,
    },
    {
      title: t('地址'),
      dataIndex: 'url',
      width: 200,
    },
    {
      title: t('请求方式'),
      dataIndex: 'method',
      width: 180,
      format: (text: string | number) => {
        if (text === 0) return 'GET';
        else if (text === 1) return 'POST';
        else if (text === 2) return 'PUT';
        else return 'DELETE';
      },
    },
  ];

  export default defineComponent({
    name: 'MenuDrawer',
    components: {
      BasicDrawer,
      BasicForm,
      FormTable,

      ButtonTable,
      ColumnTable,
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const permissionStore = usePermissionStore();
      const { notification } = useMessage();
      const rowId = ref('');
      const activeKey = ref('1');
      const buttonTable = ref();
      const columnTable = ref();
      const formTable = ref();
      const buttonDatas = ref<MenuButtonModel[]>([]);
      const columnDatas = ref<MenuButtonModel[]>([]);
      const formDatas = ref<MenuButtonModel[]>([]);
      const systemId = ref('1');
      const childIds = ref([]);
      const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
        labelWidth: 100,
        schemas: formSchema,
        showActionButtonGroup: false,
        baseColProps: { lg: 12, md: 24 },
      });

      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
        resetFields();
        setDrawerProps({ confirmLoading: false });
        let newData = cloneDeep(data);
        isUpdate.value = !!data?.isUpdate;

        if (isUpdate.value) {
          rowId.value = data.record.id;
          childIds.value = data.childIds;
          if (data.record && data.record.meta && data.record.meta.formId) {
            hasMetaFormId.value = true;
          }
          componentType.value = data.record.componentType;
          if (data.record.outLink == 1) {
            newData.record.url = data.record.component;
            if (data.record.openMode === 'window') {
              newData.record.windowUrl = data.record.path;
            }
          }
          if (data.record.parentId) {
            newData.record.systemId = newData.record.meta.systemId;
          }
          if (!data.record.icon) {
            newData.record.icon = 'ant-design:setting-outlined';
          }
          setFieldsValue({
            ...newData.record,
          });
          getMenuButtonById({ id: data.record.id }).then((res) => {
            buttonDatas.value = res;
          });
          getMenuColumnById({ menuId: data.record.id }).then((res) => {
            columnDatas.value = res;
          });
          getMenuFormById({ menuId: data.record.id }).then((res) => {
            formDatas.value = res;
          });
        } else {
          rowId.value = '';
          componentType.value = 0;
          setFieldsValue({
            menuType: 1,
            enabledMark: 1,
            outLink: 0,
            display: 1,
            componentType: 0,
            openMode: 'iframe',
            icon: 'ant-design:setting-outlined',
            systemId: import.meta.env.VITE_GLOB_PRODUCTION === 'true' ? '' : '1',
          });
        }
        const treeData = await getMenuTree();

        const system = await getSubSystemList();
        const onlineSystem = system.filter((x) => x.id !== '1'); //线上环境使用
        updateSchema([
          {
            field: 'parentId',
            componentProps: ({ formModel }) => {
              return {
                getPopupContainer: () => document.body,
                onChange: (v) => {
                  findParentSystem(treeData, treeData, v);
                  formModel.systemId = systemId.value;
                },
              };
            },
          },
          {
            field: 'systemId',
            componentProps: {
              options: import.meta.env.VITE_GLOB_PRODUCTION === 'true' ? onlineSystem : system,
            },
          },
          {
            field: 'outLink',
            dynamicDisabled: () => {
              return isUpdate.value && componentType.value == 1;
            },
          },
          {
            field: 'path',
            dynamicDisabled: () => {
              return isUpdate.value && componentType.value == 1;
            },
          },
        ]);
      });

      const getTitle = computed(() => (!isUpdate.value ? t('新增菜单') : t('编辑菜单')));

      async function handleSubmit() {
        try {
          const values = await validate();
          if (values.outLink == 1) {
            values.component = values.url;
            if (values.openMode === 'window') {
              values.path = values.windowUrl;
            }
          }
          values.buttonList = buttonTable.value
            ? buttonTable.value.getDataSource()
            : buttonDatas.value;
          values.columnList = columnTable.value
            ? columnTable.value.getDataSource()
            : columnDatas.value;
          values.formList = formTable.value ? formTable.value.getDataSource() : formDatas.value;
          setDrawerProps({ confirmLoading: true });
          // TODO custom api
          if (!isUpdate.value) {
            //false 新增
            await addMenu(values);
            notification.success({
              message: t('提示'),
              description: t('新增菜单成功'),
            }); //提示消息
          } else {
            values.id = rowId.value;
            values.childIds = childIds.value;
            await updateMenu(values);
            notification.success({
              message: t('提示'),
              description: t('修改菜单成功'),
            }); //提示消息
          }
          await permissionStore.buildRoutesAction(true, values);
          closeDrawer();
          emit('success');
        } catch (error) {
          setDrawerProps({ confirmLoading: false });
        }
      }
      function findParentSystem(treeData, tempTree, id) {
        for (let i = 0; i < treeData.length; i++) {
          let o = treeData[i];

          if (o.id == id) {
            systemId.value = o.systemId;
            if (o.parentId) {
              findParentSystem(tempTree, tempTree, o.parentId);
            } else {
              break;
            }
          } else if (o.children?.length > 0) {
            findParentSystem(o.children, tempTree, id);
          }
        }
      }
      return {
        registerDrawer,
        registerForm,
        getTitle,
        hasMetaFormId,
        handleSubmit,
        buttonTable,
        rowId,
        columnTable,
        formTable,
        activeKey,
        t,
      };
    },
  });
</script>
