import {
  render,
  screen,
  fireEvent,
  waitFor,
} from "@testing-library/react";
import { SearchBar } from "./SearchBar";
import { vi, describe, it, expect, beforeEach } from "vitest";
import { searchProducts } from "@/lib/product-actions";
import React from "react";

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

// Mock searchProducts action
vi.mock("@/lib/product-actions", () => ({
  searchProducts: vi.fn(),
}));

// Mock formatCurrency
vi.mock("@/lib/format", () => ({
  formatCurrency: (val: number) => `${val} €`,
}));

// Mock logClientError
vi.mock("@/actions/logging", () => ({
  logClientError: vi.fn(),
}));

describe("SearchBar", () => {
  const mockProducts = [
    { id: "1", title: "Laptop", price: 999.99, image: "/laptop.jpg" },
    { id: "2", title: "Smartphone", price: 599.99, image: "/phone.jpg" },
  ];

  beforeEach(() => {
    vi.clearAllMocks();
    // Default mock implementation
    vi.mocked(searchProducts).mockResolvedValue({
      success: true,
      data: { documents: mockProducts, total: 2 },
      code: 200
    });
  });

  it("renders the search input", () => {
    render(<SearchBar />);
    expect(screen.getByPlaceholderText(/durchsuchen/i)).toBeInTheDocument();
  });

  it("updates input value on change", () => {
    render(<SearchBar />);
    const input = screen.getByPlaceholderText(/durchsuchen/i) as HTMLInputElement;
    fireEvent.change(input, { target: { value: "test" } });
    expect(input.value).toBe("test");
  });

  it("shows results when typing more than 2 characters", async () => {
    render(<SearchBar />);
    const input = screen.getByPlaceholderText(/durchsuchen/i);
    fireEvent.change(input, { target: { value: "lap" } });
    fireEvent.focus(input);

    await waitFor(() => {
      expect(screen.getByText("Laptop")).toBeInTheDocument();
      expect(screen.getByText("Smartphone")).toBeInTheDocument();
    });
  });

  it("navigates to search page on submit", () => {
    render(<SearchBar />);
    const input = screen.getByPlaceholderText(/durchsuchen/i);
    fireEvent.change(input, { target: { value: "test query" } });
    fireEvent.submit(screen.getByRole("combobox").closest("form")!);
    
    expect(mockPush).toHaveBeenCalledWith("/search?q=test query");
  });

  it("handles search error gracefully", async () => {
    vi.mocked(searchProducts).mockResolvedValue({
      success: false,
      error: "Search failed",
      code: 500
    });

    render(<SearchBar />);
    const input = screen.getByPlaceholderText(/durchsuchen/i);
    fireEvent.change(input, { target: { value: "error" } });
    fireEvent.focus(input);

    await waitFor(() => {
      expect(screen.getAllByText("Keine Ergebnisse gefunden")[0]).toBeInTheDocument();
    });
  });
});
