import { onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
import { ref, type Ref } from "vue";
import type { ILoaderCommon, LoaderLoadType } from "./LoaderCommon";
import { formatError } from "./ErrorDisplay";

export interface ISimplePageListLoader<T, P> extends ILoaderCommon<P> {
  list: Ref<T[]>;
  page: Ref<number>;
  total: Ref<number>;
}

export function useSimplePageListLoader<T, P = any>(
  pageSize: number, 
  loader: (page: number, pageSize: number, params?: P) => Promise<{ list: T[], total: number }>,
  showGlobalLoading = false,
)  : ISimplePageListLoader<T, P>
{
  
  const loadStatus = ref<LoaderLoadType>('loading');
  const loadError = ref('');
  const page = ref(0);
  const total = ref(0);
  const list = ref<T[]>([]) as Ref<T[]>;

  let lastParams: P | undefined;
  let loading = false;

  async function loadData(params?: P, refresh: boolean = false) {
    if (loading) 
      return;
    if (params)
      lastParams = params;
    if (refresh) {
      page.value = 0;
      list.value = []; 
    }
    page.value++;
    loadStatus.value = 'loading';
    loading = true;
    if (showGlobalLoading)
      uni.showLoading({ title: '加载中...' });

    try {
      const res = (await loader(page.value, pageSize, lastParams));
      list.value = list.value.concat(res.list as T[]);
      total.value = res.total;
      loadStatus.value = res.list.length > 0 ? 'finished' : 'nomore';
      loadError.value = '';
      loading = false;
    } catch(e) {
      console.log(e);
      loadError.value = formatError(e);
      loadStatus.value = 'error';
      loading = false;
    } finally {
      if (showGlobalLoading)
        uni.hideLoading();
    }
  }

  onPullDownRefresh(() => {
    loadData(lastParams, true).then(() => {
      uni.stopPullDownRefresh();
    }).catch(() => {
      uni.stopPullDownRefresh();
    });
  });
  onReachBottom(() => {
    if (loadStatus.value == 'nomore')
      return;
    loadData(lastParams, false);
  });

  return {
    list,
    total,
    page,
    loadStatus,
    loadError,
    loadData,
  }
}