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

const { mockNavigate, mockRequestMagicLink } = vi.hoisted(() => ({
  mockNavigate: vi.fn(),
  mockRequestMagicLink: vi.fn(),
}));

vi.mock("react-router-dom", async (importOriginal) => {
  const actual = await importOriginal<typeof import("react-router-dom")>();
  return {
    ...actual,
    useNavigate: () => mockNavigate,
  };
});

describe("LoginPage", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
    vi.spyOn(clientSessionHooks, "useClientSession").mockReturnValue({
      data: null,
    } as ReturnType<typeof clientSessionHooks.useClientSession>);
    vi.spyOn(clientSessionHooks, "useRequestClientMagicLink").mockReturnValue({
      isPending: false,
      mutateAsync: mockRequestMagicLink,
    } as unknown as ReturnType<typeof clientSessionHooks.useRequestClientMagicLink>);
    mockRequestMagicLink.mockResolvedValue({
      message: "If this email can access the client portal, a connection link has been sent.",
      success: true,
    });
  });

  it("renders the shared auth shell and form", () => {
    renderWithProviders(<LoginPage />, { testUser: undefined });

    expect(screen.getByTestId("auth-card-shell")).toBeInTheDocument();
    expect(screen.getByLabelText("Email")).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "Recevoir un lien de connexion" })).toBeInTheDocument();
    expect(screen.getAllByAltText("Xtablo")[0]).toHaveAttribute(
      "src",
      "https://assets.xtablo.com/logo_dark.png"
    );
  });

  it("requests a magic link and forwards the stored redirect path", async () => {
    localStorage.setItem("clients.redirectUrl", "/tablo/tablo-42");
    renderWithProviders(<LoginPage />, { testUser: undefined });

    fireEvent.change(screen.getByLabelText("Email"), { target: { value: "client@example.com" } });
    fireEvent.click(screen.getByRole("button", { name: "Recevoir un lien de connexion" }));

    await waitFor(() => {
      expect(mockRequestMagicLink).toHaveBeenCalledWith({
        email: "client@example.com",
        redirectTo: "/tablo/tablo-42",
      });
    });

    expect(screen.getByText(/connection link has been sent/i)).toBeInTheDocument();
  });
});
