import { useCallback, useRef, useState } from 'react';

import type { ReactNode } from 'react';
import type { TextInputOnInputEnd } from '../TextInput';
import type { TextInputWithLoadingProps } from '../TextInput/TextInputWithLoading';

import Box from '../Box';
import Clickable from '../Clickable';
import CrossIcon from '../Icon/CrossIcon';
import SearchIcon from '../Icon/SearchIcon';
import TextInputWithLoading from '../TextInput/TextInputWithLoading';

interface SearchTextInputProps
  extends Omit<
    TextInputWithLoadingProps,
    'value' | 'children' | 'renderAfter' | 'withTracking'
  > {
  withClearButton?: boolean;
}

const SearchTextInput = ({
  withClearButton,
  onClear,
  onInputEnd,
  inputRef,
  ...inputProps
}: SearchTextInputProps) => {
  const innerRef = useRef<HTMLInputElement>(null);
  const textInputRef = inputRef || innerRef;
  const [value, setValue] = useState<string>(inputProps.defaultValue ?? '');
  const { centerText } = inputProps;

  const handleOnInputEnd = useCallback<TextInputOnInputEnd>(
    (params) => {
      setValue(params.value);
      onInputEnd?.(params);
    },
    [onInputEnd]
  );

  const renderAfter = useCallback(() => {
    let Content: ReactNode;

    const showClearButton = withClearButton && value && value.length > 0;

    if (showClearButton) {
      Content = (
        <Clickable
          testId="searchTextInputClear"
          padding="0 1.1rem 0 0"
          isInline
          onClick={() => {
            setValue('');

            if (textInputRef.current) {
              textInputRef.current.value = '';
              textInputRef.current?.focus();
            }

            if (onClear) onClear();
          }}
        >
          <CrossIcon size="1.4em" opacity={0.6} />
        </Clickable>
      );
    } else {
      Content = <SearchIcon size="1.8em" color="#666" margin=".1em .5em 0 0" />;
    }
    return (
      <Box
        fullHeight
        pointerEvents={showClearButton ? undefined : 'none'}
        centerContent
        {...(centerText ? { positionAbsolute: true, top: 0, right: 0 } : {})}
      >
        {Content}
      </Box>
    );
  }, [value, withClearButton]);

  return (
    <TextInputWithLoading
      {...inputProps}
      inputRef={textInputRef}
      renderAfter={renderAfter}
      onInputEnd={handleOnInputEnd}
      withTracking
      {...(centerText ? { padding: '0 4.6rem' } : {})}
    />
  );
};

export default SearchTextInput;
