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

const { mockOptima, mockCheckPermissions, mockHandleApiError } = vi.hoisted(
  () => ({
    mockOptima: {
      sales: {
        fetchMany: vi.fn(),
        fetchMe: vi.fn(),
        fetchMetrics: vi.fn(),
        fetchOpportunityTypes: 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("sales +page.server.ts load", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns empty data when no token", async () => {
    const result = await load({
      locals: {},
      url: new URL("http://localhost/sales"),
    } as any);

    expect(result).toMatchObject({
      opportunities: [],
      opportunityTypes: [],
      totalPages: 1,
      currentPage: 1,
      totalRecords: 0,
      search: "",
      includeClosed: false,
    });
  });

  it("fetches opportunities with pagination", async () => {
    mockOptima.sales.fetchMany.mockResolvedValueOnce({
      data: [{ id: "opp-1" }],
      meta: {
        pagination: { totalPages: 3, currentPage: 2, totalRecords: 90 },
      },
    });
    mockCheckPermissions.mockResolvedValueOnce({
      "sales.opportunity.fetch.many": true,
    });
    mockOptima.sales.fetchMetrics.mockResolvedValueOnce(null);
    mockOptima.sales.fetchOpportunityTypes.mockResolvedValueOnce({
      data: ["Type A"],
    });

    const result = await load({
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/sales?tab=list&page=2&search=deal"),
    } as any);

    expect(mockOptima.sales.fetchMany).toHaveBeenCalledWith(
      "tok",
      2,
      "deal",
      30,
      true,
    );
    expect(result).toMatchObject({
      totalPages: 3,
      currentPage: 2,
      search: "deal",
    });
  });

  it("passes includeClosed=false when param is false", async () => {
    mockOptima.sales.fetchMany.mockResolvedValueOnce({
      data: [],
      meta: {
        pagination: { totalPages: 1, currentPage: 1, totalRecords: 0 },
      },
    });
    mockCheckPermissions.mockResolvedValueOnce({});
    mockOptima.sales.fetchMetrics.mockResolvedValueOnce(null);
    mockOptima.sales.fetchOpportunityTypes.mockResolvedValueOnce({
      data: [],
    });

    await load({
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/sales?tab=list&includeClosed=false"),
    } as any);

    expect(mockOptima.sales.fetchMany).toHaveBeenCalledWith(
      "tok",
      1,
      "",
      30,
      false,
    );
  });
});
