import {
  DropdownLayoutOption,
  DropdownLayoutValueOption,
  InputSize,
  MultiSelect,
  MultiSelectProps,
  MultiSelectTag,
  TagProps,
  TagSize,
} from '@wix/design-system';
import React from 'react';
import { observer } from 'mobx-react-lite';
import { Filter, KeyedItem } from '@wix/bex-core';
import { DropdownSelectState } from '../../state';
import { FilterProps } from '../../model';
import { useFilterRenderingContext } from '../FilterRenderingContext';
import { useWindowFlipPopoverProps } from '../../utils/useWindowFlipPopoverProps';
import { useDropdownTranslationContext } from '../../providers';

export type KeyedItemOption<T> = DropdownLayoutValueOption & {
  keyedItem: KeyedItem<T>;
};

const inputSizeToTagSize: Record<InputSize, TagSize> = {
  tiny: 'tiny',
  small: 'tiny',
  medium: 'small',
  large: 'medium',
};

export type MultiSelectFilterBaseOption<T> =
  | KeyedItemOption<T>
  | DropdownLayoutOption;

export interface MultiSelectFilterBaseProps<V>
  extends Partial<MultiSelectProps>,
    FilterProps<V[]> {
  filter: Filter<V[]>;
  options: MultiSelectFilterBaseOption<V>[];
  renderTag?: (item: V) => TagProps;
  dropdownSelect: DropdownSelectState<V>;
  placeholder?: string;
}

function _MultiSelectCheckboxFilterBase<V>(
  props: MultiSelectFilterBaseProps<V>,
) {
  const {
    renderTag,
    filter,
    dropdownSelect,
    onSelect,
    onRemoveTag,
    size,
    popoverProps,
    ...rest
  } = props;

  const { location } = useFilterRenderingContext();
  const { windowFlipPopoverProps, inputRef } = useWindowFlipPopoverProps({
    popoverProps,
  });

  const effectiveSize: InputSize =
    size || (location === 'panel' ? 'small' : 'medium');

  const {
    select: { selectedValues },
  } = dropdownSelect;
  const { translate } = useDropdownTranslationContext();

  const tags: MultiSelectTag[] = selectedValues.map((keyedItem) => {
    const { key, item } = keyedItem;
    const tag = renderTag?.(item) ?? {};
    return {
      id: key,
      label: filter.itemName(item),
      size: inputSizeToTagSize[effectiveSize],
      ...tag,
    };
  });

  return (
    <MultiSelect
      inputRef={(ref) => {
        inputRef.current = ref;
      }}
      dataHook={`collection-filter-${filter.name}`}
      border="round"
      placeholder={translate('placeholder')}
      tags={tags}
      size={size}
      onClose={() => {
        dropdownSelect.close();
      }}
      onSelect={(option) => {
        const { keyedItem } = option as KeyedItemOption<V>;
        dropdownSelect.set(keyedItem);
        onSelect?.(option);
      }}
      onRemoveTag={(tagId) => {
        dropdownSelect.deleteKey(tagId);
        onRemoveTag?.(tagId);
      }}
      popoverProps={windowFlipPopoverProps}
      {...rest}
    />
  );
}

export const MultiSelectFilterBase = observer(_MultiSelectCheckboxFilterBase);
