import { throttle } from "lodash";
import {
  computed,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  Ref,
  watch,
} from "vue";
import Table from "./index.vue";

/**
 * 表格数据钩子，输入数据请求函数，页数。
 * 返回响应式的表格数据，加载下一页数据函数，刷新函数，相应式的表示是否加载中boolean值
 */
export function useTableData<T = any>({
  page_size = 20,
  fetchData,
}: {
  page_size?: number;
  fetchData: (fetchDataConfig: {
    page: number;
    page_size: number;
  }) => Promise<{ total: number; data: T[] }>;
}) {
  const loading = ref(true);
  const tableState = reactive({
    page: 1,
    page_size: page_size,
    list: [] as T[],
    total: 0,
    // loading: true,
    lock: false,
    firstFetch: true,
  }) as unknown as {
    page: number;
    page_size: number;
    list: T[];
    total: number;
    loading: boolean;
    lock: boolean;
    firstFetch: boolean;
  };

  handleFetch(true);

  async function handleFetch(firstFetch: boolean) {
    if (firstFetch) {
      tableState.page = 1;
    }
    // tableState.loading = true;
    loading.value = true;
    return fetchData({
      page: tableState.page,
      page_size: tableState.page_size,
    }).then((ret) => {
      tableState.total = ret.total;
      const httpResData = ret.data || [];
      if (firstFetch) {
        tableState.list = httpResData;
      } else {
        tableState.list = [...tableState.list, ...httpResData];
      }
      // tableState.loading = false;
      loading.value = false;
      tableState.lock = false;
      if (tableState.firstFetch) tableState.firstFetch = false;
    });
  }

  watch(
    () => [tableState.page],
    () => {
      if (tableState.page !== 1) handleFetch(tableState.firstFetch);
    }
  );

  const fetchNextPage = () => {
    if (tableState.lock) return;
    tableState.lock = true;
    if (tableState.page * tableState.page_size < tableState.total) {
      tableState.page++;
    }
  };

  return {
    /** 表格数据 */
    tableData: computed(() => {
      return tableState.list;
    }),
    /** 获取下一页 */
    fetchNextPage,
    /** 刷新 */
    refetch: () => handleFetch(true),
    loading: loading,
  };
}

/**
 *
 * @param tableRef 表格组件引用
 * @param handleScrollToEnd 滚动到底部调用函数
 */
export const useTableScrollListener = (
  tableRef: Ref<InstanceType<typeof Table> | undefined>,
  handleScrollToEnd: (scrollTop: number) => any
) => {
  onMounted(() => {
    const tableEl = tableRef.value?.getEl() as HTMLDivElement;
    const wrap = tableEl.querySelector(".el-scrollbar__wrap") as HTMLDivElement;

    wrap.onscroll = throttle(() => {
      // console.log({
      //   clientHeight: wrap.clientHeight,
      //   scrollTop: wrap.scrollTop,
      //   scrollHeight: wrap.scrollHeight,
      // });

      if (wrap.clientHeight === wrap.scrollHeight) {
        // 若clientHeight和scrollHeight相等，内容高度等于容器高度，无法滚动
        return;
      }

      if (wrap.offsetHeight + wrap.scrollTop + 100 >= wrap.scrollHeight) {
        handleScrollToEnd(wrap.scrollTop);
      }
    }, 100);
  });
  onBeforeUnmount(() => {
    const tableEl = tableRef.value?.getEl() as HTMLDivElement;
    const wrap = tableEl.querySelector(".el-scrollbar__wrap") as HTMLDivElement;
    wrap.onscroll = null;
  });
};
