import React, { useEffect } from 'react';
import { Box, Loader } from '@wix/design-system';
import { observer } from 'mobx-react-lite';
import { FiltersMap } from '@wix/bex-core';
import { CollectionTable, CollectionTableProps } from '../CollectionTable';
import { useTableSyncProps } from './useTableSyncProps';
import { TableProvider } from '../../providers';
import { getToolbarCollectionFeaturesInitializers } from '../../state/getToolbarCollectionFeaturesInitializers';
import { useTableBaseRow } from './useTableBaseRow';
import type { TableSectionsProp } from '../TableSections';

export interface TableBaseProps<T, F extends FiltersMap>
  extends CollectionTableProps<T, F> {
  rowHeight?: number | ((item: T, index: number) => number);
  estimatedRowHeight?: number;
  sections?: TableSectionsProp<T>;
}

function _TableBase<T, F extends FiltersMap = FiltersMap>(
  props: TableBaseProps<T, F>,
) {
  const { state, sections, useNewInfiniteScrollLoader, multiLevelSorting } =
    props;

  const internalScroll = state.toolbar.container.isPanelLayout
    ? true
    : props.internalScroll;

  const { table } = state;
  const { collection } = table;
  const {
    fetchedLastPage,
    query: { limit },
  } = collection;

  const { scrollElement } = useTableSyncProps(props);

  const TableBaseRow = useTableBaseRow(state);

  useEffect(() => {
    return state.init({
      featuresInitializers: [
        ...getToolbarCollectionFeaturesInitializers(props),
      ],
      hasMultiLevelSorting: multiLevelSorting !== undefined,
    });
  }, []);

  const infiniteScrollProps =
    useNewInfiniteScrollLoader || internalScroll
      ? {}
      : {
          infiniteScroll: true,
          loadMore: collection.fetchNextPageIfNeeded,
          hasMore: !fetchedLastPage,
          itemsPerPage: limit,
          loader: (
            <Box backgroundColor="D80" align="center" padding="large">
              <Loader dataHook="infinite-scroll-loader" />
            </Box>
          ),
        };

  const commonTableProps = {
    ...props,
    ...infiniteScrollProps,
    scrollElement,
    useNewInfiniteScrollLoader,
    initialLoad: false,
    state,
  };

  return (
    <TableProvider value={state}>
      {sections ? (
        <sections.TableSections
          {...commonTableProps}
          table={state}
          groupBy={sections.groupBy}
          renderSection={sections.renderSection}
          collapsible={sections.collapsible}
          events={sections.events}
        />
      ) : (
        <CollectionTable {...commonTableProps} TrElementType={TableBaseRow} />
      )}
    </TableProvider>
  );
}

export const TableBase = observer(_TableBase);
