import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
import { NavigationSearch } from "@/components/dashboard/NavigationSearch";
import { globalSearch } from "@/actions/global-search";
import { vi, describe, it, expect, beforeEach } from "vitest";
import React from "react";
import { DashboardThemeProvider } from "@/components/dashboard/DashboardThemeProvider";

// Mock next/navigation
vi.mock("next/navigation", () => ({
  useRouter: () => ({
    push: vi.fn(),
  }),
}));

// Mock globalSearch server action
vi.mock("@/actions/global-search", () => ({
  globalSearch: vi.fn(),
}));

const Wrapper = ({ children }: { children: React.ReactNode }) => (
  <DashboardThemeProvider>
    {children}
  </DashboardThemeProvider>
);

describe("NavigationSearch Performance", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should cache results to avoid redundant server calls", async () => {
    const mockResults = {
      success: true,
      data: {
        products: [{ id: "1", title: "Product 1", type: "Product", href: "/p/1" }],
        orders: [],
        users: []
      }
    };

    vi.mocked(globalSearch).mockResolvedValue(mockResults as any);

    render(<NavigationSearch />, { wrapper: Wrapper });
    const input = screen.getByLabelText("Zur Seite navigieren");

    // 1. Search for "test"
    await act(async () => {
      fireEvent.change(input, { target: { value: "test" } });
    });

    // Wait for debounce (300ms)
    await act(async () => {
      await new Promise(resolve => setTimeout(resolve, 350));
    });

    expect(globalSearch).toHaveBeenCalledTimes(1);

    // 2. Clear and search for something else
    await act(async () => {
      fireEvent.change(input, { target: { value: "other" } });
    });

    await act(async () => {
      await new Promise(resolve => setTimeout(resolve, 350));
    });

    expect(globalSearch).toHaveBeenCalledTimes(2);

    // 3. Search for "test" again - should be cached
    await act(async () => {
      fireEvent.change(input, { target: { value: "test" } });
    });

    await act(async () => {
      await new Promise(resolve => setTimeout(resolve, 350));
    });

    // Should still be 2 because "test" was cached
    expect(globalSearch).toHaveBeenCalledTimes(2);
  });
});
