import { getConfig } from "../config.js";
import { createLogger } from "../logger.js";
const log = createLogger("search");
const CATEGORY_MAP = {
  general: "general",
  news: "news",
  code: "it",
  docs: "general",
  papers: "science",
  images: "images"
};
function computeTimeRange(fromDate, toDate) {
  if (!fromDate) return null;
  const from = new Date(fromDate);
  if (isNaN(from.getTime())) return null;
  const now = toDate ? new Date(toDate) : /* @__PURE__ */ new Date();
  if (isNaN(now.getTime())) return null;
  const diffDays = Math.round((now.getTime() - from.getTime()) / (1e3 * 60 * 60 * 24));
  if (diffDays <= 1) return "day";
  if (diffDays <= 7) return "week";
  if (diffDays <= 30) return "month";
  return "year";
}
class SearxngClient {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }
  baseUrl;
  name = "searxng";
  async search(query, options = {}) {
    const config = getConfig();
    const timeoutMs = options.timeoutMs ?? config.searxngQueryTimeoutMs;
    const maxResults = options.maxResults ?? 10;
    let queryStr = query;
    if (options.includeDomains?.length) {
      const siteFilter = options.includeDomains.map((d) => `site:${d}`).join(" OR ");
      queryStr = options.includeDomains.length === 1 ? `${query} site:${options.includeDomains[0]}` : `${query} (${siteFilter})`;
    }
    const params = new URLSearchParams({
      q: queryStr,
      format: "json",
      pageno: "1"
    });
    if (options.timeRange) params.set("time_range", options.timeRange);
    if (options.language) params.set("language", options.language);
    if (options.category) {
      params.set("categories", CATEGORY_MAP[options.category] ?? "general");
    }
    if (!options.timeRange && (options.fromDate || options.toDate)) {
      const range = computeTimeRange(options.fromDate, options.toDate);
      if (range) params.set("time_range", range);
    }
    const url = `${this.baseUrl}/search?${params}`;
    log.debug("querying searxng", { query: queryStr, url });
    const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
    if (!response.ok) {
      throw new Error(`SearXNG returned ${response.status}`);
    }
    const data = await response.json();
    const total = data.results.length;
    return data.results.slice(0, maxResults).map((r, i) => {
      const published = r.publishedDate ?? r.pubdate ?? void 0;
      return {
        title: r.title,
        url: r.url,
        snippet: r.content,
        relevance_score: r.score != null ? Math.min(r.score, 1) : 1 - i / Math.max(total, 1),
        engine: "searxng",
        ...published ? { published_date: published } : {}
      };
    });
  }
}
export {
  SearxngClient
};
//# sourceMappingURL=searxng.js.map