#!/usr/bin/env node
import {
  ARROW_DOWN,
  ARROW_LEFT,
  ARROW_RIGHT,
  ARROW_UP,
  ENTER,
  ESCAPE,
  INPUT_DELAY_MS,
  RENDER_DELAY_MS,
  SPACE,
  delay
} from "../../chunk-YZTWZVGX.js";
import {
  render
} from "../../chunk-66UDJBF6.js";
import {
  afterEach,
  describe,
  globalExpect,
  it,
  vi
} from "../../chunk-XY3XDVMI.js";
import {
  SourceGrid
} from "../../chunk-FXQYEXLS.js";
import "../../chunk-7SOPVGDV.js";
import "../../chunk-VSZ5GDET.js";
import "../../chunk-KUV24B5M.js";
import "../../chunk-GG4BSB6S.js";
import "../../chunk-FTD5Z6QD.js";
import {
  init_esm_shims
} from "../../chunk-DHET7RCE.js";

// src/cli/components/wizard/source-grid.test.tsx
init_esm_shims();
import { jsx } from "react/jsx-runtime";
var createSourceOption = (id, label, overrides = {}) => ({
  id,
  label,
  selected: false,
  installed: false,
  ...overrides
});
var createSourceRow = (skillId, displayName, options) => ({
  skillId,
  displayName,
  alias: displayName,
  options
});
var defaultRows = [
  createSourceRow("web-framework-react", "react", [
    createSourceOption("public", "Public", { selected: true })
  ]),
  createSourceRow("web-state-zustand", "zustand", [
    createSourceOption("public", "Public", { selected: true })
  ]),
  createSourceRow("web-testing-vitest", "vitest", [
    createSourceOption("public", "Public", { selected: true })
  ])
];
var multiSourceRows = [
  createSourceRow("web-framework-react", "react", [
    createSourceOption("public", "Public", { selected: true }),
    createSourceOption("acme-corp", "Acme Corp")
  ]),
  createSourceRow("web-state-zustand", "zustand", [
    createSourceOption("public", "Public", { selected: true }),
    createSourceOption("acme-corp", "Acme Corp"),
    createSourceOption("internal", "Internal")
  ])
];
var defaultProps = {
  rows: defaultRows,
  defaultFocusedRow: 0,
  defaultFocusedCol: 0,
  onSelect: vi.fn(),
  onFocusChange: vi.fn()
};
var renderGrid = (props = {}) => {
  return render(/* @__PURE__ */ jsx(SourceGrid, { ...defaultProps, ...props }));
};
describe("SourceGrid component", () => {
  let cleanup;
  afterEach(() => {
    cleanup?.();
    cleanup = void 0;
  });
  describe("rendering", () => {
    it("should render all skill rows", () => {
      const { lastFrame, unmount } = renderGrid();
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("react");
      globalExpect(output).toContain("zustand");
      globalExpect(output).toContain("vitest");
    });
    it("should render source option labels", () => {
      const { lastFrame, unmount } = renderGrid();
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("Public");
    });
    it("should render multiple source options per row", () => {
      const { lastFrame, unmount } = renderGrid({ rows: multiSourceRows });
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("Public");
      globalExpect(output).toContain("Acme Corp");
    });
    it("should handle empty rows array", () => {
      const { lastFrame, unmount } = renderGrid({ rows: [] });
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("No skills to display");
    });
    it("should render single row", () => {
      const rows = [
        createSourceRow("web-framework-react", "react", [
          createSourceOption("public", "Public", { selected: true })
        ])
      ];
      const { lastFrame, unmount } = renderGrid({ rows });
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("react");
      globalExpect(output).toContain("Public");
    });
  });
  describe("keyboard navigation - vertical", () => {
    it("should move down with arrow down", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_DOWN);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(1, 0);
    });
    it("should move up with arrow up", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 1,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_UP);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
    });
    it("should wrap down to first row from last row", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 2,
        // Last row (Vitest)
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_DOWN);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
    });
    it("should wrap up to last row from first row", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_UP);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(2, 0);
    });
    it("should clamp column when moving to row with fewer options", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 1,
        // Zustand has 3 options
        defaultFocusedCol: 2,
        // Internal (index 2)
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_UP);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
    });
  });
  describe("keyboard navigation - horizontal", () => {
    it("should move right with arrow right", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_RIGHT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
    });
    it("should move left with arrow left", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_LEFT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
    });
    it("should wrap right to first column from last column", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        // Last option in React row
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_RIGHT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
    });
    it("should wrap left to last column from first column", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_LEFT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
    });
  });
  describe("selection", () => {
    it("should call onSelect when pressing space", async () => {
      const onSelect = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onSelect
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(" ");
      await delay(INPUT_DELAY_MS);
      globalExpect(onSelect).toHaveBeenCalledWith("web-framework-react", "public");
    });
    it("should call onSelect with correct skill and source IDs", async () => {
      const onSelect = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        // Acme Corp
        onSelect
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(" ");
      await delay(INPUT_DELAY_MS);
      globalExpect(onSelect).toHaveBeenCalledWith("web-framework-react", "acme-corp");
    });
    it("should call onSelect on second row", async () => {
      const onSelect = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: multiSourceRows,
        defaultFocusedRow: 1,
        defaultFocusedCol: 2,
        // Internal
        onSelect
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(" ");
      await delay(INPUT_DELAY_MS);
      globalExpect(onSelect).toHaveBeenCalledWith("web-state-zustand", "internal");
    });
  });
  describe("edge cases", () => {
    it("should handle single option per row", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_RIGHT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
    });
    it("should handle many rows", () => {
      const rows = Array.from(
        { length: 10 },
        (_, i) => createSourceRow(`web-test-${i}`, `test-${i}`, [
          createSourceOption("public", "Public", { selected: true })
        ])
      );
      const { lastFrame, unmount } = renderGrid({ rows });
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("test-0");
      globalExpect(output).toContain("test-9");
    });
  });
  describe("search pill", () => {
    const mockSearch = vi.fn();
    const mockBind = vi.fn();
    const mockSearchStateChange = vi.fn();
    const searchCandidates = [
      {
        id: "web-framework-react-pro",
        sourceUrl: "github:awesome-dev/skills",
        sourceName: "awesome-dev",
        alias: "react"
      },
      {
        id: "web-framework-react-strict",
        sourceUrl: "github:team-xyz/skills",
        sourceName: "team-xyz",
        alias: "react"
      }
    ];
    afterEach(() => {
      mockSearch.mockReset();
      mockBind.mockReset();
      mockSearchStateChange.mockReset();
    });
    it("should render search pill at end of each row when onSearch is provided", () => {
      const { lastFrame, unmount } = renderGrid({
        onSearch: mockSearch
      });
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).toContain("Search");
    });
    it("should not render search pill when onSearch is not provided", () => {
      const { lastFrame, unmount } = renderGrid();
      cleanup = unmount;
      const output = lastFrame();
      globalExpect(output).not.toContain("Search");
    });
    it("should navigate to search pill with arrow right", async () => {
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 0,
        // On the only option (Public)
        onFocusChange,
        onSearch: mockSearch
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(ARROW_RIGHT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).toHaveBeenCalledWith(0, 1);
    });
    it("should not call onSelect when space is pressed on search pill", async () => {
      const onSelect = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        // Search pill position (after Public)
        onSelect,
        onSearch: mockSearch
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(" ");
      await delay(INPUT_DELAY_MS);
      globalExpect(onSelect).not.toHaveBeenCalled();
    });
    it("should trigger search on Space when search pill is focused", async () => {
      mockSearch.mockResolvedValue(searchCandidates);
      const { stdin, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        // Search pill position
        onSearch: mockSearch,
        onSearchStateChange: mockSearchStateChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(SPACE);
      await delay(INPUT_DELAY_MS);
      globalExpect(mockSearch).toHaveBeenCalledWith("react");
      globalExpect(mockSearchStateChange).toHaveBeenCalledWith(true);
    });
    it("should render modal with results after search completes", async () => {
      mockSearch.mockResolvedValue(searchCandidates);
      const { stdin, lastFrame, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        onSearch: mockSearch
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(SPACE);
      await delay(RENDER_DELAY_MS);
      const output = lastFrame();
      globalExpect(output).toContain("react");
      globalExpect(output).toContain("awesome-dev");
      globalExpect(output).toContain("team-xyz");
    });
    it("should close modal on Escape without binding", async () => {
      mockSearch.mockResolvedValue(searchCandidates);
      const { stdin, lastFrame, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        onSearch: mockSearch,
        onBind: mockBind,
        onSearchStateChange: mockSearchStateChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(SPACE);
      await delay(RENDER_DELAY_MS);
      stdin.write(ESCAPE);
      await delay(INPUT_DELAY_MS);
      globalExpect(mockBind).not.toHaveBeenCalled();
      globalExpect(mockSearchStateChange).toHaveBeenLastCalledWith(false);
      const output = lastFrame();
      globalExpect(output).not.toContain("awesome-dev");
    });
    it("should not respond to grid navigation while modal is open", async () => {
      mockSearch.mockResolvedValue(searchCandidates);
      const onFocusChange = vi.fn();
      const { stdin, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        onSearch: mockSearch,
        onFocusChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(SPACE);
      await delay(RENDER_DELAY_MS);
      onFocusChange.mockClear();
      stdin.write(ARROW_LEFT);
      await delay(INPUT_DELAY_MS);
      stdin.write(ARROW_RIGHT);
      await delay(INPUT_DELAY_MS);
      globalExpect(onFocusChange).not.toHaveBeenCalled();
    });
    it("should bind result on Enter in modal", async () => {
      mockSearch.mockResolvedValue(searchCandidates);
      const { stdin, unmount } = renderGrid({
        rows: defaultRows,
        defaultFocusedRow: 0,
        defaultFocusedCol: 1,
        onSearch: mockSearch,
        onBind: mockBind,
        onSearchStateChange: mockSearchStateChange
      });
      cleanup = unmount;
      await delay(RENDER_DELAY_MS);
      stdin.write(SPACE);
      await delay(RENDER_DELAY_MS);
      stdin.write(ENTER);
      await delay(INPUT_DELAY_MS);
      globalExpect(mockBind).toHaveBeenCalledWith(searchCandidates[0]);
      globalExpect(mockSearchStateChange).toHaveBeenLastCalledWith(false);
    });
  });
});
//# sourceMappingURL=source-grid.test.js.map