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

const mockSigninRedirect = vi.fn();
const mockUseAuth = vi.fn();

vi.mock("react-oidc-context", () => ({
  useAuth: () => mockUseAuth(),
}));

function renderLoginPage(initialEntry: string) {
  return render(
    <MemoryRouter initialEntries={[initialEntry]}>
      <LoginPage />
    </MemoryRouter>,
  );
}

describe("LoginPage", () => {
  beforeEach(() => {
    Object.defineProperty(window, "crypto", {
      configurable: true,
      value: {},
    });
    Object.defineProperty(window, "isSecureContext", {
      configurable: true,
      value: false,
    });
    mockSigninRedirect.mockReset();
    mockUseAuth.mockReturnValue({
      activeNavigator: undefined,
      error: undefined,
      isAuthenticated: false,
      isLoading: false,
      signinRedirect: mockSigninRedirect,
    });
  });

  it("shows an actionable error instead of starting PKCE when WebCrypto is unavailable", async () => {
    renderLoginPage("/login?returnTo=%2F");

    await userEvent.click(
      screen.getByRole("button", { name: /SSO 계정으로 로그인/i }),
    );

    expect(mockSigninRedirect).not.toHaveBeenCalled();
    expect(screen.getByRole("alert")).toHaveTextContent(
      /SSO 로그인을 시작할 수 없습니다/,
    );
  });

  it("preserves the returnTo query when starting SSO manually", async () => {
    Object.defineProperty(window, "crypto", {
      configurable: true,
      value: { subtle: {} },
    });
    Object.defineProperty(window, "isSecureContext", {
      configurable: true,
      value: true,
    });
    renderLoginPage("/login?returnTo=%2Fusers%3Fpage%3D2");

    await userEvent.click(
      screen.getByRole("button", { name: /SSO 계정으로 로그인/i }),
    );

    expect(mockSigninRedirect).toHaveBeenCalledWith({
      state: {
        returnTo: "/users?page=2",
      },
    });
  });
});
