import React, { memo, useEffect, useState, useRef } from 'react';
import { joinClassNames } from '@vizality/util/dom';
import { getModule } from '@vizality/webpack';
import { Messages } from '@vizality/i18n';

import { Icon } from '.';

/**
 * @component
 * @returns {}
 */
export default memo(({ size, disabled, value, autoFocus, placeholder, loading, minLength = 4, debounce = 200, inputClassName, className, onChange, ...other }) => {
  const [ query, setQuery ] = useState(value || '');
  const inputRef = useRef(null);
  const { container, inner, disabled: _disabled, small, input, clear, iconLayout, iconContainer, icon, visible, pointer } = getModule('container', 'inner', 'small', 'input', 'clear');

  size = size || small;

  useEffect(() => {
    if (autoFocus && inputRef.current) {
      inputRef.current.focus();
    }
  }, []);

  /**
   * Set up a debounce timeout to only perform the search query every x
   * milliseconds. Especially useful for API calls.
   */
  const debounceTimeout = setTimeout(() => onChange(query), debounce);

  /**
   *
   * @param {*} evt
   * @returns {void}
   */
  const handleOnChange = evt => {
    return setQuery(evt?.currentTarget?.value);
  };

  /**
   *
   * @returns {void}
   */
  const handleClear = () => {
    return setQuery('');
  };

  useEffect(() => {
    if (typeof value !== 'undefined') {
      const evt = {
        currentTarget: {
          value
        }
      };
      handleOnChange(evt);
    }
  }, [ value ]);

  /**
   * Clear the debounce timeout on dismount.
   */
  useEffect(() => {
    return () => clearTimeout(debounceTimeout);
  }, [ debounceTimeout ]);

  return (
    <div className={joinClassNames(container, size, className, { [_disabled]: disabled })} {...other}>
      <div className={inner}>
        <input
          autoFocus={autoFocus}
          className={joinClassNames(input, inputClassName)}
          onChange={handleOnChange}
          value={query}
          placeholder={placeholder || Messages.SEARCH}
          ref={inputRef}
        />
        <div className={joinClassNames(iconLayout, size, { [pointer]: query?.length })} tabindex={query?.length ? '0' : '-1'} role='button'>
          <div className={iconContainer} onClick={() => query?.length && handleClear()}>
            <Icon svgOnly name='search' className={joinClassNames(icon, { [visible]: !query?.length })} />
            <Icon svgOnly name='close' className={joinClassNames(clear, icon, { [visible]: query?.length })} />
          </div>
        </div>
      </div>
    </div>
  );
});
