import React, { useCallback, ReactElement } from 'react';
import { observer } from 'mobx-react-lite';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { Box, Loader, Popover, SelectorList, Tag } from '@wix/design-system';
import { TagsBulkAssignPopoverState } from '../../../state/TagsBulkAssignPopoverState';
import { CreateTagButton } from './CreateTagButton';
import { EmptyState } from './EmptyState';
import { Footer } from './Footer';
import { FiltersMap, TAG_MAX_LENGTH } from '@wix/bex-core';
import { minimalRequiredWdsRuntimeCheck } from '../../../minimalRequiredWdsRuntimeCheck';
import { AsyncJobProgressModal } from './AsyncJobProgressModal';

export interface BulkAssignTagsPopoverProps<T, F extends FiltersMap> {
  state: TagsBulkAssignPopoverState<T, F>;
  popoverElement: ReactElement;
}

export const _BulkAssignTagsPopover = <T, F extends FiltersMap>({
  state,
  popoverElement,
}: BulkAssignTagsPopoverProps<T, F>) => {
  const { translate: t } = useWixPatternsContainer();

  const closePopover = useCallback(() => {
    state.closePopover();
  }, [state]);

  const handleItemSelect = useCallback(
    (item) => {
      state.handleItemSelect(item.id);
    },
    [state],
  );

  if (process.env.NODE_ENV !== 'production') {
    minimalRequiredWdsRuntimeCheck({
      required: '^1.76.1',
      requiredBy: 'WixPatterns/BulkAssignTagsPopover',
    });
  }

  const selectorListDataSource = (searchQuery: string) => {
    state.handleSearchChange(searchQuery);
    const filteredOptions = state.tagOptions.filter((tag) => {
      return tag.name!.toLowerCase().includes(searchQuery);
    });

    if (filteredOptions.length === 0 && searchQuery.length > TAG_MAX_LENGTH) {
      const truncatedTag = state.tagOptions.find(
        (tag) =>
          tag.name?.toLowerCase() ===
          searchQuery.substring(0, TAG_MAX_LENGTH).toLowerCase(),
      );

      if (truncatedTag) {
        filteredOptions.push(truncatedTag);
      }
    }

    const items = filteredOptions.map((tag, idx) => ({
      id: tag.id!,
      title: (
        <Tag
          id={tag.id!}
          removable={false}
          maxWidth="198px"
          dataHook={`bulk-assign-tags-tag-${idx}`}
        >
          {tag.name}
        </Tag>
      ),
      selected: state.assignedWithOptimisticTagIds.includes(tag.id!),
      indeterminate: state.indeterminateTagIds.includes(tag.id!),
    }));
    return Promise.resolve({
      items,
      totalCount: items.length,
    });
  };

  return (
    <>
      <Popover
        tabIndex={0}
        showArrow
        shown={state.isShown}
        appendTo="window"
        placement="bottom"
        width="304px"
        onClickOutside={closePopover}
        onEscPress={closePopover}
        onTabOut={closePopover}
        dataHook="bulk-assign-tags-popover"
      >
        <Popover.Element>{popoverElement}</Popover.Element>
        <Popover.Content>
          <Box height="270px" direction="vertical">
            {state.isLoading && (
              <Box align="center" verticalAlign="middle" flex={1}>
                <Loader dataHook="bulk-assign-tags-loading-state" />
              </Box>
            )}
            {!state.isLoading && (
              <SelectorList
                autoFocus
                key={state.tagsManagementState.items.length} // Remount the component on every new created tag
                dataHook="bulk-assign-tags-selector-list"
                dataSource={selectorListDataSource}
                emptyState={<EmptyState state={state} />}
                size="small"
                searchPlaceholder={
                  state.isInEmptyState
                    ? t(
                        'cairo.tags.collectionPage.popover.emptyState.search.placeholder',
                      )
                    : t('cairo.tags.collectionPage.popover.search.placeholder')
                }
                renderNoResults={(searchValue) => (
                  <Box padding="SP2 SP5">
                    <CreateTagButton state={state} searchValue={searchValue} />
                  </Box>
                )}
                searchMaxLength={TAG_MAX_LENGTH}
                multiple
                onSelect={handleItemSelect}
                height="216px"
              />
            )}
            <Footer state={state} />
          </Box>
        </Popover.Content>
      </Popover>
      <AsyncJobProgressModal state={state} />
    </>
  );
};

export const BulkAssignTagsPopover = observer(_BulkAssignTagsPopover);
