"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var BaseSelector_exports = {};
__export(BaseSelector_exports, {
  BaseSelector: () => BaseSelector
});
module.exports = __toCommonJS(BaseSelector_exports);
var import_jsx_runtime = require("react/jsx-runtime");
var import_react = require("react");
var import_ink = require("ink");
var import_useTerminalSize = require("../../hooks/useTerminalSize.js");
var import_overlaySizing = require("../../utils/overlaySizing.js");
var import_HintBar = require("../shared/HintBar.js");
function BaseSelectorInner({
  items,
  isVisible,
  isLoading = false,
  selectedIndex,
  onSelectIndex,
  onSelect,
  onClose,
  formatItem,
  title,
  maxVisibleItems = 8,
  loadingMessage = "Loading...",
  emptyMessage = "No items found",
  borderColor = "cyan",
  onTab,
  supportsTab = false,
  instructionsOverride
}, ref) {
  const { rows: terminalRows } = (0, import_useTerminalSize.useTerminalSize)();
  const viewportItems = (0, import_react.useMemo)(() => {
    return (0, import_overlaySizing.getMaxVisibleItemsForTerminalRows)({
      rows: terminalRows,
      hardCap: maxVisibleItems,
      reservedRows: 14
    });
  }, [terminalRows, maxVisibleItems]);
  const [scrollOffsetState, setScrollOffset] = (0, import_react.useState)(0);
  const selectedIndexRef = (0, import_react.useRef)(selectedIndex);
  const prevItemsLengthRef = (0, import_react.useRef)(items.length);
  selectedIndexRef.current = selectedIndex;
  const scrollOffset = (0, import_react.useMemo)(() => {
    const itemsChanged = items.length !== prevItemsLengthRef.current;
    if (itemsChanged && items.length <= viewportItems) {
      return 0;
    }
    let offset = scrollOffsetState;
    if (selectedIndex < offset) {
      offset = selectedIndex;
    } else if (selectedIndex >= offset + viewportItems) {
      offset = Math.max(0, selectedIndex - viewportItems + 1);
    }
    const maxOffset = Math.max(0, items.length - viewportItems);
    return Math.min(maxOffset, Math.max(0, offset));
  }, [selectedIndex, items.length, viewportItems, scrollOffsetState]);
  (0, import_react.useEffect)(() => {
    prevItemsLengthRef.current = items.length;
  }, [items.length]);
  (0, import_react.useEffect)(() => {
    if (scrollOffset !== scrollOffsetState) {
      setScrollOffset(scrollOffset);
    }
  }, [scrollOffset, scrollOffsetState]);
  const handleSelectIndex = (0, import_react.useCallback)(
    (newIndex) => {
      selectedIndexRef.current = newIndex;
      onSelectIndex(newIndex);
    },
    [onSelectIndex]
  );
  const visibleItems = (0, import_react.useMemo)(() => {
    return items.slice(scrollOffset, scrollOffset + viewportItems);
  }, [items, scrollOffset, viewportItems]);
  (0, import_react.useImperativeHandle)(
    ref,
    () => ({
      handleInput: (_input, key) => {
        if (!isVisible) return false;
        if (key.escape) {
          onClose();
          return true;
        }
        const itemsLength = items.length;
        if (isLoading || itemsLength === 0) return true;
        if (key.upArrow) {
          const nextIndex = (selectedIndexRef.current - 1 + itemsLength) % itemsLength;
          handleSelectIndex(nextIndex);
          return true;
        }
        if (key.downArrow) {
          const nextIndex = (selectedIndexRef.current + 1) % itemsLength;
          handleSelectIndex(nextIndex);
          return true;
        }
        if (key.tab && onTab) {
          const item = items[selectedIndexRef.current];
          if (item !== void 0) {
            onTab(item);
            return true;
          }
        }
        if (key.return && itemsLength > 0) {
          const item = items[selectedIndexRef.current];
          if (item !== void 0) {
            onSelect(item);
            return true;
          }
        }
        return false;
      }
    }),
    [isVisible, isLoading, items, handleSelectIndex, onClose, onSelect, onTab]
  );
  if (!isVisible) return null;
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", children: [
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: borderColor, bold: true, children: title }) }),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { flexDirection: "column", height: viewportItems, marginTop: 1, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: loadingMessage }) }),
      Array.from({ length: Math.max(0, viewportItems - 1) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }) }, `loading-spacer-${index}`))
    ] }) : items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: emptyMessage }) }),
      Array.from({ length: Math.max(0, viewportItems - 1) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }) }, `empty-spacer-${index}`))
    ] }) : Array.from({ length: viewportItems }, (_, rowIndex) => {
      const item = visibleItems[rowIndex];
      if (item === void 0) {
        return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }) }, `item-empty-${rowIndex}`);
      }
      const actualIndex = scrollOffset + rowIndex;
      const isSelected = actualIndex === selectedIndex;
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, children: formatItem(item, isSelected) }, actualIndex);
    }) }),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { paddingX: 0, paddingY: 0, marginTop: 1, children: instructionsOverride ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", wrap: "truncate-end", children: instructionsOverride }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_HintBar.HintBar,
      {
        hints: [
          "\u2191\u2193 navigate",
          supportsTab ? "Tab load" : "",
          "Enter select",
          "Esc close"
        ]
      }
    ) })
  ] });
}
const BaseSelector = (0, import_react.forwardRef)(BaseSelectorInner);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  BaseSelector
});
