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

const { mockOptima, mockJson, mockError } = vi.hoisted(() => ({
  mockOptima: {
    credential: { fetchSecureValue: 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 /companies/[id]/secure-value", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.spyOn(console, "error").mockImplementation(() => {});
  });

  it("throws 401 when no access token", async () => {
    const event = {
      locals: {},
      url: new URL("http://localhost/secure-value?credentialId=c1&fieldId=f1"),
    };
    await expect(GET(event as any)).rejects.toEqual(
      expect.objectContaining({ status: 401 }),
    );
  });

  it("throws 400 when credentialId is missing", async () => {
    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/secure-value?fieldId=f1"),
    };
    await expect(GET(event as any)).rejects.toEqual(
      expect.objectContaining({ status: 400 }),
    );
  });

  it("throws 400 when fieldId is missing", async () => {
    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/secure-value?credentialId=c1"),
    };
    await expect(GET(event as any)).rejects.toEqual(
      expect.objectContaining({ status: 400 }),
    );
  });

  it("fetches secure value successfully", async () => {
    mockOptima.credential.fetchSecureValue.mockResolvedValueOnce({
      data: "secret",
    });

    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/secure-value?credentialId=c1&fieldId=f1"),
    };

    await GET(event as any);

    expect(mockOptima.credential.fetchSecureValue).toHaveBeenCalledWith(
      "tok",
      "c1",
      "f1",
    );
    expect(mockJson).toHaveBeenCalledWith({ data: "secret" });
  });

  it("throws on API failure", async () => {
    mockOptima.credential.fetchSecureValue.mockRejectedValueOnce({
      status: 403,
    });

    const event = {
      locals: { session: { accessToken: "tok" } },
      url: new URL("http://localhost/secure-value?credentialId=c1&fieldId=f1"),
    };

    await expect(GET(event as any)).rejects.toBeDefined();
  });
});
