import { matchRoutes } from "react-router-dom";
import { describe, expect, it } from "vitest";
import { buildAdminAuthRedirectUris } from "../lib/authConfig";
import { adminRoutes } from "./routes";

describe("admin routes", () => {
  it("accepts the auth callback path generated from the public admin URL", () => {
    const { redirectUri } = buildAdminAuthRedirectUris(
      "https://sadmin.hmac.kr",
    );
    const callbackPath = new URL(redirectUri).pathname;

    const matches = matchRoutes(adminRoutes, callbackPath);

    expect(callbackPath).toBe("/auth/callback");
    expect(matches?.at(-1)?.route.path).toBe("/auth/callback");
  });

  it("registers the super-admin Ory SSOT system route", () => {
    const matches = matchRoutes(adminRoutes, "/system/ory-ssot");

    expect(matches?.at(-1)?.route.path).toBe("system/ory-ssot");
  });

  it("registers the super-admin data integrity management route", () => {
    const matches = matchRoutes(adminRoutes, "/system/data-integrity");

    expect(matches?.at(-1)?.route.path).toBe("system/data-integrity");
  });

  it("routes global custom claim settings before user detail id matching", () => {
    const matches = matchRoutes(adminRoutes, "/users/custom-claims");
    const leafRoute = matches?.at(-1)?.route;

    expect(leafRoute?.path).toBe("users/custom-claims");
    expect(getRouteElementName(leafRoute?.element)).toBe(
      "GlobalCustomClaimsPage",
    );
  });

  it("keeps protected admin pages behind an auth guard before mounting the layout", () => {
    const rootRoute = adminRoutes.find((route) => route.path === "/");
    const protectedShellRoute = rootRoute?.children?.[0];

    expect(getRouteElementName(rootRoute?.element)).toBe("AuthGuard");
    expect(getRouteElementName(protectedShellRoute?.element)).toBe("AppLayout");
    expect(protectedShellRoute?.children?.at(0)?.index).toBe(true);
  });
});

function getRouteElementName(element: unknown) {
  if (
    typeof element === "object" &&
    element !== null &&
    "type" in element &&
    typeof element.type === "function"
  ) {
    return element.type.name;
  }

  return undefined;
}
