<template>
  <BasicDrawer @register="registerDrawer" :title="drawerTitle" :width="1000" destroyOnClose>
    <BasicTable @register="registerTable" :rowSelection="rowSelection">
      <template #tableTitle>
        <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">新增</a-button>
        <a-dropdown v-if="selectedRowKeys.length > 0">
          <template #overlay>
            <a-menu>
              <a-menu-item key="1" @click="batchHandleDelete">
                <Icon icon="ant-design:delete-outlined" />
                删除
              </a-menu-item>
            </a-menu>
          </template>
          <a-button>
            批量操作
            <Icon icon="mdi:chevron-down" />
          </a-button>
        </a-dropdown>
      </template>

      <template #action="{ record }">
        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
      </template>
    </BasicTable>

    <component :is="modalComponent" @register="registerModal" @success="handleSuccess" />
  </BasicDrawer>
</template>

<script lang="ts" setup>
  import { computed, reactive, ref, unref } from 'vue';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicTable, TableAction } from '/@/components/Table';
  import type { BasicColumn, BasicTableProps, FormSchema } from '/@/components/Table';
  import { useTable } from '/@/components/Table';
  import { useModal } from '/@/components/Modal';

  type FixedMode = 'schoolId' | 'bizSchool' | 'majorId';

  type DrawerOpenConfig = {
    title: string;
    record?: Recordable;
    fixedMode?: FixedMode;
    bizType?: string;
    columns: BasicColumn[];
    searchSchemas?: FormSchema[];
    listApi: (params: any) => Promise<any>;
    deleteOne: (params: any, handleSuccess: Fn) => Promise<any>;
    batchDelete: (params: any, handleSuccess: Fn) => Promise<any>;
    modalComponent: any;
    getExtraDropDownActions?: (record: any) => any[];
    majorId?: number | string;
    ownerName?: string;
  };

  const [registerModal, { openModal }] = useModal();

  const ownerName = ref('');
  const fixedParams = ref<Recordable>({});

  const title = ref('');
  const fixedMode = ref<FixedMode>('schoolId');
  const bizType = ref('school');
  const columns = ref<BasicColumn[]>([]);
  const searchSchemas = ref<FormSchema[]>([]);
  const listApi = ref<(params: any) => Promise<any>>();
  const deleteOne = ref<(params: any, handleSuccess: Fn) => Promise<any>>();
  const batchDelete = ref<(params: any, handleSuccess: Fn) => Promise<any>>();
  const modalComponent = ref<any>();
  const getExtraDropDownActions = ref<((record: any) => any[]) | undefined>();

  function getDisableFieldsByMode() {
    if (unref(fixedMode) === 'schoolId') {
      return ['schoolId'];
    }
    if (unref(fixedMode) === 'bizSchool') {
      return ['bizType', 'bizId'];
    }
    if (unref(fixedMode) === 'majorId') {
      return ['majorId'];
    }
    return [];
  }

  const fixedDisabledFields = reactive<string[]>(getDisableFieldsByMode());
  const filteredSearchSchemas = computed(() => {
    return (unref(searchSchemas) || []).filter((s) => !fixedDisabledFields.includes(String(s.field)));
  });

  const drawerTitle = computed(() => {
    const name = unref(ownerName);
    const t = unref(title);
    return name ? `${t}（${name}）` : t;
  });

  const selectedRowKeys = ref<any[]>([]);
  const selectedRows = ref<Recordable[]>([]);

  const rowSelection = reactive({
    type: 'checkbox',
    selectedRowKeys: selectedRowKeys,
    selectedRows: selectedRows,
    onChange(keys, rows) {
      selectedRowKeys.value = keys;
      selectedRows.value = rows;
    },
  });

  const tableProps = reactive<Partial<BasicTableProps>>({
    rowKey: 'id',
    useSearchForm: true,
    canResize: false,
    showIndexColumn: false,
    showTableSetting: true,
    showActionColumn: true,
    actionColumn: {
      width: 160,
      fixed: 'right',
    },
    api: (params) => {
      if (!unref(listApi)) return Promise.resolve({ records: [], total: 0 });
      return unref(listApi)!(Object.assign({}, params, unref(fixedParams)));
    },
    beforeFetch: (params) => {
      return Object.assign(params, unref(fixedParams));
    },
    formConfig: {
      schemas: [],
      autoSubmitOnEnter: true,
      showAdvancedButton: true,
      fieldMapToNumber: [],
      fieldMapToTime: [],
    },
    columns: [],
  });

  const [registerTable, { reload, setProps }] = useTable(tableProps);

  const [registerDrawer] = useDrawerInner(async (data: DrawerOpenConfig) => {
    selectedRowKeys.value = [];

    title.value = data?.title || '';
    fixedMode.value = (data?.fixedMode as FixedMode) || 'schoolId';
    bizType.value = data?.bizType || 'school';
    columns.value = data?.columns || [];
    searchSchemas.value = data?.searchSchemas || [];
    listApi.value = data?.listApi;
    deleteOne.value = data?.deleteOne;
    batchDelete.value = data?.batchDelete;
    modalComponent.value = data?.modalComponent;
    getExtraDropDownActions.value = data?.getExtraDropDownActions;

    if (unref(fixedMode) === 'schoolId') {
      const school = data?.record;
      fixedParams.value = { schoolId: school?.id };
      ownerName.value = school?.mainName || school?.shortName || school?.mainCode || String(school?.id || '');
    } else if (unref(fixedMode) === 'bizSchool') {
      const school = data?.record;
      fixedParams.value = { bizType: unref(bizType), bizId: school?.id };
      ownerName.value = school?.mainName || school?.shortName || school?.mainCode || String(school?.id || '');
    } else if (unref(fixedMode) === 'majorId') {
      fixedParams.value = { majorId: data?.majorId };
      ownerName.value = data?.ownerName || String(data?.majorId || '');
    }

    fixedDisabledFields.splice(0, fixedDisabledFields.length, ...getDisableFieldsByMode());

    setProps({
      title: unref(title),
      columns: unref(columns),
      formConfig: {
        ...(tableProps.formConfig as any),
        schemas: unref(filteredSearchSchemas),
      },
    });

    reload();
  });

  function handleAdd() {
    openModal(true, {
      isUpdate: false,
      showFooter: true,
      record: unref(fixedParams),
      dynamicDisabledFields: fixedDisabledFields,
    });
  }

  function handleEdit(record: Recordable) {
    openModal(true, {
      record: Object.assign({}, record, unref(fixedParams)),
      isUpdate: true,
      showFooter: true,
      dynamicDisabledFields: fixedDisabledFields,
    });
  }

  function handleDetail(record: Recordable) {
    openModal(true, {
      record: Object.assign({}, record, unref(fixedParams)),
      isUpdate: true,
      showFooter: false,
      dynamicDisabledFields: fixedDisabledFields,
    });
  }

  async function handleDelete(record: Recordable) {
    await unref(deleteOne)?.({ id: record.id }, handleSuccess);
  }

  async function batchHandleDelete() {
    await unref(batchDelete)?.({ ids: selectedRowKeys.value }, handleSuccess);
  }

  function handleSuccess() {
    (selectedRowKeys.value = []) && reload();
  }

  function getTableAction(record) {
    return [
      {
        label: '编辑',
        onClick: handleEdit.bind(null, record),
      },
    ];
  }

  function getDropDownAction(record) {
    const extra = unref(getExtraDropDownActions) ? unref(getExtraDropDownActions)!(record) : [];
    return [
      {
        label: '详情',
        onClick: handleDetail.bind(null, record),
      },
      ...extra,
      {
        label: '删除',
        popConfirm: {
          title: '是否确认删除',
          confirm: handleDelete.bind(null, record),
        },
      },
    ];
  }
</script>
