import { screen } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import * as clientSessionHooks from "../hooks/useClientSession";
import AppRoutes from "../routes";
import { renderWithProviders } from "../test/testHelpers";
import { ClientLayout } from "./ClientLayout";

describe("ClientLayout", () => {
  beforeEach(() => {
    vi.restoreAllMocks();
    Object.defineProperty(window, "matchMedia", {
      writable: true,
      value: vi.fn().mockImplementation(() => ({
        addEventListener: vi.fn(),
        addListener: vi.fn(),
        dispatchEvent: vi.fn(),
        matches: false,
        media: "",
        onchange: null,
        removeEventListener: vi.fn(),
        removeListener: vi.fn(),
      })),
    });
    vi.spyOn(clientSessionHooks, "useRequestClientMagicLink").mockReturnValue({
      isPending: false,
      mutateAsync: vi.fn(),
    } as unknown as ReturnType<typeof clientSessionHooks.useRequestClientMagicLink>);
    vi.spyOn(clientSessionHooks, "useClientLogout").mockReturnValue({
      isPending: false,
      mutateAsync: vi.fn(),
    } as unknown as ReturnType<typeof clientSessionHooks.useClientLogout>);
  });

  it("uses the main app style header shell and scrolling main viewport", () => {
    vi.spyOn(clientSessionHooks, "useClientSession").mockReturnValue({
      data: {
        id: "client-1",
        email: "client@example.com",
      },
    } as ReturnType<typeof clientSessionHooks.useClientSession>);

    const { container } = renderWithProviders(<ClientLayout />);

    const header = container.querySelector("header");
    expect(header).toHaveClass("h-[75px]");
    expect(header).toHaveClass("bg-navbar-background");

    const headerInner = header?.firstElementChild;
    expect(headerInner).toHaveClass("w-full");
    expect(headerInner).toHaveClass("max-w-7xl");
    expect(headerInner).toHaveClass("mx-auto");

    const main = container.querySelector("main");
    expect(main).toHaveClass("flex-1");
    expect(main).toHaveClass("overflow-auto");
    expect(main).not.toHaveClass("max-w-7xl");
    expect(main).not.toHaveClass("mx-auto");

    const contentWrapper = main?.firstElementChild;
    expect(contentWrapper).toHaveClass("mx-auto");
    expect(contentWrapper).toHaveClass("w-full");
    expect(contentWrapper).toHaveClass("max-w-7xl");
    expect(contentWrapper).toHaveClass("px-4");
    expect(contentWrapper).toHaveClass("sm:px-6");
  });

  it("redirects unauthenticated client routes to the login page", async () => {
    vi.spyOn(clientSessionHooks, "useClientSession").mockReturnValue({
      data: null,
      isLoading: false,
    } as ReturnType<typeof clientSessionHooks.useClientSession>);

    renderWithProviders(<AppRoutes />, {
      route: "/tablo/tablo-1",
      testUser: undefined,
    });

    expect(await screen.findByTestId("auth-card-shell")).toBeInTheDocument();
    expect(
      await screen.findByRole("button", { name: "Recevoir un lien de connexion" })
    ).toBeInTheDocument();
  });
});
