import { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { afterEach, describe, expect, it, vi } from "vitest";
import { ForbiddenMessage } from "./ForbiddenMessage";

const authState = {
  user: {
    profile: {
      role: "user",
    },
  },
};

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

vi.mock("../../lib/i18n", () => ({
  t: (key: string, fallback?: string, vars?: Record<string, unknown>) => {
    let text = fallback ?? key;
    for (const [name, value] of Object.entries(vars ?? {})) {
      text = text.replaceAll(`{{${name}}}`, String(value));
    }
    return text;
  },
}));

const roots: Root[] = [];

afterEach(() => {
  for (const root of roots.splice(0)) {
    act(() => {
      root.unmount();
    });
  }
});

async function renderMessage(resourceToken: "audit" | "clients" | "consents") {
  const container = document.createElement("div");
  document.body.appendChild(container);
  const root = createRoot(container);
  roots.push(root);

  await act(async () => {
    root.render(<ForbiddenMessage resourceToken={resourceToken} />);
  });

  return container;
}

describe("ForbiddenMessage", () => {
  it("renders resource-specific user guidance", async () => {
    authState.user.profile.role = "user";

    const audit = await renderMessage("audit");
    expect(audit.textContent).toContain("Audit Logs");
    expect(audit.textContent).toContain("audit read relationship");

    const consents = await renderMessage("consents");
    expect(consents.textContent).toContain("User Consent Grants");
    expect(consents.textContent).toContain("operational relationship");

    const clients = await renderMessage("clients");
    expect(clients.textContent).toContain("Connected Applications");
    expect(clients.textContent).toContain("target application");
  });

  it("renders specific guidance for privileged admin roles", async () => {
    authState.user.profile.role = "rp_admin";
    const rpAdmin = await renderMessage("clients");
    expect(rpAdmin.textContent).toContain(
      "RP administrators can only access resources for their assigned applications.",
    );

    authState.user.profile.role = "tenant_admin";
    const tenantAdmin = await renderMessage("clients");
    expect(tenantAdmin.textContent).toContain(
      "Tenant administrator permissions are not configured correctly or have expired.",
    );
  });
});
