#!/usr/bin/env node
import {
  useModalState
} from "./chunk-7SOPVGDV.js";
import {
  SearchModal
} from "./chunk-VSZ5GDET.js";
import {
  useFocusedListItem
} from "./chunk-GG4BSB6S.js";
import {
  CLI_COLORS,
  SCROLL_VIEWPORT
} from "./chunk-FTD5Z6QD.js";
import {
  init_esm_shims
} from "./chunk-DHET7RCE.js";

// src/cli/components/wizard/source-grid.tsx
init_esm_shims();
import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
import { Box, Text, measureElement, useInput } from "ink";

// src/cli/components/hooks/use-source-grid-search-modal.ts
init_esm_shims();
import { useCallback, useState } from "react";
function useSourceGridSearchModal({
  rows,
  onSearch,
  onBind,
  onSearchStateChange
}) {
  const searchModal = useModalState();
  const [searchResults, setSearchResults] = useState([]);
  const [searchAlias, setSearchAlias] = useState("");
  const resetSearch = useCallback(() => {
    searchModal.close();
    setSearchResults([]);
    setSearchAlias("");
    onSearchStateChange?.(false);
  }, [onSearchStateChange, searchModal]);
  const handleSearchTrigger = useCallback(
    async (rowIndex) => {
      const row = rows[rowIndex];
      if (!row || !onSearch) return;
      const alias = row.alias;
      setSearchAlias(alias);
      searchModal.open(rowIndex);
      onSearchStateChange?.(true);
      const results = await onSearch(alias);
      setSearchResults(results);
    },
    [rows, onSearch, onSearchStateChange, searchModal]
  );
  const handleBind = useCallback(
    (candidate) => {
      onBind?.(candidate);
      resetSearch();
    },
    [onBind, resetSearch]
  );
  const handleCloseSearch = useCallback(() => {
    resetSearch();
  }, [resetSearch]);
  return {
    searchModal: { isOpen: searchModal.isOpen },
    searchResults,
    searchAlias,
    handleSearchTrigger,
    handleBind,
    handleCloseSearch
  };
}

