import _ from "lodash";
import cn from "classnames";
import React, { useState, useMemo, useCallback } from "react";
import searchIcon from "!!svg-sprite-loader!@cloudbees/honeyui-icons/solid/search.svg";
import { Icon } from "../";

interface ISearchProps {
  ["data-testid"]?: string;
  ariaLabel?: string;
  className?: string;
  debounce?: number;
  onChange: (value: string) => void;
  placeholder?: string;
  size?: "sm" | "md" | "lg";
  value?: string;
  disabled?: boolean;
}

const Search: React.FC<ISearchProps> = props => {
  const dataTestId = props["data-testid"] || "honey-ui-search";
  const [value, setValue] = useState(props.value);

  const handleChange = useMemo(
    () => (props.debounce ? _.debounce(props.onChange, props.debounce) : props.onChange),
    [props.debounce, props.onChange]
  );

  const onChange = useCallback(
    (e: React.FormEvent<HTMLInputElement>) => {
      setValue(e.currentTarget.value);
      handleChange(e.currentTarget.value);
    },
    [handleChange]
  );

  if (!props.ariaLabel && !props.placeholder) {
    console.warn("ariaLabel or placeholder must be provided with search");
  }

  return (
    <div
      data-testid={dataTestId}
      className={cn("input-group", props.className, {
        "input-group-sm": props.size === "sm",
        "input-group-lg": props.size === "lg"
      })}
    >
      <div className="input-group-prepend">
        <span className="input-group-text">
          <Icon id={searchIcon.id} viewBox={searchIcon.viewBox} size="sm" color="dark" />
        </span>
      </div>
      <input
        data-testid={`${dataTestId}-input`}
        type="search"
        className="form-control"
        aria-label={props.ariaLabel || props.placeholder}
        value={value}
        onChange={onChange}
        placeholder={props.placeholder}
        disabled={props.disabled}
      />
      {props.children ? (
        <div className="dropdown-menu show" data-testid={`${dataTestId}-result-items`}>
          {props.children}
        </div>
      ) : null}
    </div>
  );
};

Search.displayName = "Search";
Search.defaultProps = {
  size: "md",
  value: ""
};

export default Search;
