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

const { mockOptima } = vi.hoisted(() => ({
  mockOptima: {
    user: {
      fetchInfo: vi.fn(),
      checkPermissions: vi.fn(),
    },
  },
}));

vi.mock("$lib", () => ({ optima: mockOptima }));

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

describe("root +layout.server.ts load", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.spyOn(console, "error").mockImplementation(() => {});
  });

  it("returns canViewAdmin false when no access token", async () => {
    const result = await load({
      locals: {},
    } as any);

    expect(result).toEqual({ canViewAdmin: false, user: null });
  });

  it("returns canViewAdmin false when session accessToken is null", async () => {
    const result = await load({
      locals: { session: { accessToken: null } },
    } as any);

    expect(result).toEqual({ canViewAdmin: false, user: null });
  });

  it("returns canViewAdmin true when permission is granted", async () => {
    mockOptima.user.fetchInfo.mockResolvedValueOnce({
      data: { id: "u1" },
    });
    mockOptima.user.checkPermissions.mockResolvedValueOnce({
      data: {
        results: [
          { permission: "ui.navigation.admin.view", hasPermission: true },
        ],
      },
    });

    const result = await load({
      locals: { session: { accessToken: "tok" } },
    } as any);

    expect(result).toEqual({ canViewAdmin: true, user: { id: "u1" } });
  });

  it("returns canViewAdmin false when permission is denied", async () => {
    mockOptima.user.fetchInfo.mockResolvedValueOnce({
      data: { id: "u1" },
    });
    mockOptima.user.checkPermissions.mockResolvedValueOnce({
      data: {
        results: [
          { permission: "ui.navigation.admin.view", hasPermission: false },
        ],
      },
    });

    const result = await load({
      locals: { session: { accessToken: "tok" } },
    } as any);

    expect(result).toEqual({ canViewAdmin: false, user: { id: "u1" } });
  });

  it("returns canViewAdmin false on permission check error", async () => {
    mockOptima.user.fetchInfo.mockRejectedValueOnce(new Error("fail"));

    const result = await load({
      locals: { session: { accessToken: "tok" } },
    } as any);

    expect(result).toEqual({ canViewAdmin: false, user: null });
  });
});
