import Ce from "./index-extends.js";
import * as p from "react";
import it from "./index-useId2.js";
import ce from "./index-useControlled2.js";
import st from "./index-usePreviousProps.js";
import Z from "./index-useEventCallback2.js";
import lt from "./index-setRef.js";
function Pe(d) {
  return typeof d.normalize < "u" ? d.normalize("NFD").replace(/[\u0300-\u036f]/g, "") : d;
}
function at(d = {}) {
  const {
    ignoreAccents: k = !0,
    ignoreCase: h = !0,
    limit: C,
    matchFrom: te = "any",
    stringify: U,
    trim: R = !1
  } = d;
  return (P, {
    inputValue: q,
    getOptionLabel: V
  }) => {
    let S = R ? q.trim() : q;
    h && (S = S.toLowerCase()), k && (S = Pe(S));
    const B = S ? P.filter((ne) => {
      let w = (U || V)(ne);
      return h && (w = w.toLowerCase()), k && (w = Pe(w)), te === "start" ? w.indexOf(S) === 0 : w.indexOf(S) > -1;
    }) : P;
    return typeof C == "number" ? B.slice(0, C) : B;
  };
}
function ee(d, k) {
  for (let h = 0; h < d.length; h += 1)
    if (k(d[h]))
      return h;
  return -1;
}
const ut = at(), Ve = 5, ct = (d) => {
  var k;
  return d.current !== null && ((k = d.current.parentElement) == null ? void 0 : k.contains(document.activeElement));
}, ft = [];
function xt(d) {
  const {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    unstable_isActiveElementInListbox: k = ct,
    // eslint-disable-next-line @typescript-eslint/naming-convention
    unstable_classNamePrefix: h = "Mui",
    autoComplete: C = !1,
    autoHighlight: te = !1,
    autoSelect: U = !1,
    blurOnSelect: R = !1,
    clearOnBlur: P = !d.freeSolo,
    clearOnEscape: q = !1,
    componentName: V = "useAutocomplete",
    defaultValue: S = d.multiple ? ft : null,
    disableClearable: B = !1,
    disableCloseOnSelect: ne = !1,
    disabled: w,
    disabledItemsFocusable: ve = !1,
    disableListWrap: fe = !1,
    filterOptions: Le = ut,
    filterSelectedOptions: de = !1,
    freeSolo: v = !1,
    getOptionDisabled: K,
    getOptionKey: pe,
    getOptionLabel: ge = (t) => {
      var e;
      return (e = t.label) != null ? e : t;
    },
    groupBy: z,
    handleHomeEndKeys: he = !d.freeSolo,
    id: Me,
    includeInputInList: me = !1,
    inputValue: Re,
    isOptionEqualToValue: D = (t, e) => t === e,
    multiple: a = !1,
    onChange: be,
    onClose: xe,
    onHighlightChange: ye,
    onInputChange: A,
    onOpen: Oe,
    open: He,
    openOnFocus: Fe = !1,
    options: oe,
    readOnly: H = !1,
    selectOnFocus: _e = !d.freeSolo,
    value: Ue
  } = d, x = it(Me);
  let m = ge;
  m = (t) => {
    const e = ge(t);
    if (typeof e != "string") {
      if (process.env.NODE_ENV !== "production") {
        const n = e === void 0 ? "undefined" : `${typeof e} (${e})`;
      }
      return String(e);
    }
    return e;
  };
  const re = p.useRef(!1), ie = p.useRef(!0), c = p.useRef(null), y = p.useRef(null), [j, qe] = p.useState(null), [O, se] = p.useState(-1), Ie = te ? 0 : -1, g = p.useRef(Ie), [o, Be] = ce({
    controlled: Ue,
    default: S,
    name: V
  }), [l, J] = ce({
    controlled: Re,
    default: "",
    name: V,
    state: "inputValue"
  }), [Y, we] = p.useState(!1), W = p.useCallback((t, e) => {
    if (!(a ? o.length < e.length : e !== null) && !P)
      return;
    let r;
    if (a)
      r = "";
    else if (e == null)
      r = "";
    else {
      const i = m(e);
      r = typeof i == "string" ? i : "";
    }
    l !== r && (J(r), A && A(t, r, "reset"));
  }, [m, l, a, A, J, P, o]), [L, ke] = ce({
    controlled: He,
    default: !1,
    name: V,
    state: "open"
  }), [Ke, Se] = p.useState(!0), Te = !a && o != null && l === m(o), b = L && !H, u = b ? Le(
    oe.filter((t) => !(de && (a ? o : [o]).some((e) => e !== null && D(t, e)))),
    // we use the empty string to manipulate `filterOptions` to not filter any options
    // i.e. the filter predicate always returns true
    {
      inputValue: Te && Ke ? "" : l,
      getOptionLabel: m
    }
  ) : [], T = st({
    filteredOptions: u,
    value: o,
    inputValue: l
  });
  p.useEffect(() => {
    const t = o !== T.value;
    Y && !t || v && !t || W(null, o);
  }, [o, W, Y, T.value, v]);
  const le = L && u.length > 0 && !H;
  process.env.NODE_ENV !== "production" && o !== null && !v && oe.length > 0 && (a ? o : [o]).filter((e) => !oe.some((n) => D(n, e))).length > 0;
  const X = Z((t) => {
    t === -1 ? c.current.focus() : j.querySelector(`[data-tag-index="${t}"]`).focus();
  });
  p.useEffect(() => {
    a && O > o.length - 1 && (se(-1), X(-1));
  }, [o, a, O, X]);
  function ze(t, e) {
    if (!y.current || t < 0 || t >= u.length)
      return -1;
    let n = t;
    for (; ; ) {
      const r = y.current.querySelector(`[data-option-index="${n}"]`), i = ve ? !1 : !r || r.disabled || r.getAttribute("aria-disabled") === "true";
      if (r && r.hasAttribute("tabindex") && !i)
        return n;
      if (e === "next" ? n = (n + 1) % u.length : n = (n - 1 + u.length) % u.length, n === t)
        return -1;
    }
  }
  const N = Z(({
    event: t,
    index: e,
    reason: n = "auto"
  }) => {
    if (g.current = e, e === -1 ? c.current.removeAttribute("aria-activedescendant") : c.current.setAttribute("aria-activedescendant", `${x}-option-${e}`), ye && ye(t, e === -1 ? null : u[e], n), !y.current)
      return;
    const r = y.current.querySelector(`[role="option"].${h}-focused`);
    r && (r.classList.remove(`${h}-focused`), r.classList.remove(`${h}-focusVisible`));
    let i = y.current;
    if (y.current.getAttribute("role") !== "listbox" && (i = y.current.parentElement.querySelector('[role="listbox"]')), !i)
      return;
    if (e === -1) {
      i.scrollTop = 0;
      return;
    }
    const s = y.current.querySelector(`[data-option-index="${e}"]`);
    if (s && (s.classList.add(`${h}-focused`), n === "keyboard" && s.classList.add(`${h}-focusVisible`), i.scrollHeight > i.clientHeight && n !== "mouse" && n !== "touch")) {
      const f = s, I = i.clientHeight + i.scrollTop, Q = f.offsetTop + f.offsetHeight;
      Q > I ? i.scrollTop = Q - i.clientHeight : f.offsetTop - f.offsetHeight * (z ? 1.3 : 0) < i.scrollTop && (i.scrollTop = f.offsetTop - f.offsetHeight * (z ? 1.3 : 0));
    }
  }), E = Z(({
    event: t,
    diff: e,
    direction: n = "next",
    reason: r = "auto"
  }) => {
    if (!b)
      return;
    const s = ze((() => {
      const f = u.length - 1;
      if (e === "reset")
        return Ie;
      if (e === "start")
        return 0;
      if (e === "end")
        return f;
      const I = g.current + e;
      return I < 0 ? I === -1 && me ? -1 : fe && g.current !== -1 || Math.abs(e) > 1 ? 0 : f : I > f ? I === f + 1 && me ? -1 : fe || Math.abs(e) > 1 ? f : 0 : I;
    })(), n);
    if (N({
      index: s,
      reason: r,
      event: t
    }), C && e !== "reset")
      if (s === -1)
        c.current.value = l;
      else {
        const f = m(u[s]);
        c.current.value = f, f.toLowerCase().indexOf(l.toLowerCase()) === 0 && l.length > 0 && c.current.setSelectionRange(l.length, f.length);
      }
  }), je = () => {
    const t = (e, n) => {
      const r = e ? m(e) : "", i = n ? m(n) : "";
      return r === i;
    };
    if (g.current !== -1 && T.filteredOptions && T.filteredOptions.length !== u.length && T.inputValue === l && (a ? o.length === T.value.length && T.value.every((e, n) => m(o[n]) === m(e)) : t(T.value, o))) {
      const e = T.filteredOptions[g.current];
      if (e)
        return ee(u, (n) => m(n) === m(e));
    }
    return -1;
  }, ae = p.useCallback(() => {
    if (!b)
      return;
    const t = je();
    if (t !== -1) {
      g.current = t;
      return;
    }
    const e = a ? o[0] : o;
    if (u.length === 0 || e == null) {
      E({
        diff: "reset"
      });
      return;
    }
    if (y.current) {
      if (e != null) {
        const n = u[g.current];
        if (a && n && ee(o, (i) => D(n, i)) !== -1)
          return;
        const r = ee(u, (i) => D(i, e));
        r === -1 ? E({
          diff: "reset"
        }) : N({
          index: r
        });
        return;
      }
      if (g.current >= u.length - 1) {
        N({
          index: u.length - 1
        });
        return;
      }
      N({
        index: g.current
      });
    }
  }, [
    // Only sync the highlighted index when the option switch between empty and not
    u.length,
    // Don't sync the highlighted index with the value when multiple
    // eslint-disable-next-line react-hooks/exhaustive-deps
    a ? !1 : o,
    de,
    E,
    N,
    b,
    l,
    a
  ]), Je = Z((t) => {
    lt(y, t), t && ae();
  });
  process.env.NODE_ENV !== "production" && p.useEffect(() => {
    (!c.current || c.current.nodeName !== "INPUT") && c.current && c.current.nodeName;
  }, [V]), p.useEffect(() => {
    ae();
  }, [ae]);
  const $ = (t) => {
    L || (ke(!0), Se(!0), Oe && Oe(t));
  }, F = (t, e) => {
    L && (ke(!1), xe && xe(t, e));
  }, M = (t, e, n, r) => {
    if (a) {
      if (o.length === e.length && o.every((i, s) => i === e[s]))
        return;
    } else if (o === e)
      return;
    be && be(t, e, n, r), Be(e);
  }, G = p.useRef(!1), _ = (t, e, n = "selectOption", r = "options") => {
    let i = n, s = e;
    if (a) {
      s = Array.isArray(o) ? o.slice() : [], process.env.NODE_ENV !== "production" && s.filter((Q) => D(e, Q)).length > 1;
      const f = ee(s, (I) => D(e, I));
      f === -1 ? s.push(e) : r !== "freeSolo" && (s.splice(f, 1), i = "removeOption");
    }
    W(t, s), M(t, s, i, {
      option: e
    }), !ne && (!t || !t.ctrlKey && !t.metaKey) && F(t, i), (R === !0 || R === "touch" && G.current || R === "mouse" && !G.current) && c.current.blur();
  };
  function Ye(t, e) {
    if (t === -1)
      return -1;
    let n = t;
    for (; ; ) {
      if (e === "next" && n === o.length || e === "previous" && n === -1)
        return -1;
      const r = j.querySelector(`[data-tag-index="${n}"]`);
      if (!r || !r.hasAttribute("tabindex") || r.disabled || r.getAttribute("aria-disabled") === "true")
        n += e === "next" ? 1 : -1;
      else
        return n;
    }
  }
  const Ee = (t, e) => {
    if (!a)
      return;
    l === "" && F(t, "toggleInput");
    let n = O;
    O === -1 ? l === "" && e === "previous" && (n = o.length - 1) : (n += e === "next" ? 1 : -1, n < 0 && (n = 0), n === o.length && (n = -1)), n = Ye(n, e), se(n), X(n);
  }, De = (t) => {
    re.current = !0, J(""), A && A(t, "", "clear"), M(t, a ? [] : null, "clear");
  }, We = (t) => (e) => {
    if (t.onKeyDown && t.onKeyDown(e), !e.defaultMuiPrevented && (O !== -1 && ["ArrowLeft", "ArrowRight"].indexOf(e.key) === -1 && (se(-1), X(-1)), e.which !== 229))
      switch (e.key) {
        case "Home":
          b && he && (e.preventDefault(), E({
            diff: "start",
            direction: "next",
            reason: "keyboard",
            event: e
          }));
          break;
        case "End":
          b && he && (e.preventDefault(), E({
            diff: "end",
            direction: "previous",
            reason: "keyboard",
            event: e
          }));
          break;
        case "PageUp":
          e.preventDefault(), E({
            diff: -Ve,
            direction: "previous",
            reason: "keyboard",
            event: e
          }), $(e);
          break;
        case "PageDown":
          e.preventDefault(), E({
            diff: Ve,
            direction: "next",
            reason: "keyboard",
            event: e
          }), $(e);
          break;
        case "ArrowDown":
          e.preventDefault(), E({
            diff: 1,
            direction: "next",
            reason: "keyboard",
            event: e
          }), $(e);
          break;
        case "ArrowUp":
          e.preventDefault(), E({
            diff: -1,
            direction: "previous",
            reason: "keyboard",
            event: e
          }), $(e);
          break;
        case "ArrowLeft":
          Ee(e, "previous");
          break;
        case "ArrowRight":
          Ee(e, "next");
          break;
        case "Enter":
          if (g.current !== -1 && b) {
            const n = u[g.current], r = K ? K(n) : !1;
            if (e.preventDefault(), r)
              return;
            _(e, n, "selectOption"), C && c.current.setSelectionRange(c.current.value.length, c.current.value.length);
          } else v && l !== "" && Te === !1 && (a && e.preventDefault(), _(e, l, "createOption", "freeSolo"));
          break;
        case "Escape":
          b ? (e.preventDefault(), e.stopPropagation(), F(e, "escape")) : q && (l !== "" || a && o.length > 0) && (e.preventDefault(), e.stopPropagation(), De(e));
          break;
        case "Backspace":
          if (a && !H && l === "" && o.length > 0) {
            const n = O === -1 ? o.length - 1 : O, r = o.slice();
            r.splice(n, 1), M(e, r, "removeOption", {
              option: o[n]
            });
          }
          break;
        case "Delete":
          if (a && !H && l === "" && o.length > 0 && O !== -1) {
            const n = O, r = o.slice();
            r.splice(n, 1), M(e, r, "removeOption", {
              option: o[n]
            });
          }
          break;
      }
  }, Xe = (t) => {
    we(!0), Fe && !re.current && $(t);
  }, Ae = (t) => {
    if (k(y)) {
      c.current.focus();
      return;
    }
    we(!1), ie.current = !0, re.current = !1, U && g.current !== -1 && b ? _(t, u[g.current], "blur") : U && v && l !== "" ? _(t, l, "blur", "freeSolo") : P && W(t, o), F(t, "blur");
  }, Ge = (t) => {
    const e = t.target.value;
    l !== e && (J(e), Se(!1), A && A(t, e, "input")), e === "" ? !B && !a && M(t, null, "clear") : $(t);
  }, Qe = (t) => {
    const e = Number(t.currentTarget.getAttribute("data-option-index"));
    g.current !== e && N({
      event: t,
      index: e,
      reason: "mouse"
    });
  }, Ze = (t) => {
    N({
      event: t,
      index: Number(t.currentTarget.getAttribute("data-option-index")),
      reason: "touch"
    }), G.current = !0;
  }, et = (t) => {
    const e = Number(t.currentTarget.getAttribute("data-option-index"));
    _(t, u[e], "selectOption"), G.current = !1;
  }, tt = (t) => (e) => {
    const n = o.slice();
    n.splice(t, 1), M(e, n, "removeOption", {
      option: o[t]
    });
  }, Ne = (t) => {
    L ? F(t, "toggleInput") : $(t);
  }, nt = (t) => {
    t.currentTarget.contains(t.target) && t.target.getAttribute("id") !== x && t.preventDefault();
  }, ot = (t) => {
    t.currentTarget.contains(t.target) && (c.current.focus(), _e && ie.current && c.current.selectionEnd - c.current.selectionStart === 0 && c.current.select(), ie.current = !1);
  }, rt = (t) => {
    !w && (l === "" || !L) && Ne(t);
  };
  let ue = v && l.length > 0;
  ue = ue || (a ? o.length > 0 : o !== null);
  let $e = u;
  if (z) {
    const t = /* @__PURE__ */ new Map();
    let e = !1;
    $e = u.reduce((n, r, i) => {
      const s = z(r);
      return n.length > 0 && n[n.length - 1].group === s ? n[n.length - 1].options.push(r) : (process.env.NODE_ENV !== "production" && (t.get(s) && !e && (e = !0), t.set(s, !0)), n.push({
        key: i,
        index: i,
        group: s,
        options: [r]
      })), n;
    }, []);
  }
  return w && Y && Ae(), {
    getRootProps: (t = {}) => Ce({
      "aria-owns": le ? `${x}-listbox` : null
    }, t, {
      onKeyDown: We(t),
      onMouseDown: nt,
      onClick: ot
    }),
    getInputLabelProps: () => ({
      id: `${x}-label`,
      htmlFor: x
    }),
    getInputProps: () => ({
      id: x,
      value: l,
      onBlur: Ae,
      onFocus: Xe,
      onChange: Ge,
      onMouseDown: rt,
      // if open then this is handled imperatively so don't let react override
      // only have an opinion about this when closed
      "aria-activedescendant": b ? "" : null,
      "aria-autocomplete": C ? "both" : "list",
      "aria-controls": le ? `${x}-listbox` : void 0,
      "aria-expanded": le,
      // Disable browser's suggestion that might overlap with the popup.
      // Handle autocomplete but not autofill.
      autoComplete: "off",
      ref: c,
      autoCapitalize: "none",
      spellCheck: "false",
      role: "combobox",
      disabled: w
    }),
    getClearProps: () => ({
      tabIndex: -1,
      type: "button",
      onClick: De
    }),
    getPopupIndicatorProps: () => ({
      tabIndex: -1,
      type: "button",
      onClick: Ne
    }),
    getTagProps: ({
      index: t
    }) => Ce({
      key: t,
      "data-tag-index": t,
      tabIndex: -1
    }, !H && {
      onDelete: tt(t)
    }),
    getListboxProps: () => ({
      role: "listbox",
      id: `${x}-listbox`,
      "aria-labelledby": `${x}-label`,
      ref: Je,
      onMouseDown: (t) => {
        t.preventDefault();
      }
    }),
    getOptionProps: ({
      index: t,
      option: e
    }) => {
      var n;
      const r = (a ? o : [o]).some((s) => s != null && D(e, s)), i = K ? K(e) : !1;
      return {
        key: (n = pe == null ? void 0 : pe(e)) != null ? n : m(e),
        tabIndex: -1,
        role: "option",
        id: `${x}-option-${t}`,
        onMouseMove: Qe,
        onClick: et,
        onTouchStart: Ze,
        "data-option-index": t,
        "aria-disabled": i,
        "aria-selected": r
      };
    },
    id: x,
    inputValue: l,
    value: o,
    dirty: ue,
    expanded: b && j,
    popupOpen: b,
    focused: Y || O !== -1,
    anchorEl: j,
    setAnchorEl: qe,
    focusedTag: O,
    groupedOptions: $e
  };
}
export {
  at as createFilterOptions,
  xt as default
};
