import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";

// Mock external dependencies (navigation, auth, data fetching) so the test
// covers only this component's behavior.
type MeResult = [{ data: { me: { id: string; name: string; email: string } | null } | undefined }];

const { logout, navigate, useQueryMock } = vi.hoisted(() => ({
  logout: vi.fn(),
  navigate: vi.fn(),
  useQueryMock: vi.fn<() => MeResult>(),
}));

vi.mock("@tailor-platform/app-shell", () => ({
  useAuth: () => ({ logout }),
  useNavigate: () => navigate,
}));

vi.mock("urql", () => ({
  useQuery: () => useQueryMock(),
}));

vi.mock("@/graphql", () => ({
  graphql: (query: string) => query,
}));

import { UserProfileMenu } from "./user-profile-menu";

describe("user-profile-menu", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    useQueryMock.mockReturnValue([
      { data: { me: { id: "user-1", name: "Ada Lovelace", email: "ada@example.com" } } },
    ]);
  });

  it("renders the signed-in user's name and email", () => {
    render(<UserProfileMenu />);
    expect(screen.getByText("Ada Lovelace")).toBeInTheDocument();
    expect(screen.getByText("ada@example.com")).toBeInTheDocument();
  });

  it("shows a placeholder while the profile is loading", () => {
    useQueryMock.mockReturnValue([{ data: undefined }]);
    render(<UserProfileMenu />);
    expect(screen.getByText("...")).toBeInTheDocument();
  });

  it("navigates to the profile page when the profile button is clicked", async () => {
    render(<UserProfileMenu />);
    await userEvent.click(screen.getByTitle("View profile"));
    expect(navigate).toHaveBeenCalledWith("/user-management/profile");
  });

  it("logs out when the sign out button is clicked", async () => {
    render(<UserProfileMenu />);
    await userEvent.click(screen.getByTitle("Sign out"));
    expect(logout).toHaveBeenCalledOnce();
  });
});
