const SEARCH_SVC_URL = process.env.SEARCH_SVC_URL?.trim() ?? '';
const SEARXNG_URL = process.env.SEARXNG_URL?.trim() ?? '';
const FALLBACK_URLS = (
  process.env.SEARXNG_FALLBACK_URL?.split(',').map((u) => u.trim()) ?? [
    'https://searx.tiekoetter.com',
    'https://search.sapti.me',
  ]
).filter(Boolean);

export type SearchResult = {
  title: string;
  url: string;
  img_src?: string;
  thumbnail?: string;
  iframe_src?: string;
};

export async function search(
  query: string,
  opts?: { engines?: string[] },
): Promise<{ results: SearchResult[] }> {
  const engines = opts?.engines?.join(',') ?? '';

  if (SEARCH_SVC_URL) {
    const params = new URLSearchParams();
    params.set('q', query);
    if (engines) params.set('engines', engines);
    const url = `${SEARCH_SVC_URL.replace(/\/$/, '')}/api/v1/search?${params}`;
    const res = await fetch(url, { signal: AbortSignal.timeout(15000) });
    if (!res.ok) {
      const err = (await res.json().catch(() => ({}))) as { error?: string };
      throw new Error(err.error ?? `Search HTTP ${res.status}`);
    }
    return res.json();
  }

  const candidates = [SEARXNG_URL, ...FALLBACK_URLS].filter(Boolean).map((u) =>
    u!.startsWith('http') ? u! : `http://${u}`,
  );
  if (candidates.length === 0) throw new Error('SearXNG/SEARCH_SVC_URL not configured');

  let lastErr: Error | null = null;
  for (const base of candidates) {
    try {
      const params = new URLSearchParams();
      params.set('format', 'json');
      params.set('q', query);
      if (engines) params.set('engines', engines);
      const url = `${base}/search?${params}`;
      const res = await fetch(url, { signal: AbortSignal.timeout(15000) });
      const data = (await res.json()) as { results?: SearchResult[] };
      return { results: data.results ?? [] };
    } catch (e) {
      lastErr = e instanceof Error ? e : new Error(String(e));
    }
  }
  throw lastErr ?? new Error('Search failed');
}
