<template>
  <div
    :class="{
      'flex justify-center items-center': !hasData,
    }"
  >
    <template v-if="resp">
      <template v-if="hasData">
        <div><slot :data="converted"></slot></div>
        <el-pagination
          v-if="!hidePager"
          class="m-t-10px"
          :class="paginationClass"
          :background="paginationBackground"
          :layout="paginationLayout"
          :total="total"
          :page-size="num"
          :current="page"
          @change="refresh"
        />
      </template>
      <template v-else>
        <slot name="empty">
          <div class="font-5 font-bold">暂无数据</div>
        </slot>
      </template>
    </template>
  </div>
</template>
<script generic="T extends AnySucceedPagedResp, R = T['data']['data']" setup lang="ts">
import { type PagedParams } from '@/api';
import type { AnySucceedPagedResp } from '@/schemas/response';
import { computed, ref } from 'vue';
const {
  handleRequest,
  num,
  hidePager = false,
  converter,
} = defineProps<{
  num: number;
  paginationClass?: string;
  paginationBackground?: boolean;
  paginationLayout?: string;
  hidePager?: boolean;
  handleRequest: (params: PagedParams) => Promise<T | undefined>;
  converter?: (raw: T['data']['data']) => R;
}>();
defineSlots<{
  default: (props: { data: R }) => unknown;
  empty: () => unknown;
}>();
const emit = defineEmits<{
  change: [data: R];
  loadComplete: [succeed: boolean];
}>();
const loading = ref(true);
const resp = ref<T>();
const hasData = computed(() => !!resp.value?.data.data.length);
const converted = computed(() => {
  const data = resp.value?.data.data;
  if (!data) return [] as R;
  return converter?.(data) ?? (data as R);
});
const page = ref(1);
const total = computed(() => resp.value?.data.total);
async function refresh() {
  loading.value = true;
  resp.value = await handleRequest({ page: page.value, num });
  emit('change', converted.value);
  emit('loadComplete', !!resp.value);
  loading.value = false;
  return !!resp.value;
}
defineExpose({ refresh });
refresh();
</script>
