import {
  Accordion,
  Box,
  SidePanel,
  SidePanelProps,
  WixStyleReactDefaultsOverrideProvider,
} from '@wix/design-system';
import React, { useState } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { observer } from 'mobx-react-lite';
import { useBuildAccordionItems } from '../../hooks/useBuildAccordionItems';
import { FiltersPanelFooter } from './FiltersPanelFooter';
import { FilterRenderingContextProvider } from '../FilterRenderingContext';
import { FiltersPanelState } from './FiltersPanelState';
import { FiltersPanelSearch } from './FiltersPanelSearch';
import { FiltersPanelSearchNoResults } from './FiltersPanelSearchNoResults';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { useRafRender } from '../../hooks/useRafRender';
import { CollectionToolbarFiltersState } from '../CollectionToolbarFilters/CollectionToolbarFiltersState';
import { PatternsSidePanel } from '../SidePanel/PatternsSidePanel';

const FILTER_SEARCH_THRESHOLD = 7;

export interface FiltersPanelProps<T, F extends FiltersMap>
  extends Partial<SidePanelProps> {
  state: CollectionToolbarFiltersState<T, F>;
}

function _FiltersPanel<T, F extends FiltersMap>(
  props: FiltersPanelProps<T, F>,
) {
  const { state, children, ...rest } = props;

  const {
    toolbar,
    totalInlineFilters: { value: totalInlineFilters },
  } = state;

  const entered = useRafRender();

  const { translate: t } = useWixPatternsContainer();

  const [filtersPanelState] = useState(
    () =>
      new FiltersPanelState({
        toolbar,
      }),
  );

  const showSearch = state.panelFilterElements.length > FILTER_SEARCH_THRESHOLD;

  const accordionItems = useBuildAccordionItems(
    state,
    showSearch ? filtersPanelState.searchValue : '',
  );

  const hasActiveSearch =
    showSearch && filtersPanelState.searchValue.trim().length > 0;
  const noResults = hasActiveSearch && accordionItems.length === 0;

  const [filterRenderingContext] = useState(() => ({
    location: 'panel' as const,
  }));

  const [wsrDefaults] = useState(() => ({
    input: {
      size: 'small' as const,
    },
    button: {
      size: 'small' as const,
    },
  }));

  if (!entered) {
    return null;
  }

  let child = (
    <PatternsSidePanel
      dataHook="filters-side-panel"
      onClose={filtersPanelState.onCloseButtonClick}
      width="100%"
      closeButtonProps={{
        ariaLabel: t('cairo.filtersPanel.header.closeButton.ariaLabel'),
      }}
      {...rest}
    >
      <SidePanel.Header
        title={
          state.panelTitle.value ??
          (totalInlineFilters != null
            ? t('cairo.filtersPanel.header', {
                num: totalInlineFilters,
              })
            : undefined)
        }
      >
        {showSearch && (
          <Box padding="0 SP2 SP2 SP2">
            <FiltersPanelSearch state={filtersPanelState} />
          </Box>
        )}
      </SidePanel.Header>

      <div
        data-hook="filters-panel-scroll-container"
        style={{ overflowY: 'auto' }}
      >
        {noResults ? (
          <FiltersPanelSearchNoResults state={filtersPanelState} />
        ) : (
          <Accordion
            dataHook="filters-panel-accordion"
            skin="light"
            hideShadow
            multiple
            items={accordionItems}
          />
        )}
      </div>
      <SidePanel.Footer noPadding>
        <FiltersPanelFooter
          state={toolbar}
          onClearButtonClicked={state.onClearButtonClicked}
        />
      </SidePanel.Footer>
      {children}
    </PatternsSidePanel>
  );

  child = (
    <FilterRenderingContextProvider value={filterRenderingContext}>
      {child}
    </FilterRenderingContextProvider>
  );

  child = (
    <WixStyleReactDefaultsOverrideProvider value={wsrDefaults}>
      {child}
    </WixStyleReactDefaultsOverrideProvider>
  );

  return child;
}

export const FiltersPanel = observer(_FiltersPanel);
