/**
 * WebSearch tool — search the web using available search APIs.
 *
 * Supported backends (checked in order):
 *   1. Brave Search API (BRAVE_SEARCH_API_KEY)
 *   2. SearXNG local instance (SEARXNG_URL, default http://localhost:8888)
 *   3. Fallback: returns instructions to configure a search backend
 */

export const definition = {
  name: 'WebSearch',
  description: 'Search the web for current information. Returns structured results with titles, URLs, and snippets.',
  input_schema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'The search query' },
      allowed_domains: { type: 'array', items: { type: 'string' }, description: 'Only include results from these domains' },
      blocked_domains: { type: 'array', items: { type: 'string' }, description: 'Exclude results from these domains' }
    },
    required: ['query']
  }
};

async function searchBrave(query, apiKey) {
  const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=10`;
  const response = await fetch(url, {
    headers: { 'X-Subscription-Token': apiKey, 'Accept': 'application/json' }
  });
  if (!response.ok) throw new Error(`Brave API ${response.status}`);
  const data = await response.json();
  return (data.web?.results || []).map(r => ({
    title: r.title || '',
    url: r.url || '',
    snippet: r.description || ''
  }));
}

async function searchSearXNG(query, baseUrl) {
  const url = `${baseUrl}/search?q=${encodeURIComponent(query)}&format=json`;
  const response = await fetch(url, { headers: { 'Accept': 'application/json' } });
  if (!response.ok) throw new Error(`SearXNG ${response.status}`);
  const data = await response.json();
  return (data.results || []).slice(0, 10).map(r => ({
    title: r.title || '',
    url: r.url || '',
    snippet: r.content || ''
  }));
}

function filterResults(results, allowedDomains, blockedDomains) {
  let filtered = results;
  if (allowedDomains?.length) {
    filtered = filtered.filter(r => {
      try {
        const host = new URL(r.url).hostname;
        return allowedDomains.some(d => host.includes(d));
      } catch { return false; }
    });
  }
  if (blockedDomains?.length) {
    filtered = filtered.filter(r => {
      try {
        const host = new URL(r.url).hostname;
        return !blockedDomains.some(d => host.includes(d));
      } catch { return true; }
    });
  }
  return filtered;
}

export async function execute(input, context) {
  const { query, allowed_domains, blocked_domains } = input;

  if (!query) return { content: 'Error: query is required', is_error: true };

  let results;

  // Try Brave Search first
  const braveKey = process.env.BRAVE_SEARCH_API_KEY;
  if (braveKey) {
    try {
      results = await searchBrave(query, braveKey);
    } catch (err) {
      return { content: `Brave Search error: ${err.message}`, is_error: true };
    }
  }

  // Try SearXNG
  if (!results) {
    const searxUrl = process.env.SEARXNG_URL || 'http://localhost:8888';
    try {
      results = await searchSearXNG(query, searxUrl);
    } catch {
      // SearXNG not available — that's OK
    }
  }

  if (!results) {
    return {
      content: 'Web search not configured. Set BRAVE_SEARCH_API_KEY env var or run a SearXNG instance at SEARXNG_URL.',
      is_error: true
    };
  }

  results = filterResults(results, allowed_domains, blocked_domains);

  if (results.length === 0) {
    return { content: `No results for "${query}"`, is_error: false };
  }

  const formatted = results.map((r, i) =>
    `${i + 1}. **${r.title}**\n   ${r.url}\n   ${r.snippet}`
  ).join('\n\n');

  return { content: formatted, is_error: false };
}
