/* -------------------------------------------------------------------------- */
/*                                   Imports                                  */
/* -------------------------------------------------------------------------- */
import React from "react";
import classNames from "classnames";
import { Combobox, Transition } from "@headlessui/react";
import { Fragment, useEffect, useState } from "react";
import { useSearchStoreImplementation } from "searchResults/data/searchStoreImplementation";
import { useSearchViewModel } from "searchResults/controller/searchResultsViewModel";
import { Loader } from "components/Loader/Loader";
/* -------------------------------------------------------------------------- */
/*                               Component props                              */
/* -------------------------------------------------------------------------- */
type Hint = {
  id: string;
  caption: string;
};

type Props<T> = {
  onSelected: (value: Hint) => void;
  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
  overflow-hidden
  focus:outline-none
  text-base 
  sm:text-sm
  overflow-y-scroll
  shadow-md
  scrollbar-thin  
  scrollbar-thumb-gray-500
  scrollbar-track-inherit
  scrollbar-thumb-rounded`;

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

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

export default function SearchInput<T>({
  onSelected,
  disabled,
  inGroup = false,
  className,
  maxScrollSize = 140,
  elementScrollSize = 36,
  placeHolder = "Search...",
  ...props
}: Props<T>) {
  const store = useSearchStoreImplementation();
  const {
    changeInputValue,
    currentSearchState,
    inputValue,
    searchResults,
    isLoading,
    isFailed,
  } = useSearchViewModel(store);
  return (
    <div>
      <Combobox value={inputValue} onChange={changeInputValue}>
        <div className="relative">
          <div className="relative w-full  bg-white text-left focus:outline-none sm:text-sm">
            <Combobox.Input
              autoComplete="off"
              className={classNames([
                [`${inputStyle}`],
                { [`${inputInGroup}`]: inGroup },
                className,
              ])}
              onChange={(event) => changeInputValue(event.target.value)}
              placeholder={placeHolder}
              displayValue={() => inputValue}
            />
          </div>

          {currentSearchState !== "" && !isFailed && !isLoading && (
            <Transition
              as="div"
              className={`${inputList}`}
              leave="transition ease-in duration-100"
              leaveFrom="opacity-100"
              leaveTo="opacity-0"
            >
              <Combobox.Options>
                {searchResults === undefined ||
                (searchResults.data.length === 0 &&
                  currentSearchState !== "") ? (
                  <div>Nothing found</div>
                ) : null}
                {searchResults !== undefined &&
                  searchResults.data.map((result) => (
                    <Combobox.Option
                      key={result.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={result.title}
                      onClick={() => {
                        if (result.title != undefined) {
                          changeInputValue(result.title);
                        }
                      }}
                    >
                      <div>{result.title}</div>
                    </Combobox.Option>
                  ))}
              </Combobox.Options>
            </Transition>
          )}
          {isLoading && (
            <div className={classNames(`${inputList}`, "mt-3")}>
              <div className="w-full flex text-center py-2 items-center justify-center">
                <Loader className="w-5 h-5" />
              </div>
            </div>
          )}
        </div>
      </Combobox>
    </div>
  );
}
