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

const { mockOptima, mockJson, mockError } = vi.hoisted(() => ({
  mockOptima: {
    company: {
      fetchMany: vi.fn(),
    },
  },
  mockJson: vi.fn((data, init?) => {
    return new Response(JSON.stringify(data), {
      status: init?.status ?? 200,
    });
  }),
  mockError: vi.fn((status: number, message: string) => {
    throw { status, body: { message } };
  }),
}));

vi.mock("$lib", () => ({ optima: mockOptima }));
vi.mock("@sveltejs/kit", () => ({
  json: mockJson,
  error: mockError,
}));

import { GET } from "./+server";

describe("GET /api/companies/search", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.spyOn(console, "error").mockImplementation(() => {});
  });

  it("returns 401 with empty data when no token", async () => {
    const event = {
      locals: {},
      url: new URL("http://localhost/api/companies/search"),
    };

    GET(event as any);

    expect(mockJson).toHaveBeenCalledWith({ data: [] }, { status: 401 });
  });

  it("fetches companies with search params", async () => {
    mockOptima.company.fetchMany.mockResolvedValueOnce({
      data: [{ id: "1", name: "Acme" }],
    });

    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL(
        "http://localhost/api/companies/search?search=acme&page=2&rpp=10",
      ),
    };

    await GET(event as any);

    expect(mockOptima.company.fetchMany).toHaveBeenCalledWith(
      "tok",
      2,
      "acme",
      10,
    );
    expect(mockJson).toHaveBeenCalledWith({
      data: [{ id: "1", name: "Acme" }],
    });
  });

  it("uses default params when not specified", async () => {
    mockOptima.company.fetchMany.mockResolvedValueOnce({ data: [] });

    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/api/companies/search"),
    };

    await GET(event as any);

    expect(mockOptima.company.fetchMany).toHaveBeenCalledWith("tok", 1, "", 15);
  });

  it("returns 500 on fetch failure", async () => {
    mockOptima.company.fetchMany.mockRejectedValueOnce(new Error("fail"));

    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/api/companies/search"),
    };

    await GET(event as any);

    expect(mockJson).toHaveBeenCalledWith({ data: [] }, { status: 500 });
  });
});
