import { AddItemProps } from '@wix/design-system';
import React, { ReactElement, useEffect } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { ToolbarCollectionContentAutoSizer } from '../ToolbarCollectionContentAutoSizer';
import { observer } from 'mobx-react-lite';
import { GridFoldersState } from '../../state';
import { ActionCell } from '../ActionCell';
import { SupportedCardGalleryItemProps } from './SupportedCardGalleryItemProps';
import { useGridBaseSyncProps } from './useGridBaseSyncProps';
import { getToolbarCollectionFeaturesInitializers } from '../../state/getToolbarCollectionFeaturesInitializers';
import { GridFoldersSectionsGroup } from './GridFoldersSectionsGroup';
import { GridFoldersPresetProps } from './GridFolders.types';
import { GridItemBaseProps } from './GridItemBaseProps';
import { CollectionCard } from '../CollectionCard';
import {
  ToolbarCollection,
  ToolbarCollectionBaseProps,
} from '../ToolbarCollection';
import { GridFoldersPlaceholderStates } from './GridFoldersPlaceholderStates';
import { PartialAllFilters } from '../../state/FoldersAndItemsCollectionsState';
import { minimalRequiredWdsRuntimeCheck } from '../../minimalRequiredWdsRuntimeCheck';
import { useToolbarCollectionSyncProps } from '../ToolbarCollection/useToolbarCollectionSyncProps';

export interface GridFoldersBaseProps<
  T1,
  F1 extends FiltersMap,
  T2,
  F2 extends FiltersMap,
> extends Omit<
      ToolbarCollectionBaseProps<T1, PartialAllFilters<F1, F2>>,
      'topNotification'
    >,
    GridItemBaseProps<T1, F1> {
  dataHook?: string;
  /** A GridFoldersState instance created using [useGridFolders](./?path=/story/base-components-collections-gridfolders-usegridfolders--usegridfolders). */
  state: GridFoldersState<T1, F1, T2, F2>;
  /** Optional custom title for the items section */
  itemsSectionTitle?: string;
  foldersSectionTitle?: string;
  /** Same as `renderItem`, but for a folder item. */
  renderFolderItem?: (
    item: T2,
    index: number,
  ) => Partial<SupportedCardGalleryItemProps>;
  /** Same as `preset` but for a folder item */
  folderPreset?: 'full' | 'title';
  /** Same as `actionCell`, but for a folder item. */
  folderActionCell?: ActionCell<T2, F2>;
  /** Same as `renderAddItem`, but for a folder item. */
  renderFolderAddItem?: () => ReactElement<AddItemProps>;
  topNotification?: ReactElement;
}

export type GridFoldersBasePropsWithoutPreset<
  T1,
  F1 extends FiltersMap,
  T2,
  F2 extends FiltersMap,
> = Omit<
  GridFoldersBaseProps<T1, F1, T2, F2>,
  'preset' | 'folderPreset' | 'renderItem' | 'renderFolderItem'
>;

export type GridFoldersProps<
  T1,
  F1 extends FiltersMap,
  T2,
  F2 extends FiltersMap,
> = GridFoldersPresetProps<
  T1,
  T2,
  GridFoldersBasePropsWithoutPreset<T1, F1, T2, F2>
>;

function _GridFolders<T1, F1 extends FiltersMap, T2, F2 extends FiltersMap>(
  props: GridFoldersProps<T1, F1, T2, F2>,
) {
  const {
    state,
    exportModal,
    dataHook,
    cardProps,
    emptyState,
    noResultsState,
    renderError,
    errorState = renderError &&
      (((err, { isOnline, retry }) =>
        renderError?.({ err, isOnline, retry })) as GridFoldersProps<
        T1,
        F1,
        T2,
        F2
      >['errorState']),
  } = props;

  const { toolbar } = state;

  if (process.env.NODE_ENV !== 'production') {
    // https://github.com/wix-private/wix-design-systems/pull/13091/files#diff-0befb17e7fa12b244a3efce19b067187b39d3a96d4f7e62a59f4f0fd876dc37cR102
    minimalRequiredWdsRuntimeCheck({
      required: '^1.89.0',
      requiredBy: 'WixPatterns/GridFolders',
    });
  }

  useToolbarCollectionSyncProps({
    ...props,
    state: state.toolbar,
    isUsingDragAndDrop: false,
    isUsingBulkActionsToolbar: false,
    isUsingHorizontalScroll: false,
    isUsingFolders: true,
    isUsingTableVirtualization: false,
  });

  useGridBaseSyncProps({ ...props, state: state.items });
  useGridBaseSyncProps({
    ...props,
    renderAddItem: props.renderFolderAddItem,
    state: state.folders,
  });

  useEffect(
    () =>
      state.init({
        featuresInitializers: getToolbarCollectionFeaturesInitializers(props),
      }),
    [],
  );

  return (
    <CollectionCard
      errorState={false}
      state={toolbar}
      dataHook={dataHook}
      {...cardProps}
    >
      <ToolbarCollection {...props} state={toolbar}>
        <GridFoldersPlaceholderStates
          state={state}
          emptyState={emptyState}
          noResultsState={noResultsState}
          errorState={errorState}
        >
          <ToolbarCollectionContentAutoSizer>
            <GridFoldersSectionsGroup {...props} />
          </ToolbarCollectionContentAutoSizer>
        </GridFoldersPlaceholderStates>
      </ToolbarCollection>
      {exportModal ?? toolbar.featuredComponents.exportModal.value}
    </CollectionCard>
  );
}

export const GridFolders = observer(_GridFolders);
