import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createI18nMock } from "../../test/i18nMock";
import GlobalCustomClaimsPage from "./GlobalCustomClaimsPage";

const fetchGlobalCustomClaimDefinitionsMock = vi.hoisted(() => vi.fn());
const updateGlobalCustomClaimDefinitionsMock = vi.hoisted(() => vi.fn());

vi.mock("../../lib/i18n", () => createI18nMock());

vi.mock("../../lib/adminApi", () => ({
  fetchGlobalCustomClaimDefinitions: fetchGlobalCustomClaimDefinitionsMock,
  updateGlobalCustomClaimDefinitions: updateGlobalCustomClaimDefinitionsMock,
}));

vi.mock("../../components/ui/use-toast", () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

function renderGlobalCustomClaimsPage() {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter>
        <GlobalCustomClaimsPage />
      </MemoryRouter>
    </QueryClientProvider>,
  );
}

describe("GlobalCustomClaimsPage", () => {
  beforeEach(() => {
    fetchGlobalCustomClaimDefinitionsMock.mockReset();
    fetchGlobalCustomClaimDefinitionsMock.mockResolvedValue({
      items: [
        {
          key: "locale",
          label: "Locale",
          valueType: "text",
          readPermission: "admin_only",
          writePermission: "admin_only",
          description: "",
        },
      ],
    });
    updateGlobalCustomClaimDefinitionsMock.mockReset();
    updateGlobalCustomClaimDefinitionsMock.mockResolvedValue({ items: [] });
  });

  it("forces user read permission on when user write permission is enabled", async () => {
    renderGlobalCustomClaimsPage();

    const readSelect = await screen.findByTestId(
      "global-claim-definition-read-permission-locale",
    );
    const writeSelect = await screen.findByTestId(
      "global-claim-definition-write-permission-locale",
    );

    expect(readSelect).toHaveValue("admin_only");
    expect(writeSelect).toHaveValue("admin_only");

    fireEvent.change(writeSelect, { target: { value: "user_and_admin" } });

    await waitFor(() => {
      expect(readSelect).toHaveValue("user_and_admin");
      expect(writeSelect).toHaveValue("user_and_admin");
    });

    fireEvent.click(screen.getByRole("button", { name: /저장|Save/ }));

    await waitFor(() => {
      expect(updateGlobalCustomClaimDefinitionsMock).toHaveBeenCalled();
    });
    expect(updateGlobalCustomClaimDefinitionsMock.mock.calls[0][0]).toEqual({
      items: [
        expect.objectContaining({
          key: "locale",
          readPermission: "user_and_admin",
          writePermission: "user_and_admin",
        }),
      ],
    });
  });
});
