import React, { ReactElement, ReactNode } from 'react';
import { TableProvider } from '../../providers';
import { CollectionCard } from '../CollectionCard';
import { NestedTableState } from '../../state';
import { ToolbarBaseProps } from '../ToolbarCollection';
import { NestedTableWSRTable } from './NestedTableWSRTable';
import { observer } from 'mobx-react-lite';
import { minimalRequiredWdsRuntimeCheck } from '../../minimalRequiredWdsRuntimeCheck';
import { NestedTableDragAndDrop } from '../NestedTableDragAndDrop/NestedTableDragAndDrop';
import { DragAndDropCategoriesProps } from '../DragAndDrop/DragAndDropCategoriesProps';
import {
  CollectionToolbarFiltersElement,
  TabsFilterElement,
} from '../assertComponentType';
import { TagsElement } from '../Tags';
import { TabsFilterProps } from '../TabsFilter';

export interface NestedTableProps<C extends string>
  extends ToolbarBaseProps,
    DragAndDropCategoriesProps<{}> {
  /**
   * A state object created with [`useNestedTable`](./?path=/story/base-components-collections-nestedtable--usenestedtable)
   * @overrideType [NestedTableState](./?path=/story/base-components-collections-nestedtable--nestedtablestate)
   */
  state: NestedTableState<C>;
  /**
   * A function that renders when there's an error fetching data from the server.<br> <br>
   * Supported parameters: <br>
   * - `err`: [object] The error thrown by the [`fetchData()`](./?path=/story/common-hooks--usecollection) function. <br>
   * - `isOnline`: [bool] Whether internet connection is available. <br>
   * - `retry`: [func] Retry collection fetch on failed response. Similar to `collection.retryFetch`.
   * @deprecated Use `errorState` instead.
   */
  renderError?: (params: {
    err: unknown;
    isOnline: boolean;
    retry: () => void;
  }) => ReactElement;
  /**
   * A function that renders when there's an error fetching data from the server.<br> <br>
   * Supported parameters: <br>
   * - `err`: [object] The error thrown by the [`fetchData()`](./?path=/story/common-hooks--usecollection) function. <br>
   * - `isOnline`: [bool] Whether internet connection is available. <br>
   * - `retry`: [func] Retry collection fetch on failed response. Similar to `collection.retryFetch`.
   */
  errorState?: (
    err: unknown,
    params: {
      isOnline: boolean;
      retry: () => void;
    },
  ) => ReactElement;
  /**
   * Shown when the collection is empty.
   * Pass either a [`<CollectionEmptyState />`](./?path=/story/features-display-empty-states--collectionemptystate)
   * or [`<CollectionPremiuimEmptyState />`](./?path=/story/features-display-empty-states--collectionpremiumemptystate) component.
   */
  emptyState?: ReactNode;

  /**
   * Shown when a search or filter has no results.
   * Accepts a [`CollectionNoResultsState`](./?path=/story/features-display-empty-states--collectionnoresultsstate) component.
   */
  noResultsState?: ReactNode;
  /**
   * Indicates whether the table should have horizontal scrolling.
   * Defining column widths as percentages is not supported with horizontal scrolling.
   */
  horizontalScroll?: boolean;
  dataHook?: string;
  rowHeight?: number;
  estimatedRowHeight?: number;
  /**
   *  Width of the column containing the `actionCell` component.
   */
  actionCellWidth?: string | number;

  /**
   * Adds functionality to allow visitors to reorder items manually.
   * This prop accepts a [Drag and Drop](./?path=/story/features-sort-drag-and-drop--overview) component.
   */
  dragAndDrop?: typeof NestedTableDragAndDrop;

  /**
   * Indicates whether the table should have an internal scroll (instead of the default page scroll)
   */
  internalScroll?: boolean;

  /**
   * Renders a notification below the header. Accepts a [`TableTopNotification`](./?path=/story/features-display-tabletopnotification--tabletopnotification) component.
   * @overrideType [TableTopNotification](./?path=/story/features-display-tabletopnotification--tabletopnotification)
   */
  topNotification?: ReactElement;

  /**
   * Adds filters to the toolbar and/or a sliding panel.
   * Accepts a `ToolbarFilters` component, which must have the `panelTitle` prop defined.
   * @overrideType [ToolbarFilters](./?path=%2Fstory%2Ffeatures-filter-components--toolbarfilters)
   * @external
   */
  filters?: CollectionToolbarFiltersElement;
  /**
   * Display a summary bar below the toolbar.
   * Accepts a [`SummaryBar`](./?path=/story/features-display-toolbar--summarybar) component.
   * @overrideType [SummaryBar](./?path=/story/features-display-toolbar--summarybar)
   * @external
   */
  summaryBar?: ReactNode;
  /**
   * Enables tags feature. In this element you can pass the configuration
   * @overrideType [TagsElement](./?path=/story/features-enrich-tags--tags)
   */
  tags?: TagsElement<C, any>;

  tabs?: TabsFilterElement<TabsFilterProps<any>>;
}

function _NestedTable<C extends string>(props: NestedTableProps<C>) {
  const { state, dataHook } = props;

  const { toolbar } = state;

  if (process.env.NODE_ENV !== 'production') {
    minimalRequiredWdsRuntimeCheck({
      required: '^1.64.1',
      requiredBy: 'WixPatterns/NestedTable',
    });
  }

  return (
    <CollectionCard errorState={false} state={toolbar} dataHook={dataHook}>
      <TableProvider value={state.tableState}>
        <NestedTableWSRTable {...props} />
      </TableProvider>
    </CollectionCard>
  );
}

export const NestedTable = observer(_NestedTable);
