import { Box, Page, Table } from '@wix/design-system';
import React, { FunctionComponent, ReactNode } from 'react';
import { ToolbarCollectionState } from '../../state';
import { observer } from 'mobx-react-lite';
import { CollectionToolbar } from '../CollectionToolbar';
import { FiltersMap } from '@wix/bex-core';
import { PartialFunctionComponent } from '../PartialFunctionComponent';
import { CollectionToolbarsProvider } from './CollectionToolbarsProvider';
import { ToolbarAndTitlebarContainer } from './ToolbarAndTitlebarContainer';
import { ToolbarCollectionBaseProps } from '../ToolbarCollection';
import { TopNotificationBasicRenderProp } from '../TableTopNotification';
import { useIsMobile } from '../../hooks/useIsMobile';
import {
  CollectionToolbarsVisualization,
  CollectionToolbarsVisualizationProps,
} from './CollectionToolbarsVisualization';
import { useIsCollectionToolbarExists } from '../CollectionToolbar/useIsCollectionToolbarExists';

export interface CollectionToolbarsProps<T, F extends FiltersMap>
  extends Pick<
    ToolbarCollectionBaseProps<T, F>,
    | 'showTitleBar'
    | 'tags'
    | 'sticky'
    | 'title'
    | 'tabs'
    | 'search'
    | 'customColumns'
    | 'multiLevelSorting'
    | 'views'
    | 'filters'
    | 'selectionToolbar'
    | 'dragAndDropReorderModeToolbar'
    | 'extraToolbar'
    | 'summaryBar'
    | 'tableGridSwitchButton'
    | 'exportButton'
    | 'importButton'
    | 'primaryActionButton'
    | 'secondaryActions'
    | 'moreActions'
  > {
  state: ToolbarCollectionState<T, F>;
  topNotification?: TopNotificationBasicRenderProp;
  titleBar?: ReactNode;
  visualization?: CollectionToolbarsVisualizationProps<T, F>['visualization'];
}

function BorderRadiusTopCard({ children }: { children?: ReactNode }) {
  const isMobile = useIsMobile();
  return (
    <Box
      direction="vertical"
      backgroundColor="D80"
      borderTopLeftRadius={isMobile ? 0 : 8}
      borderTopRightRadius={isMobile ? 0 : 8}
    >
      {children}
    </Box>
  );
}

function BorderRadiusTopBottomCard({ children }: { children?: ReactNode }) {
  const isMobile = useIsMobile();
  return (
    <Box
      direction="vertical"
      backgroundColor="D80"
      borderRadius={isMobile ? 0 : 8}
    >
      {children}
    </Box>
  );
}

function _CollectionToolbars<T, F extends FiltersMap = FiltersMap>(
  props: CollectionToolbarsProps<T, F>,
) {
  const {
    sticky,
    state,
    selectionToolbar,
    extraToolbar,
    summaryBar,
    topNotification: topNotificationProp,
    titleBar,
    visualization: customSlot,
  } = props;

  const {
    collection,
    featuredComponents,
    hasSubToolbarComponents,
    shouldDisplayFiltersTags,
    bulk: { selectedIds },
    internalScroll,
    container: { isPanelLayout },
  } = state;

  const isMobile = useIsMobile();

  const topNotification = isPanelLayout
    ? undefined
    : typeof topNotificationProp === 'function'
    ? topNotificationProp()
    : topNotificationProp;

  const AppliedFiltersTagList = featuredComponents.appliedFiltersTagList.value
    ?.component as PartialFunctionComponent as FunctionComponent | null;

  const { showRefreshLoader } = collection;

  const shouldDisplaySubToolbar =
    shouldDisplayFiltersTags && hasSubToolbarComponents;

  const shouldRenderCollectionToolbar = useIsCollectionToolbarExists(props);

  const toolbars = (
    <>
      {selectionToolbar && !showRefreshLoader && selectedIds.length > 0 ? (
        selectionToolbar
      ) : (
        <>
          {extraToolbar}
          {(!isMobile || shouldRenderCollectionToolbar) && (
            <CollectionToolbar {...props} dataHook="collection-toolbar" />
          )}
        </>
      )}
      {shouldDisplaySubToolbar && (
        <Box direction="vertical" backgroundColor="D80">
          <Table.SubToolbar dataHook="collection-table-sub-toolbar">
            {AppliedFiltersTagList && shouldDisplayFiltersTags && (
              <AppliedFiltersTagList />
            )}
          </Table.SubToolbar>
        </Box>
      )}
      {summaryBar}
      {topNotification}
    </>
  );

  /* wrapping with Card is WSR way to make the sticky table header not to add extra border between the header and the content https://www.docs.wixdesignsystem.com/?path=/story/components-lists-table--table#Sticky_Toolbar_&_Sub-toolbar*/

  const child = (
    <ToolbarAndTitlebarContainer state={state.toolbar}>
      {customSlot ? (
        <>
          <BorderRadiusTopBottomCard>{toolbars}</BorderRadiusTopBottomCard>
          <CollectionToolbarsVisualization
            state={state}
            visualization={customSlot}
          />
          <BorderRadiusTopCard>{titleBar}</BorderRadiusTopCard>
        </>
      ) : (
        <BorderRadiusTopCard>
          {toolbars}
          {titleBar}
        </BorderRadiusTopCard>
      )}
    </ToolbarAndTitlebarContainer>
  );

  return (
    <CollectionToolbarsProvider>
      {sticky && !internalScroll ? (
        <Page.Sticky style={isMobile ? { top: 78 } : undefined}>
          {child}
        </Page.Sticky>
      ) : (
        child
      )}
    </CollectionToolbarsProvider>
  );
}

export const CollectionToolbars = observer(_CollectionToolbars);
