import { Box, TableToolbar } from '@wix/design-system';
import React, { cloneElement, Fragment, isValidElement, useMemo } from 'react';
import { classes, st } from './SearchOrCustomFilter.st.css.js';
import { ToolbarBaseProps } from '../ToolbarCollection';
import { useToolbarCollectionContext } from '../ToolbarCollectionContext';
import { observer } from 'mobx-react-lite';
import { useIsMobile } from '../../hooks/useIsMobile';
import { CollectionSearchElement } from '../assertComponentType.js';
import { runInAction } from 'mobx';
import {
  SEARCH_COLLAPSED_WIDTH,
  SEARCH_EXPANDED_WIDTH,
} from '../../state/Toolbar/toolbarResponsiveConstants';

export interface SearchOrCustomFilterProps {
  search: ToolbarBaseProps['search'];
  state: {
    _searchExpanded: boolean;
  };
}

function _SearchOrCustomFilter(props: SearchOrCustomFilterProps) {
  const { search: _search, state } = props;

  const {
    toolbar: { responsive },
  } = useToolbarCollectionContext();
  const { search: searchResponsive, responsiveDisabled } = responsive;

  const isMobile = useIsMobile();

  const isSearchExpanded = state._searchExpanded;

  const { search, isExpandable } = useMemo(() => {
    if (!isValidElement(_search)) {
      return {
        search: _search,
        isExpandable: false,
      };
    }
    const element = cloneElement(_search as CollectionSearchElement, {
      onExpandTransitionStart: (collapsed?: boolean) => {
        runInAction(() => {
          if (!collapsed) {
            state._searchExpanded = true;
          }
        });
      },
      onExpandTransitionEnd: (collapsed?: boolean) => {
        runInAction(() => {
          if (collapsed) {
            state._searchExpanded = false;
          }
        });
      },
    });
    return {
      search: element,
      isExpandable: element.props.expandable,
    };
  }, [_search]);

  if (responsiveDisabled || isMobile) {
    let child = search;

    if (isMobile) {
      child = (
        <Fragment>
          {isMobile && isValidElement(_search) && (
            <Box visibility="hidden">
              {/* render extra hidden search for measurement as the actual search is positioned absolutely */}
              {cloneElement(_search as CollectionSearchElement, {
                dataHook: `collection-search-mobile-measurement`,
                // bypass stateful behavior on mobile for measurement
                value: '',
                onChange: () => {},
              })}
            </Box>
          )}
          <Box
            className={st(classes.searchMobile, {
              expandable: isExpandable,
              expanded: isSearchExpanded,
            })}
          >
            {search}
          </Box>
        </Fragment>
      );
    }

    return (
      <TableToolbar.Item className={st(isMobile ? undefined : classes.search)}>
        {child}
      </TableToolbar.Item>
    );
  }

  const shouldShrink = searchResponsive._shouldShrink;

  const width = shouldShrink ? SEARCH_COLLAPSED_WIDTH : SEARCH_EXPANDED_WIDTH;

  return (
    <Box direction="horizontal" width={`${width}px`}>
      <Box width={`${width}px`}>{search}</Box>
    </Box>
  );
}

export const SearchOrCustomFilter = observer(_SearchOrCustomFilter);
