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

const { mockOptima, mockCheckPermissions, mockHandleApiError } = vi.hoisted(
  () => ({
    mockOptima: {
      company: { fetch: vi.fn(), fetchConfigurations: vi.fn() },
      credential: { fetchByCompany: vi.fn() },
      credentialType: { fetchMany: vi.fn() },
      unifi: { fetchCompanySites: vi.fn() },
    },
    mockCheckPermissions: vi.fn(),
    mockHandleApiError: vi.fn(),
  }),
);

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

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

describe("companies/[id] +page.server.ts load", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns empty data when no access token", async () => {
    const result = await load({
      locals: {},
      params: { id: "c1" },
    } as any);

    expect(result).toMatchObject({
      company: null,
      configurations: [],
      credentials: [],
      credentialTypes: [],
      unifiSites: [],
      accessToken: null,
    });
  });

  it("loads company with all related data", async () => {
    mockCheckPermissions.mockResolvedValueOnce({
      "company.fetch.address": true,
      "company.fetch.contacts": true,
      "credential.secure_values.read": true,
      "unifi.site.wifi": true,
      "unifi.site.wifi.read.name": true,
      "unifi.site.wifi.update": false,
    });
    mockOptima.company.fetchConfigurations.mockResolvedValueOnce({
      data: [{ id: "cfg-1" }],
    });
    mockOptima.credential.fetchByCompany.mockResolvedValueOnce({
      data: [{ id: "cred-1" }],
    });
    mockOptima.credentialType.fetchMany.mockResolvedValueOnce({
      data: [{ id: "ct-1" }],
    });
    mockOptima.unifi.fetchCompanySites.mockResolvedValueOnce({
      data: [{ id: "site-1" }],
    });
    mockOptima.company.fetch.mockResolvedValueOnce({
      data: { id: "c1", name: "Acme" },
    });

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

    expect(result).toMatchObject({
      company: { id: "c1", name: "Acme" },
      configurations: [{ id: "cfg-1" }],
      credentials: [{ id: "cred-1" }],
      credentialTypes: [{ id: "ct-1" }],
      unifiSites: [{ id: "site-1" }],
      accessToken: "tok",
    });

    expect(mockOptima.company.fetch).toHaveBeenCalledWith("tok", "c1", {
      includeAddress: true,
      includeAllAddresses: true,
      includePrimaryContact: true,
      includeAllContacts: true,
    });
  });

  it("handles credential fetch failure gracefully", async () => {
    mockCheckPermissions.mockResolvedValueOnce({
      "company.fetch.address": false,
      "company.fetch.contacts": false,
    });
    mockOptima.company.fetchConfigurations.mockResolvedValueOnce({ data: [] });
    mockOptima.credential.fetchByCompany.mockRejectedValueOnce(
      new Error("fail"),
    );
    mockOptima.credentialType.fetchMany.mockRejectedValueOnce(
      new Error("fail"),
    );
    mockOptima.unifi.fetchCompanySites.mockRejectedValueOnce(new Error("fail"));
    mockOptima.company.fetch.mockResolvedValueOnce({ data: { id: "c1" } });

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

    expect(result).toMatchObject({
      credentials: [],
      credentialTypes: [],
      unifiSites: [],
    });
  });
});
