import {
  Combobox,
  ComboboxButton,
  ComboboxInput,
  ComboboxOption,
  ComboboxOptions,
} from "@headlessui/react";
import { CheckIcon, ChevronUpDownIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { __ } from "@wordpress/i18n";
import { useState } from "react";

/**
 * Multi select with a search box.
 *
 * @param {Array}    items       List of { value, label }.
 * @param {Array}    selected    Selected values.
 * @param {Function} onChange    Called with the new list of selected values.
 * @param {string}   placeholder       Text shown when nothing is selected.
 * @param {string}   searchPlaceholder Text shown in the search box when something is selected.
 */
const SearchMultiSelect = ({
  items = [],
  selected = [],
  onChange = () => {},
  placeholder = __("Select", "custom-product-badge-for-woocommerce"),
  searchPlaceholder = __("Search...", "custom-product-badge-for-woocommerce"),
}) => {
  const [query, setQuery] = useState("");

  const labels = Object.fromEntries(items.map((item) => [item.value, item.label]));
  const normalizedQuery = query.toLowerCase().trim();
  const filteredItems = normalizedQuery
    ? items.filter((item) => item.label.toLowerCase().includes(normalizedQuery))
    : items;

  const handleRemoveItem = (value) => {
    onChange(selected.filter((item) => item !== value));
  };

  return (
    <Combobox
      value={selected}
      onChange={(values) => {
        setQuery("");
        onChange(values);
      }}
      onClose={() => setQuery("")}
      multiple
      immediate
    >
      <div className="ino:relative ino:w-80">
        <div className="ino:relative ino:flex ino:flex-wrap ino:items-center ino:gap-1.5 ino:min-h-9 ino:w-full ino:rounded-md ino:border ino:border-border ino:bg-card ino:py-1 ino:pr-9 ino:pl-1.5 ino:text-sm ino:shadow-xs ino:transition-colors ino:hover:border-primary/40 ino:focus-within:border-primary ino:focus-within:ring-2 ino:focus-within:ring-ring/50">
          {selected.map((value) => (
            <span
              className="ino:inline-flex ino:items-center ino:gap-1 ino:rounded-full ino:border ino:border-border ino:bg-muted ino:py-0.5 ino:pr-1 ino:pl-2.5 ino:text-xs ino:font-medium ino:text-foreground"
              key={value}
            >
              {labels[value] ?? value}
              <XMarkIcon
                role="button"
                aria-label={__("Remove", "custom-product-badge-for-woocommerce")}
                onClick={() => handleRemoveItem(value)}
                className="ino:size-4 ino:cursor-pointer ino:rounded-full ino:p-0.5 ino:text-muted-foreground ino:transition-colors ino:hover:bg-red-500/10 ino:hover:text-red-600"
              />
            </span>
          ))}
          <ComboboxInput
            className="ino:flex-1 ino:min-w-24 ino:border-none! ino:shadow-none! ino:bg-transparent! ino:h-7 ino:py-0! ino:px-1! ino:min-h-0! ino:text-sm ino:text-foreground ino:placeholder:text-muted-foreground ino:focus:ring-0"
            placeholder={selected.length ? searchPlaceholder : placeholder}
            value={query}
            onChange={(event) => setQuery(event.target.value)}
          />
          <ComboboxButton className="ino:absolute ino:inset-y-0 ino:right-0 ino:flex ino:items-center ino:pr-2">
            <ChevronUpDownIcon
              className="ino:size-4 ino:text-muted-foreground"
              aria-hidden="true"
            />
          </ComboboxButton>
        </div>
        <ComboboxOptions className="ino:custom-scrollbar ino:absolute ino:z-10 ino:mt-1.5 ino:max-h-60 ino:w-full ino:overflow-auto ino:rounded-lg ino:border ino:border-border ino:bg-popover ino:p-1 ino:shadow-lg ino:outline-none ino:empty:invisible">
          {filteredItems.length === 0 ? (
            <div className="ino:px-2 ino:py-1.5 ino:text-sm ino:text-muted-foreground">
              {__("Nothing found.", "custom-product-badge-for-woocommerce")}
            </div>
          ) : (
            filteredItems.map((item) => (
              <ComboboxOption
                key={item.value}
                value={item.value}
                className={({ focus }) =>
                  `ino:relative ino:m-0 ino:flex ino:cursor-pointer ino:items-center ino:justify-between ino:gap-2 ino:rounded-md ino:px-2 ino:py-1.5 ${focus ? "ino:bg-muted" : ""}`
                }
              >
                {({ selected: isSelected }) => (
                  <>
                    <span
                      className={`ino:block ino:truncate ino:text-sm ${isSelected ? "ino:font-medium ino:text-primary" : "ino:text-foreground"}`}
                    >
                      {item.label}
                    </span>
                    {isSelected && (
                      <CheckIcon className="ino:h-4 ino:w-4 ino:shrink-0 ino:text-primary" />
                    )}
                  </>
                )}
              </ComboboxOption>
            ))
          )}
        </ComboboxOptions>
      </div>
    </Combobox>
  );
};

export default SearchMultiSelect;
