import React from "react";
import { render } from "@testing-library/react";
import OverviewPage from "@/app/(private)/dashboard/products/overview/page";
import { getAdminProducts } from "@/lib/product-actions";
import { vi, describe, it, expect, beforeEach } from "vitest";

// Mock the server action in its correct location
vi.mock("@/lib/product-actions", () => ({
  getAdminProducts: vi.fn(),
}));

// Mock next/navigation
vi.mock("next/navigation", () => ({
  useRouter: () => ({ push: vi.fn(), refresh: vi.fn() }),
  usePathname: () => "/dashboard/products/overview",
  useSearchParams: () => new URLSearchParams(),
  notFound: vi.fn(),
}));

// Mock the client component
vi.mock("@/app/(private)/dashboard/products/overview/OverviewClient", () => ({
  default: ({ initialData }: any) => (
    <div data-testid="overview-client">
      {initialData?.documents?.length || 0} products loaded
    </div>
  ),
}));

// Mock the skeleton component
vi.mock("@/components/dashboard/shared/DataTableSkeleton", () => ({
  DataTableSkeleton: () => <div data-testid="skeleton">Loading...</div>,
}));

// Mock the error component
vi.mock("@/components/dashboard/shared/InlineError", () => ({
  InlineError: ({ message }: { message: string }) => <div data-testid="error">{message}</div>,
}));

describe("Products Overview Performance: SSR Refactor", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("should fetch products on the server and pass them to the client component", async () => {
    const mockProducts = {
      success: true,
      data: {
        total: 1,
        documents: [
          { id: "1", title: "Test Product", price: "10.00", image: "" }
        ]
      }
    };
    vi.mocked(getAdminProducts).mockResolvedValue(mockProducts as any);

    const searchParams = Promise.resolve({
      page: "2",
      pageSize: "20",
      sortBy: "price",
      sortOrder: "DESC"
    });

    // Call the server component
    const PageComponent = await OverviewPage({ searchParams });
    const { getByTestId } = render(PageComponent);

    // Verify server-side fetch was called with correct parameters from URL
    expect(getAdminProducts).toHaveBeenCalledWith({
        page: 2,
        pageSize: 20,
        query: undefined,
        sortBy: "price",
        sortOrder: "DESC"
    });

    // Verify the data was passed to the client component
    expect(getByTestId("overview-client").textContent).toContain("1 products loaded");
  });

  it("should use default parameters when none are provided in URL", async () => {
    vi.mocked(getAdminProducts).mockResolvedValue({ success: true, data: { total: 0, documents: [] } } as any);

    const searchParams = Promise.resolve({});

    await OverviewPage({ searchParams });

    expect(getAdminProducts).toHaveBeenCalledWith({
        page: 1,
        pageSize: 10,
        query: undefined,
        sortBy: "created_at",
        sortOrder: "DESC"
    });
  });

  it("should show InlineError when getAdminProducts fails", async () => {
    vi.mocked(getAdminProducts).mockResolvedValue({ 
      success: false, 
      error: "Something went wrong",
      code: 500
    } as any);

    const searchParams = Promise.resolve({});

    const PageComponent = await OverviewPage({ searchParams });
    const { getByTestId } = render(PageComponent);

    expect(getByTestId("error")).toBeInTheDocument();
    expect(getByTestId("error").textContent).toBe("Something went wrong");
  });
});
