import { renderHook, act } from "@testing-library/react";
import { useComboboxHighlight } from "./useComboboxHighlight";

describe("useComboboxHighlight", () => {
  describe("clear", () => {
    it("should set index to -1 with empty options", () => {
      const { result } = renderHook(() => useComboboxHighlight([]));
      expect(result.current.highlightedIndex).toBe(-1);

      act(() => {
        result.current.clearHighlight();
      });

      expect(result.current.highlightedIndex).toBe(-1);
    });

    it("should clear the highlighted index with non-empty options", () => {
      const { result } = renderHook(() => useComboboxHighlight(["Apple"]));

      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(0); // Can't go beyond 0 with single option

      act(() => {
        result.current.clearHighlight();
      });
      expect(result.current.highlightedIndex).toBe(0);
    });

    it("should maintain highlighted group index at 0", () => {
      const options = [
        { heading: "Fruits", options: ["Apple", "Banana"] },
        { heading: "Vegetables", options: ["Carrot"] },
      ];
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(1);
      expect(result.current.highlightedGroupIndex).toBe(0);

      act(() => {
        result.current.clearHighlight();
      });
      expect(result.current.highlightedGroupIndex).toBe(0);
      expect(result.current.highlightedIndex).toBe(0);
    });
  });

  describe("ungrouped", () => {
    const options = ["Apple", "Banana", "Cherry"];

    it("should highlight next option", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(1);

      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(2);
    });

    it("should stop at last option when highlighting next", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(2);
    });

    it("should highlight previous option", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightPreviousOption();
      });
      expect(result.current.highlightedIndex).toBe(1);
    });

    it("should stop at first option when highlighting previous", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightPreviousOption();
      });
      expect(result.current.highlightedIndex).toBe(0);
    });
  });

  describe("grouped", () => {
    const options = [
      { heading: "Fruits", options: ["Apple", "Banana"] },
      { heading: "Vegetables", options: ["Carrot", "Daikon"] },
    ];

    it("should highlight next option within group", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(1);
      expect(result.current.highlightedGroupIndex).toBe(0);
    });

    it("should move to next group when reaching end of current group", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(0);
      expect(result.current.highlightedGroupIndex).toBe(1);
    });

    it("should stop at last option of last group", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedIndex).toBe(1);
      expect(result.current.highlightedGroupIndex).toBe(1);
    });

    it("should highlight previous option within group", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightPreviousOption();
      });
      expect(result.current.highlightedIndex).toBe(0);
      expect(result.current.highlightedGroupIndex).toBe(0);
    });

    it("should move to previous group from start of current group", () => {
      const { result } = renderHook(() => useComboboxHighlight(options));

      // Move to second group first
      act(() => {
        result.current.highlightNextOption();
      });
      act(() => {
        result.current.highlightNextOption();
      });
      expect(result.current.highlightedGroupIndex).toBe(1);
      expect(result.current.highlightedIndex).toBe(0);

      // Move back to previous group
      act(() => {
        result.current.highlightPreviousOption();
      });
      expect(result.current.highlightedGroupIndex).toBe(0);
      expect(result.current.highlightedIndex).toBe(1);
    });
  });

  describe("highlightFirstOption/LastOption", () => {
    describe("ungrouped", () => {
      const options = ["Apple", "Banana", "Cherry"];

      it("should highlight first option", () => {
        const { result } = renderHook(() => useComboboxHighlight(options));

        act(() => {
          result.current.highlightFirstOption();
        });
        expect(result.current.highlightedIndex).toBe(0);
      });

      it("should highlight last option", () => {
        const { result } = renderHook(() => useComboboxHighlight(options));

        act(() => {
          result.current.highlightLastOption();
        });
        expect(result.current.highlightedIndex).toBe(2);
      });
    });

    describe("grouped", () => {
      const options = [
        { heading: "Fruits", options: ["Apple", "Banana"] },
        { heading: "Vegetables", options: ["Carrot", "Daikon", "Fig"] },
      ];

      it("should highlight first option of first group", () => {
        const { result } = renderHook(() => useComboboxHighlight(options));

        act(() => {
          result.current.highlightFirstOption();
        });
        expect(result.current.highlightedGroupIndex).toBe(0);
        expect(result.current.highlightedIndex).toBe(0);
      });

      it("should highlight last option of last group", () => {
        const { result } = renderHook(() => useComboboxHighlight(options));

        act(() => {
          result.current.highlightLastOption();
        });
        expect(result.current.highlightedGroupIndex).toBe(1);
        expect(result.current.highlightedIndex).toBe(2);
      });
    });
  });
});
