import test from "node:test";
import assert from "node:assert/strict";
import { createExaProvider } from "./exa.ts";

const baseConfig = {
  name: "exa-main",
  type: "exa" as const,
  apiKey: "exa-test-key",
  options: {
    defaultSearchLimit: 7,
    defaultFetchTextMaxCharacters: 9000,
    defaultFetchHighlightsMaxCharacters: 1200,
  },
};

test("createExaProvider maps generic search requests to Exa search with contents disabled", async () => {
  let captured: { query: string; options: Record<string, unknown> } | undefined;

  const provider = createExaProvider(baseConfig, () => ({
    async search(query, options) {
      captured = { query, options };
      return {
        requestId: "req-search-1",
        searchTime: 123,
        results: [
          {
            id: "doc-1",
            title: "Exa Docs",
            url: "https://exa.ai/docs",
            publishedDate: "2026-04-09",
            author: "Exa",
            score: 0.98,
          },
        ],
      };
    },
    async getContents() {
      throw new Error("not used");
    },
  }));

  const result = await provider.search({
    query: "exa docs",
    includeDomains: ["exa.ai"],
  });

  assert.deepEqual(captured, {
    query: "exa docs",
    options: {
      contents: false,
      numResults: 7,
      includeDomains: ["exa.ai"],
      excludeDomains: undefined,
      startPublishedDate: undefined,
      endPublishedDate: undefined,
      category: undefined,
    },
  });
  assert.equal(result.providerName, "exa-main");
  assert.equal(result.results[0]?.url, "https://exa.ai/docs");
});

test("createExaProvider fetch defaults to text and preserves per-url failures", async () => {
  const calls: Array<{ urls: string[]; options: Record<string, unknown> }> = [];

  const provider = createExaProvider(baseConfig, () => ({
    async search() {
      throw new Error("not used");
    },
    async getContents(urls, options) {
      const requestUrls = Array.isArray(urls) ? urls : [urls];
      calls.push({ urls: requestUrls, options });

      if (requestUrls[0] === "https://bad.example") {
        throw new Error("429 rate limited");
      }

      return {
        requestId: `req-${calls.length}`,
        results: [
          {
            url: requestUrls[0],
            title: "Fetched page",
            text: "Fetched body",
          },
        ],
      };
    },
  }));

  const result = await provider.fetch({
    urls: ["https://good.example", "https://bad.example"],
  });

  assert.equal((calls[0]?.options.text as { maxCharacters: number }).maxCharacters, 9000);
  assert.deepEqual(result.results, [
    {
      url: "https://good.example",
      title: "Fetched page",
      text: "Fetched body",
      highlights: undefined,
      summary: undefined,
    },
    {
      url: "https://bad.example",
      title: null,
      error: "429 rate limited",
    },
  ]);
});
