import { nextTick, ref } from "vue";
import { getDataType } from "@/assets/js/utils.js";

/**
 * @param api {Function} 接口函数
 * @param options {Object?: {callbackFn, otherParams, immediate, usePagination, key}} 配置项
 * @param options.callbackFn {Function?} 回调函数（返回值【第一个参数表格数据，第二个参数后台返回的所有数据】）
 * @param options.otherParams {Object?} 其它接口参数
 * @param options.immediate {Boolean?} 是否立即执行接口函数（默认是）
 * @param options.usePagination {Boolean?} 是否使用分页（默认是）
 * @param options.key {String?} 返回的存放数组的key（默认varList）
 * @return {Object} 返回对象包含以下属性：list 表格数据，pagination 分页数据，searchForm 搜索表单数据，tableRef 表格实例，responseData 后台所有返回值，fnGetData 获取数据函数，fnResetPagination 重置分页函数
 */

export default function useListData(api, options = {}) {
  if (getDataType(api) !== "Function") throw new Error("api必须是一个函数");
  if (getDataType(options) !== "Object")
    throw new Error("options必须是一个对象");
  if (options.immediate && getDataType(options.immediate) !== "Boolean")
    throw new Error("options.immediate必须是一个布尔值");
  if (options.usePagination && getDataType(options.usePagination) !== "Boolean")
    throw new Error("options.usePagination必须是一个布尔值");
  if (options.key && getDataType(options.key) !== "String")
    throw new Error("options.key必须是一个字符串");
  const immediate = options.immediate ?? true;
  const usePagination = options.usePagination ?? true;
  const key = options.key ?? "varList";
  if (!immediate && options.otherParams)
    throw new Error("options.otherParams只有在immediate为true时才有效");
  if (
    immediate &&
    options.otherParams &&
    getDataType(options.otherParams) !== "Object"
  )
    throw new Error("options.otherParams必须是一个对象");
  if (options.callbackFn && getDataType(options.callbackFn) !== "Function")
    throw new Error("options.callbackFn必须是一个函数");
  const responseData = ref({});
  const list = ref([]);
  const pagination = ref({
    currentPage: 1,
    pageSize: 10,
    total: 0,
  });
  const searchForm = ref({});
  const tableRef = ref(null);
  const fnGetData = async (otherParams = {}) => {
    const resData = await api({
      ...(usePagination
        ? {
            currentPage: pagination.value.currentPage,
            showCount: pagination.value.pageSize,
          }
        : {}),
      ...searchForm.value,
      ...(options.otherParams || {}),
      ...(getDataType(otherParams) === "Object" ? otherParams : {}),
    });
    list.value = resData[key];
    pagination.value.total = resData.page.totalResult;
    responseData.value = resData;
    options.callbackFn && options.callbackFn(list.value, resData);
  };
  immediate && fnGetData().then();
  const fnResetPagination = async (otherParams) => {
    list.value = [];
    pagination.value = {
      currentPage: 1,
      pageSize: 10,
      total: 0,
    };
    await nextTick();
    await fnGetData(otherParams);
    tableRef.value && tableRef.value.clearSelection();
  };
  return {
    list,
    pagination,
    searchForm,
    tableRef,
    responseData,
    fnGetData: async (otherParams) => await fnGetData(otherParams),
    fnResetPagination: async (otherParams) =>
      await fnResetPagination(otherParams),
  };
}
