import { DynamicStructuredTool } from '@langchain/core/tools';
import { z } from 'zod';
import type { FastifyBaseLogger } from 'fastify';

/**
 * Web Search Tool
 *
 * Calls the Tavily REST API directly. The config interface is intentionally
 * minimal so the underlying provider can be swapped without touching callers.
 */

export interface WebSearchToolConfig {
  apiKey: string;
  logger: FastifyBaseLogger;
}

export function createWebSearchTool(config: WebSearchToolConfig): DynamicStructuredTool {
  const { apiKey, logger } = config;

  return new DynamicStructuredTool({
    name: 'WebSearch',
    description: 'Search the web. Returns titles, URLs, and content summaries. Use this for general web searches. For academic/scientific papers, prefer ArxivSearch instead.',
    schema: z.object({
      query: z.string().describe('The search query'),
      max_results: z.number().optional().default(8).describe('Maximum number of results to return (default: 8)'),
    }),
    func: async ({ query, max_results }) => {
      logger.debug({ query, max_results }, 'Executing WebSearch tool');

      try {
        const response = await fetch('https://api.tavily.com/search', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            api_key: apiKey,
            query,
            max_results,
            search_depth: 'basic',
          }),
          signal: AbortSignal.timeout(30_000),
        });

        if (!response.ok) {
          const text = await response.text();
          throw new Error(`Tavily API error ${response.status}: ${text}`);
        }

        const data = await response.json() as { results?: Array<{ title: string; url: string; content: string }> };

        const items = (data.results ?? []).map(r => ({
          title: r.title,
          url: r.url,
          snippet: r.content,
        }));

        logger.info({ query, resultCount: items.length }, 'Web search completed');

        return JSON.stringify({ query, results: items });
      } catch (error) {
        logger.error({ error, query, errorMessage: error instanceof Error ? error.message : String(error) }, 'WebSearch tool failed');
        return JSON.stringify({ error: error instanceof Error ? error.message : String(error) });
      }
    },
  });
}
