var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
import { jsx, jsxs } from "react/jsx-runtime";
import React, { useState, useCallback, useRef, useEffect } from "react";
import Downshift from "downshift";
import { arrayOf, string, func, bool, shape } from "prop-types";
import styled, { css } from "styled-components";
import { ChevronDown, ChevronUp } from "@gympass/yoga-icons";
import Input from "../../Input/web/Input";
const escapeRegExp = (str) => str.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
const Wrapper = styled.div`
  position: relative;

  ${({ full }) => `width: ${full ? "100%" : "auto"}`}

  ${({
  isOpen,
  theme: {
    yoga: {
      components: { input }
    }
  }
}) => isOpen ? `

      ${Input} {
        border-color: ${input.border.color.typed};
        border-bottom-width: 0;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
      }

      fieldset {
        border-color: ${input.border.color.typed};
        border-bottom-width: 0;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
      }

      label {
        color: ${input.label.color.focus};
        font-weight: ${input.label.font.weight};
      }

      legend {
        font-weight: ${input.label.font.weight};
      }
      ` : ""}
`;
const List = styled.ul`
  position: absolute;
  margin: 0;

  padding: 0;

  z-index: 999;

  ${({
  full,
  error,
  theme: {
    yoga: {
      colors,
      components: { autocomplete }
    }
  }
}) => css`
    top: ${autocomplete.height}px;

    width: ${full ? "100%" : `${autocomplete.width}px`};
    max-height: ${autocomplete.height * 6}px;
    overflow-y: auto;
    box-sizing: border-box;

    background-color: ${autocomplete.field.backgroundColor};

    border-width: ${autocomplete.border.width}px;
    border-style: solid;
    border-color: ${autocomplete.border.color.typed};

    border-color: ${error ? colors.feedback.attention[1] : autocomplete.border.color.typed};

    border-top-width: 0;
    border-bottom-left-radius: ${autocomplete.border.radius}px;
    border-bottom-right-radius: ${autocomplete.border.radius}px;
  `}
`;
const Item = styled.li`
  box-sizing: border-box;

  list-style: none;

  cursor: pointer;

  ${({
  selected,
  theme: {
    yoga: {
      components: { autocomplete }
    }
  }
}) => `
    padding:
      ${autocomplete.list.padding.top}px
      ${autocomplete.list.padding.right}px
      ${autocomplete.list.padding.bottom}px
      ${autocomplete.list.padding.left}px;

    background-color: ${autocomplete.list.backgroundColor.default};
    outline: none;

    font-size: ${autocomplete.list.font.size}px;
    font-weight: ${autocomplete.list.font.weight.default};
    line-height: ${autocomplete.list.font.lineHeight}px;

    &:hover {
      background-color: ${autocomplete.list.backgroundColor.hover};
    }

    ${selected ? `background-color: ${autocomplete.list.backgroundColor.hover};` : ""}
  `}
`;
const Match = styled.mark`
  background: transparent;
  color: inherit;

  ${({
  theme: {
    yoga: {
      components: { autocomplete }
    }
  }
}) => `
    font-weight: ${autocomplete.list.font.weight.matched};
  `}
`;
const noop = () => {
};
const emptyArr = [];
const AutoComplete = React.forwardRef(
  (_a, ref) => {
    var _b = _a, {
      className,
      style,
      full = false,
      options = emptyArr,
      onChange = noop,
      onClean = noop,
      onSelect = noop,
      value,
      error,
      openSuggestionsAriaLabel = "Open suggestions",
      closeSuggestionsAriaLabel = "Close suggestions",
      highlightFirst = false,
      shouldFilterOptions = true
    } = _b, props = __objRest(_b, [
      "className",
      "style",
      "full",
      "options",
      "onChange",
      "onClean",
      "onSelect",
      "value",
      "error",
      "openSuggestionsAriaLabel",
      "closeSuggestionsAriaLabel",
      "highlightFirst",
      "shouldFilterOptions"
    ]);
    const [userValue, setUserValue] = useState(value);
    const [isSuggestionsOpen, setIsSuggestionsOpen] = useState(false);
    const inputRef = useRef();
    const handleOpenSuggestions = useCallback(() => {
      var _a2;
      (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
      setIsSuggestionsOpen(true);
    }, []);
    const handleCloseSuggestions = useCallback(() => {
      setIsSuggestionsOpen(false);
    }, []);
    useEffect(() => {
      const handleKeyUp = ({ key }) => {
        return key === "Escape" && handleCloseSuggestions();
      };
      window.addEventListener("keyup", handleKeyUp);
      return () => window.removeEventListener("keyup", handleKeyUp);
    }, []);
    return /* @__PURE__ */ jsx(
      Downshift,
      {
        selectedItem: userValue,
        defaultHighlightedIndex: highlightFirst ? 0 : null,
        onStateChange: (changes) => {
          const { selectedItem, inputValue } = changes;
          if (selectedItem) {
            setUserValue(selectedItem);
            onSelect(selectedItem);
            onChange(selectedItem);
            handleCloseSuggestions();
          } else if (Object.prototype.hasOwnProperty.call(changes, "inputValue")) {
            setUserValue(inputValue);
            onChange(inputValue);
          }
        },
        children: ({
          getInputProps,
          getItemProps,
          clearSelection,
          getMenuProps,
          getRootProps,
          highlightedIndex,
          isOpen,
          openMenu,
          inputValue
        }) => {
          const reg = new RegExp(
            `(${escapeRegExp(inputValue || "").trim()})`,
            "gi"
          );
          const suggestionList = shouldFilterOptions ? options.filter((option) => option.match(reg)).sort(
            (first, second) => first.toLowerCase().indexOf(inputValue) < second.toLowerCase().indexOf(inputValue) ? -1 : 1
          ) : options;
          if (!!inputValue && isOpen) {
            setIsSuggestionsOpen(true);
          }
          return /* @__PURE__ */ jsxs(
            Wrapper,
            __spreadProps(__spreadValues({
              className,
              style,
              full,
              isOpen: isSuggestionsOpen
            }, getRootProps()), {
              ref,
              onBlur: handleCloseSuggestions,
              children: [
                /* @__PURE__ */ jsx(
                  Input,
                  __spreadProps(__spreadValues(__spreadProps(__spreadValues({}, props), {
                    error,
                    full,
                    onClean: (cleanable) => {
                      onClean(cleanable);
                      clearSelection();
                      handleCloseSuggestions();
                    }
                  }), getInputProps({
                    onFocus: () => inputValue.length ? openMenu() : null
                  })), {
                    rightIcon: isSuggestionsOpen ? /* @__PURE__ */ jsx(
                      ChevronUp,
                      {
                        onClick: handleCloseSuggestions,
                        "aria-label": closeSuggestionsAriaLabel
                      }
                    ) : /* @__PURE__ */ jsx(
                      ChevronDown,
                      {
                        onClick: handleOpenSuggestions,
                        "aria-label": openSuggestionsAriaLabel
                      }
                    ),
                    ref: inputRef,
                    includeAriaAttributes: false
                  })
                ),
                isSuggestionsOpen && /* @__PURE__ */ jsx(List, __spreadProps(__spreadValues({}, getMenuProps()), { full, error: !!error, children: suggestionList.map((option, optionIndex) => /* @__PURE__ */ jsx(
                  Item,
                  __spreadProps(__spreadValues({}, getItemProps({
                    key: `${option}${optionIndex}`,
                    index: optionIndex,
                    item: option,
                    selected: highlightedIndex === optionIndex
                  })), {
                    children: option.split(reg).map(
                      (part, index) => !!inputValue && part.match(reg) ? /* @__PURE__ */ jsx(Match, { children: part }, index) : /* @__PURE__ */ jsx(React.Fragment, { children: part }, `unmatch-${index}`)
                    )
                  })
                )) }))
              ]
            })
          );
        }
      }
    );
  }
);
AutoComplete.propTypes = {
  className: string,
  full: bool,
  options: arrayOf(string),
  style: shape({}),
  /** callback to know when a user selects a suggestion */
  onSelect: func,
  /** called when user type or clean the field and when selects a suggestion */
  onChange: func,
  /** a callback to know when the user cleaned the field */
  onClean: func,
  value: string,
  error: string,
  /** an aria label for the open suggestions icon */
  openSuggestionsAriaLabel: string,
  /** an aria label for the close suggestions icon */
  closeSuggestionsAriaLabel: string,
  /** flag to enable options filtering */
  shouldFilterOptions: bool,
  /** first highlighted option for whenever Autocomplete is restarted */
  highlightFirst: bool
};
var AutoComplete_default = AutoComplete;
export {
  AutoComplete_default as default
};
