import { observer } from 'mobx-react-lite';
import { Box, Search, SearchProps, TextButton } from '@wix/design-system';
import React, {
  CSSProperties,
  useState,
  useRef,
  useCallback,
  useEffect,
} from 'react';
import { FiltersMap } from '@wix/bex-core';
import { useCollectionContext } from '@wix/bex-core/react';
import { useIsMobile } from '../hooks/useIsMobile';

export interface CollectionSearchProps extends Partial<SearchProps> {
  onSearchChange?: (value: string) => unknown;
  onSearchClick?: () => unknown;
  onSearchBlur?: (value: string) => unknown;
  visibility?: CSSProperties['visibility'];
}

export const CollectionSearch = observer(function CollectionSearch<
  T,
  F extends FiltersMap = FiltersMap,
>({
  onSearchChange,
  onSearchClick,
  onSearchBlur,
  visibility,
  expandable,
  ...rest
}: CollectionSearchProps) {
  const collection = useCollectionContext<T, F>();
  const {
    query: { search },
    translate: t,
  } = collection;

  const isMobile = useIsMobile();
  const [isSearchExpanded, setIsSearchExpanded] = useState(!!search.value);

  const searchInputRef = useRef<Search>(null);

  useEffect(() => {
    collection.searchInputRef = {
      focus: () => {
        searchInputRef.current?.focus();
      },
    };
    return () => {
      collection.searchInputRef = null;
    };
  }, [collection]);

  const handleCancel = useCallback(() => {
    collection.clearSearch();
    onSearchChange?.('');

    if (searchInputRef.current) {
      searchInputRef.current.blur();
      setIsSearchExpanded(false);
    }
  }, [collection, onSearchChange]);

  const showCancelButton = isMobile && isSearchExpanded;

  const searchElement = (
    <Search
      dataHook="collection-search"
      onChange={(e) => {
        const value = e.target.value;
        collection.search(e.target.value, { clearResult: true });
        onSearchChange?.(value);
      }}
      ref={searchInputRef}
      value={search.value}
      onClear={() => {
        const value = '';
        collection.clearSearch();
        onSearchChange?.(value);
      }}
      expandable={expandable}
      expandDirection={isMobile ? 'left' : undefined}
      placeholder={t('cairo.searchPlaceholder', { defaultValue: '' })}
      textOverflow="ellipsis"
      onFocus={() => {
        setIsSearchExpanded(true);
      }}
      onBlur={(e) => {
        const value = e.target.value;
        if (!value) {
          setIsSearchExpanded(false);
        }
        onSearchBlur?.(value);
      }}
      {...rest}
    />
  );

  if (isMobile && expandable) {
    return (
      <Box width="100%" gap="SP2" verticalAlign="middle">
        {searchElement}
        {showCancelButton && (
          <TextButton
            dataHook="collection-search-cancel"
            onClick={handleCancel}
            size="small"
          >
            {t('cairo.cancel.button')}
          </TextButton>
        )}
      </Box>
    );
  }

  return searchElement;
});
