import { FiltersMap } from '@wix/bex-core';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import React, { useCallback } from 'react';
import {
  AccordionProps,
  accordionSectionItemBuilder,
} from '@wix/design-system';
import { CollectionFilter } from '../components/CollectionFilter';
import { FilterElement } from '../components/CollectionToolbarFilters';
import { CollectionToolbarFiltersState } from '../components/CollectionToolbarFilters/CollectionToolbarFiltersState';
import { FilterAccordionTitle } from '../components/FiltersPanel/FilterAccordionTitle';

function useBuildAccordionItem<T, F extends FiltersMap>(
  state: CollectionToolbarFiltersState<T, F>,
) {
  return useCallback((filterElement: FilterElement) => {
    const { type: Component, props: filterProps } = filterElement;
    const { filter, initiallyOpen, popoverProps, accordionItemProps } =
      filterProps;

    const clonedElement = (
      <Component
        {...filterProps}
        popoverProps={{ appendTo: 'window', ...popoverProps }}
      />
    );

    return {
      title: (
        <FilterAccordionTitle
          state={state.toolbar}
          filter={filter}
          filterProps={filterProps}
        />
      ),
      children: filterProps.filter ? (
        <CollectionFilter filter={filterProps.filter} state={state}>
          {clonedElement}
        </CollectionFilter>
      ) : (
        clonedElement
      ),
      initiallyOpen,
      ...accordionItemProps,
    };
  }, []);
}

export function useBuildAccordionItems<T, F extends FiltersMap>(
  state: CollectionToolbarFiltersState<T, F>,
) {
  const { translate: t } = useWixPatternsContainer();
  const buildAccordionItem = useBuildAccordionItem(state);
  const { panelFilterElements } = state;

  const defaultSectionTitle = t('cairo.filtersPanel.sections.default.title');

  const { groups, defaultGroup } = panelFilterElements.reduce<{
    groups: Record<string, NonNullable<AccordionProps['items']>>;
    defaultGroup: NonNullable<AccordionProps['items']>;
  }>(
    (accumulator, item) => {
      const sectionTitle = item.props?.sectionTitle;

      if (!sectionTitle) {
        return {
          ...accumulator,
          defaultGroup: [...accumulator.defaultGroup, buildAccordionItem(item)],
        };
      }

      const groupItems = accumulator.groups[sectionTitle]
        ? [...accumulator.groups[sectionTitle], buildAccordionItem(item)]
        : [
            accordionSectionItemBuilder({ title: sectionTitle }),
            buildAccordionItem(item),
          ];

      return {
        ...accumulator,
        groups: {
          ...accumulator.groups,
          [sectionTitle]: groupItems,
        },
      };
    },
    {
      groups: {},
      defaultGroup: [],
    },
  );

  const items = Object.values(groups).flat();

  if (!items.length) {
    return defaultGroup;
  }

  return [
    ...items,
    ...(defaultGroup.length
      ? [
          accordionSectionItemBuilder({ title: defaultSectionTitle }),
          ...defaultGroup,
        ]
      : []),
  ];
}
