<template>
  <div class="table-pro-content">
    <n-card
      v-if="props.searchFormOptions"
      class="searchForm"
      size="small"
    >
      <n-collapse>
        <n-collapse-item
          title="搜索表单"
          name="searchForm"
          style="user-select: none"
        >
          <FormPro
            ref="searchFormInst"
            v-model:value="searchFormParams"
            v-bind="props.searchFormProps"
            :form-item-options="props.searchFormOptions"
          />
          <template #header-extra>
            <n-space>
              <n-button
                strong
                secondary
                type="primary"
                @click.stop="search"
              >
                搜索
              </n-button>
              <n-button
                strong
                secondary
                type="warning"
                @click.stop="resetFormAndTable"
              >
                重置
              </n-button>
            </n-space>
          </template>
        </n-collapse-item>
      </n-collapse>
    </n-card>
    <n-alert
      v-show="!isEmpty(selectKeys)"
      size="small"
      class="margin-top"
      type="info"
    >
      <template #header>
        <n-space>
          当前选中了{{ selectKeys.length }}条
          <n-button
            text
            type="info"
            @click="clearSelect"
          >
            清空
          </n-button>
          <n-button
            text
            type="success"
            @click="selectDetail"
          >
            详情
          </n-button>
          <slot
            name="selectionExtra"
            :selectKeys="selectKeys"
            :selectRows="selectRows"
          ></slot>
        </n-space>
      </template>
    </n-alert>
    <n-card
      class="dataTable margin-top"
      :title="props.tableTitle"
      size="small"
    >
      <template #header-extra>
        <n-space>
          <slot name="headerExtra"></slot>
          <n-button
            v-if="!props.searchFormOptions"
            circle
            @click="search"
          >
            <template #icon>
              <Icon name="MaterialSymbolsSync" />
            </template>
          </n-button>
        </n-space>
      </template>
      <n-data-table
        ref="dataTableInst"
        v-bind="{ ...props, pagination: paginationProps }"
        :rowKey="rk"
        :data="datasource"
        :loading="loading"
        :checkedRowKeys="selectKeys"
        @update:checked-row-keys="onSelectRowKeysChange"
      ></n-data-table>
    </n-card>
  </div>
</template>

<script setup lang="tsx">
  import type { FormModelValue, FormProInst } from "@/components";
  import { tableProProps } from "./TablePro";
  import { computed, onMounted, ref, useTemplateRef } from "vue";
  import useTablePro from "./hooks/useTablePro";
  import { FormPro } from "@/components";
  import type { DataTableInst, PaginationProps } from "naive-ui";
  import type { TableProInst, TableProSlots } from "./interface";
  import { isEmpty } from "lodash-es";
  import useSelection from "./hooks/useSelection";
  import type { CreateRowKey } from "naive-ui/es/data-table/src/interface";
  import { Icon } from "@/components";

  const props = defineProps(tableProProps);

  const slots = defineSlots<TableProSlots>();

  const rk: CreateRowKey<any> = (row) => row[props.rowKey];

  const dataTableInst = useTemplateRef<DataTableInst>("dataTableInst");
  const searchFormInst = useTemplateRef<FormProInst>("searchFormInst");
  const searchFormParams = ref<FormModelValue>({});

  const {
    loading,
    datasource,
    page,
    search,
    requestGetTableData,
    handleSizeChange,
    handleCurrentChange,
    resetState,
  } = useTablePro(
    props.requestApi,
    searchFormInst,
    searchFormParams,
    props.isPageTable,
    props.dataCallback,
    props.requestError
  );

  const {
    selectKeys,
    selectRows,
    onSelectRowKeysChange,
    clearSelect,
    selectDetail,
  } = useSelection(props.rowKey, datasource);

  /**
   * 重置表单并查询
   */
  const resetFormAndTable = () => {
    Object.keys(searchFormParams.value).forEach((k) => {
      searchFormParams.value[k] = null;
    });
    searchFormInst.value?.restoreValidation();
    clearSelect();
    resetState();
    requestGetTableData();
  };

  const paginationProps = computed<PaginationProps | false>(() => {
    if (!props.isPageTable) {
      //如果不是分页表格也想实现伪分页 请设置remote = false 然后维护pagination状态
      if (props.pagination) {
        return props.pagination;
      }
      return false;
    }
    return {
      page: page.value.current,
      pageSize: page.value.size,
      itemCount: page.value.total,
      showSizePicker: true,
      pageSizes: [10, 30, 50, 70, 100],
      showQuickJumper: true,
      onUpdatePage: handleCurrentChange,
      onUpdatePageSize: handleSizeChange,
      suffix: ({ itemCount }) => `共${itemCount}条`,
      //当表格为异步分页表格时 上述配置是ok的 当表格为非异步分页表格时 如果需要进行分页 请自行配置相关分页属性 并设置remote为false
      ...props.pagination,
    };
  });

  onMounted(() => props.requestAuto && requestGetTableData(true));

  defineExpose<TableProInst>({
    clearFilters: () => dataTableInst.value?.clearFilters(),
    clearSorter: () => dataTableInst.value?.clearSorter(),
    downloadCsv: (options) => dataTableInst.value?.downloadCsv(options),
    filters: (filters) => dataTableInst.value?.filters(filters),
    page: (page) => dataTableInst.value?.page(page),
    scrollTo: (options) => dataTableInst.value?.scrollTo(options as any),
    sort: (columnKey, order) => dataTableInst.value?.sort(columnKey, order),
    searchParams: searchFormParams,
    requestGetTableData: requestGetTableData,
    resetTable: resetFormAndTable,
    selectKeys: selectKeys as any,
    selectRows: selectRows as any,
    clearSelect,
  });
</script>

<style scoped></style>