// src/cli/components/wizard/source-grid.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var SEARCH_PILL_LABEL = "\u2315 Search";
var SearchPill = ({ isFocused }) => {
  const borderColor = isFocused ? CLI_COLORS.UNFOCUSED : CLI_COLORS.NEUTRAL;
  return /* @__PURE__ */ jsx(Box, { marginRight: 1, borderColor, borderStyle: "single", borderDimColor: !isFocused, children: /* @__PURE__ */ jsxs(Text, { dimColor: !isFocused, bold: isFocused, children: [
    " ",
    SEARCH_PILL_LABEL,
    " "
  ] }) });
};
var SourceTag = ({
  option,
  isFocused
}) => {
  const getBorderColor = () => {
    if (isFocused) {
      return option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.UNFOCUSED;
    }
    return CLI_COLORS.NEUTRAL;
  };
  const textColor = option.selected ? CLI_COLORS.PRIMARY : CLI_COLORS.NEUTRAL;
  const isBold = isFocused || option.selected;
  return /* @__PURE__ */ jsx(
    Box,
    {
      marginRight: 1,
      borderColor: getBorderColor(),
      borderStyle: "single",
      borderDimColor: !isFocused,
      children: /* @__PURE__ */ jsxs(Text, { color: textColor, bold: isBold, dimColor: false, children: [
        " ",
        option.label,
        " "
      ] })
    }
  );
};
var SourceSection = ({
  row,
  isFocused,
  focusedOptionIndex,
  showSearchPill
}) => {
  const searchPillIndex = row.options.length;
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
    /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { children: row.displayName }) }),
    /* @__PURE__ */ jsxs(Box, { flexDirection: "row", flexWrap: "wrap", marginTop: 0, children: [
      row.options.map((option, index) => /* @__PURE__ */ jsx(
        SourceTag,
        {
          option,
          isFocused: isFocused && index === focusedOptionIndex
        },
        option.id
      )),
      showSearchPill && /* @__PURE__ */ jsx(SearchPill, { isFocused: isFocused && focusedOptionIndex === searchPillIndex })
    ] })
  ] });
};
var getNavigableCount = (row, showSearchPill) => {
  return row.options.length + (showSearchPill ? 1 : 0);
};
var SourceGrid = ({
  rows,
  availableHeight = 0,
  onSelect,
  onSearch,
  onBind,
  onSearchStateChange,
  defaultFocusedRow = 0,
  defaultFocusedCol = 0,
  onFocusChange
}) => {
  const {
    searchModal,
    searchResults,
    searchAlias,
    handleSearchTrigger,
    handleBind,
    handleCloseSearch
  } = useSourceGridSearchModal({ rows, onSearch, onBind, onSearchStateChange });
  const showSearchPill = !!onSearch;
  const getColCount = useCallback2(
    (row) => {
      const rowData = rows[row];
      return rowData ? getNavigableCount(rowData, showSearchPill) : 0;
    },
    [rows, showSearchPill]
  );
  const { focusedRow, focusedCol, moveFocus } = useFocusedListItem(rows.length, getColCount, {
    wrap: true,
    onChange: onFocusChange,
    initialRow: defaultFocusedRow,
    initialCol: defaultFocusedCol
  });
  const sectionRefs = useRef([]);
  const [sectionHeights, setSectionHeights] = useState2([]);
  const [scrollTopPx, setScrollTopPx] = useState2(0);
  const setSectionRef = useCallback2((index, el) => {
    sectionRefs.current[index] = el;
  }, []);
  useEffect(() => {
    const heights = sectionRefs.current.map((el) => {
      if (el) {
        const { height } = measureElement(el);
        return height;
      }
      return 0;
    });
    setSectionHeights((prev) => {
      if (prev.length === heights.length && prev.every((h, i) => h === heights[i])) {
        return prev;
      }
      return heights;
    });
  });
  const scrollEnabled = availableHeight > 0 && availableHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;
  useEffect(() => {
    if (!scrollEnabled || sectionHeights.length === 0) return;
    let topOfFocused = 0;
    for (let i = 0; i < focusedRow; i++) {
      topOfFocused += sectionHeights[i] ?? 0;
    }
    const focusedHeight = sectionHeights[focusedRow] ?? 0;
    const bottomOfFocused = topOfFocused + focusedHeight;
    setScrollTopPx((prev) => {
      if (topOfFocused < prev) {
        return topOfFocused;
      }
      if (bottomOfFocused > prev + availableHeight) {
        return bottomOfFocused - availableHeight;
      }
      return prev;
    });
  }, [focusedRow, sectionHeights, scrollEnabled, availableHeight]);
  useInput(
    useCallback2(
      (input, key) => {
        if (input === " ") {
          const currentRow = rows[focusedRow];
          if (!currentRow) return;
          if (showSearchPill && focusedCol === currentRow.options.length) {
            void handleSearchTrigger(focusedRow);
            return;
          }
          if (focusedCol < currentRow.options.length) {
            const currentOption = currentRow.options[focusedCol];
            if (currentOption) {
              onSelect(currentRow.skillId, currentOption.id);
            }
          }
          return;
        }
        const isLeft = key.leftArrow;
        const isRight = key.rightArrow;
        const isUp = key.upArrow;
        const isDown = key.downArrow;
        if (isLeft) {
          moveFocus("left");
        } else if (isRight) {
          moveFocus("right");
        } else if (isUp) {
          moveFocus("up");
        } else if (isDown) {
          moveFocus("down");
        }
      },
      [rows, focusedRow, focusedCol, onSelect, showSearchPill, handleSearchTrigger, moveFocus]
    ),
    { isActive: !searchModal.isOpen }
  );
  if (rows.length === 0) {
    return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No skills to display." }) });
  }
  const sectionElements = rows.map((row, rowIndex) => /* @__PURE__ */ jsx(Box, { ref: (el) => setSectionRef(rowIndex, el), flexShrink: 0, children: /* @__PURE__ */ jsx(
    SourceSection,
    {
      row,
      isFocused: rowIndex === focusedRow,
      focusedOptionIndex: focusedCol,
      showSearchPill
    }
  ) }, row.skillId));
  const searchModalElement = searchModal.isOpen && /* @__PURE__ */ jsx(
    SearchModal,
    {
      results: searchResults,
      alias: searchAlias,
      onBind: handleBind,
      onClose: handleCloseSearch
    }
  );
  if (!scrollEnabled) {
    return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
      /* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: sectionElements }),
      searchModalElement
    ] });
  }
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: availableHeight, children: [
    /* @__PURE__ */ jsx(Box, { flexDirection: "column", overflow: "hidden", flexGrow: 1, children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: scrollTopPx > 0 ? -scrollTopPx : 0, flexShrink: 0, children: sectionElements }) }),
    searchModalElement
  ] });
};

export {
  SourceGrid
};
//# sourceMappingURL=chunk-FXQYEXLS.js.map