import { beforeEach, describe, expect, it, vi } from "vitest";

const { mockOptima, mockCheckPermissions, mockHandleApiError, mockRedirect } =
  vi.hoisted(() => ({
    mockOptima: {
      user: { fetchInfo: vi.fn() },
    },
    mockCheckPermissions: vi.fn(),
    mockHandleApiError: vi.fn(),
    mockRedirect: vi.fn((status: number, location: string) => {
      throw { status, location };
    }),
  }));

vi.mock("$lib", () => ({ optima: mockOptima }));
vi.mock("$lib/permissions", () => ({
  checkPermissions: mockCheckPermissions,
}));
vi.mock("$lib/optima-api/errorHandler", () => ({
  handleApiError: mockHandleApiError,
}));
vi.mock("@sveltejs/kit", () => ({
  redirect: mockRedirect,
}));

import { load } from "./+layout.server";

describe("admin +layout.server.ts load", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("redirects to /login when no access token", async () => {
    await expect(
      load({
        locals: {},
        parent: vi.fn().mockResolvedValue({}),
      } as any),
    ).rejects.toEqual(
      expect.objectContaining({ status: 303, location: "/login" }),
    );
  });

  it("redirects to / when canViewAdmin is false", async () => {
    await expect(
      load({
        locals: { session: { accessToken: "tok" } },
        parent: vi.fn().mockResolvedValue({ canViewAdmin: false }),
      } as any),
    ).rejects.toEqual(expect.objectContaining({ status: 303, location: "/" }));
  });

  it("returns user and permissions when authorized", async () => {
    mockCheckPermissions.mockResolvedValueOnce({
      "admin.users.view": true,
      "admin.roles.view": true,
      "admin.credential-types.view": true,
      "ui.navigation.reports.view": true,
    });
    mockOptima.user.fetchInfo.mockResolvedValueOnce({
      data: { id: "u1", name: "Admin" },
    });

    const result = await load({
      locals: { session: { accessToken: "tok" } },
      parent: vi.fn().mockResolvedValue({ canViewAdmin: true }),
    } as any);

    expect(result).toMatchObject({
      user: { id: "u1", name: "Admin" },
      permissions: expect.objectContaining({
        "ui.navigation.admin.view": true,
        "admin.users.view": true,
      }),
    });
  });
});
