import { jsx, jsxs } from "react/jsx-runtime";
import { useState, useEffect, useRef, useMemo } from "react";
import { Box, Text, useInput } from "ink";
function BaseAutocomplete({
  items,
  query,
  isVisible,
  isLoading = false,
  onSelect,
  onLoadIntoInput,
  onClose,
  filterFn,
  scoreFn,
  formatItem,
  formatLoadText,
  title,
  maxVisibleItems = 10,
  loadingMessage = "Loading...",
  emptyMessage = "No matches found",
  borderColor = "cyan"
}) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [scrollOffset, setScrollOffset] = useState(0);
  const selectedIndexRef = useRef(0);
  useEffect(() => {
    selectedIndexRef.current = selectedIndex;
  }, [selectedIndex]);
  const filteredItems = useMemo(() => {
    if (!query) return items;
    return items.filter((item) => filterFn(item, query)).sort((a, b) => {
      const scoreA = scoreFn(a, query);
      const scoreB = scoreFn(b, query);
      return scoreB - scoreA;
    });
  }, [items, query, filterFn, scoreFn]);
  useEffect(() => {
    setSelectedIndex(0);
    setScrollOffset(0);
  }, [filteredItems.length]);
  useEffect(() => {
    if (selectedIndex < scrollOffset) {
      setScrollOffset(selectedIndex);
    } else if (selectedIndex >= scrollOffset + maxVisibleItems) {
      setScrollOffset(Math.max(0, selectedIndex - maxVisibleItems + 1));
    }
  }, [selectedIndex, scrollOffset, maxVisibleItems]);
  const visibleItems = useMemo(() => {
    return filteredItems.slice(scrollOffset, scrollOffset + maxVisibleItems);
  }, [filteredItems, scrollOffset, maxVisibleItems]);
  useInput(
    (input, key) => {
      if (!isVisible) return;
      const itemsLength = filteredItems.length;
      if (itemsLength === 0) return;
      if (key.upArrow) {
        setSelectedIndex((prev) => (prev - 1 + itemsLength) % itemsLength);
      }
      if (key.downArrow) {
        setSelectedIndex((prev) => (prev + 1) % itemsLength);
      }
      if (key.escape) {
        onClose();
      }
      if (key.tab && onLoadIntoInput && formatLoadText && itemsLength > 0) {
        const item = filteredItems[selectedIndexRef.current];
        if (item) {
          onLoadIntoInput(formatLoadText(item));
        }
        return;
      }
      if (key.return && itemsLength > 0) {
        const item = filteredItems[selectedIndexRef.current];
        if (item) {
          onSelect(item);
        }
      }
    },
    { isActive: isVisible }
  );
  if (!isVisible) return null;
  if (isLoading) {
    return /* @__PURE__ */ jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, paddingY: 1, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: loadingMessage }) });
  }
  if (filteredItems.length === 0) {
    return /* @__PURE__ */ jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, paddingY: 1, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: emptyMessage }) });
  }
  const hasMoreAbove = scrollOffset > 0;
  const hasMoreBelow = scrollOffset + maxVisibleItems < filteredItems.length;
  const totalItems = filteredItems.length;
  return /* @__PURE__ */ jsxs(
    Box,
    {
      borderStyle: "single",
      borderColor,
      flexDirection: "column",
      height: Math.min(maxVisibleItems + 3, totalItems + 3),
      children: [
        /* @__PURE__ */ jsx(Box, { paddingX: 1, paddingY: 0, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
          title,
          " (",
          selectedIndex + 1,
          "/",
          totalItems,
          ") - \u2191\u2193 navigate",
          onLoadIntoInput && ", Tab load",
          ", Enter select, Esc close"
        ] }) }),
        hasMoreAbove && /* @__PURE__ */ jsx(Box, { paddingX: 1, paddingY: 0, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
          "... \u2191 (",
          scrollOffset,
          " more above)"
        ] }) }),
        visibleItems.map((item, visibleIndex) => {
          const actualIndex = scrollOffset + visibleIndex;
          const isSelected = actualIndex === selectedIndex;
          return /* @__PURE__ */ jsx(Box, { paddingX: 1, paddingY: 0, children: formatItem(item, isSelected) }, actualIndex);
        }),
        hasMoreBelow && /* @__PURE__ */ jsx(Box, { paddingX: 1, paddingY: 0, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
          "... \u2193 (",
          totalItems - scrollOffset - maxVisibleItems,
          " more below)"
        ] }) })
      ]
    }
  );
}
export {
  BaseAutocomplete
};
