/* -------------------------------------------------------------------------- */
/*                                   Imports                                  */
/* -------------------------------------------------------------------------- */
import React from "react";
import classNames from "classnames";
import "../index.css";
import { Combobox, Transition } from "@headlessui/react";
import { Fragment, useEffect, useState } from "react";

/* -------------------------------------------------------------------------- */
/*                               Component props                              */
/* -------------------------------------------------------------------------- */
type Hint = {
  id: string;
  caption: string;
};

type Props<T> = {
  onChange: (query: string) => void;
  onSelected: (value: Hint) => void;
  IsEmptyItems: () => React.ReactNode;
  hints: Hint[];
  displayValueResolver?: (element: T) => any;
  disabled?: boolean;
  inGroup?: boolean;
  className?: string;
  maxScrollSize?: number;
  elementScrollSize?: number;
  placeHolder?: string;
};
/* -------------------------------------------------------------------------- */
/*                                 styles                                     */
/* -------------------------------------------------------------------------- */
const inputStyle = `
  w-full 
  cursor-default
  rounded
  overflow-hidden
  border
  border-solid
  shadow-none
  border-gray-100
  focus:outline-none
  focus:border-gray-200
  hover:border-gray-200 
  py-2 pl-3
  text-sm 
  text-gray-900  
`;

const inputList = `
  absolute z-10 mt-1 w-full max-h-56
  bg-white shadow-lg
  rounded py-1
  overflow-hidden
  focus:outline-none
  text-base 
  sm:text-sm`;

const inputInGroup = [
  `border-none
  hover:none
  active:none
  focus:none
    `,
];

/* -------------------------------------------------------------------------- */
/*                          Component implementation                          */
/* -------------------------------------------------------------------------- */

export default function SearchBar<T>({
  onChange,
  onSelected,
  hints,
  displayValueResolver,
  disabled,
  inGroup = false,
  className,
  maxScrollSize = 140,
  elementScrollSize = 36,
  placeHolder = "Search...",
  IsEmptyItems,
  ...props
}: Props<T>) {
  const [selected, setSelected] = useState<any>(hints);
  const [query, setQuery] = useState("");

  useEffect(() => {
    onChange(query);
  }, [query, onChange]);

  const handleSelected = (value: Hint) => {
    setSelected(value);
    onSelected && onSelected(value);
  };
  return (
    <div>
      <Combobox value={selected} {...props} onChange={handleSelected}>
        <div className="relative">
          <div className="relative w-full  bg-white text-left focus:outline-none sm:text-sm">
            <Combobox.Input
              className={classNames([
                [`${inputStyle}`],
                { [`${inputInGroup}`]: inGroup },
                className,
              ])}
              onChange={(event) => setQuery(event.target.value)}
              placeholder={placeHolder}
              displayValue={(value: T) =>
                displayValueResolver ? displayValueResolver(value) : value
              }
            />
          </div>
          <div>
            {query.length > 0 && (
              <div className={`${inputList}`}>
                <Transition
                  as={Fragment}
                  leave="transition ease-in duration-100"
                  leaveFrom="opacity-100"
                  leaveTo="opacity-0"
                  afterLeave={() => setQuery("")}
                >
                  <Combobox.Options>
                    {hints.length === 0 && query !== "" ? IsEmptyItems() : null}
                    {/* <Scrollbar
                      style={{
                        height: hints.length * elementScrollSize,
                        maxHeight: maxScrollSize,
                      }}
                    > */}
                    {hints.map((item: any, id: number) => (
                      <Combobox.Option
                        key={id}
                        className={({ active, selected }) =>
                          classNames(
                            active
                              ? "text-gray-900 bg-blue-50"
                              : "font-normal ",
                            "cursor-default select-none relative py-2 pl-3 pr-9",
                            selected
                              ? "text-gray-900 bg-blue-100"
                              : "font-normal "
                          )
                        }
                        value={item}
                      >
                        <div>{item.caption}</div>
                      </Combobox.Option>
                    ))}
                    {/* </Scrollbar> */}
                  </Combobox.Options>
                </Transition>
              </div>
            )}
          </div>
        </div>
      </Combobox>
    </div>
  );
}
