import {
  listItemSectionBuilder,
  listItemSelectBuilder,
} from '@wix/design-system';
import { ArrayField, KeyedItem } from '@wix/bex-core';
import { ListItem } from './listItem';
import { useCallback, useMemo } from 'react';
import { DropdownLayoutOption } from '@wix/design-system/dist/types/DropdownLayout';

export function useBuildOption<V>({
  filter,
  checkbox,
  renderItem,
}: {
  filter: ArrayField<V>;
  renderItem?: (item: V, index: number) => ListItem;
  checkbox?: boolean;
}) {
  return useCallback(
    (keyedItem: KeyedItem<V>, index: number) => {
      const { key, item } = keyedItem;
      const option = renderItem?.(item, index);

      const title = filter.itemName(item);

      return Object.assign(
        listItemSelectBuilder({
          id: key,
          checkbox,
          ellipsis: true,
          title: filter.itemName(item),
          label: title,
          ...option,
        }),
        {
          sectionId: option?.sectionId,
          keyedItem,
        },
      );
    },
    [renderItem, checkbox],
  );
}

type DropdownLayoutOptionWithSectionId = DropdownLayoutOption & {
  sectionId?: string;
};

export interface BuildSectionOptionsArgs {
  readonly items: DropdownLayoutOptionWithSectionId[];
  readonly renderSection?: (
    sectionId: string,
  ) => Parameters<typeof listItemSectionBuilder>[0];
}

export function useBuildGroupedOptions({
  items,
  renderSection,
}: BuildSectionOptionsArgs) {
  return useMemo(() => {
    if (!renderSection) {
      return items;
    }

    const { groups } = items.reduce(
      (acc, option) => {
        const sectionId = option.sectionId || '';

        let group;

        if (acc._cache[sectionId]) {
          group = acc._cache[sectionId];
        } else {
          group = [
            listItemSectionBuilder(renderSection(sectionId)),
          ] as DropdownLayoutOption[];
          acc.groups.push(group);
          acc._cache[sectionId] = group;
        }

        group.push(option);

        return acc;
      },
      {
        _cache: {} as Record<string, DropdownLayoutOption[]>,
        groups: [] as DropdownLayoutOption[][],
      },
    );

    return groups.flatMap((e) => e);
  }, [items, renderSection]);
}
