
import type { AgentTool } from "@jaeswift/jae-agent-core";
import { Text } from "@jaeswift/jae-tui";
import { type Static, Type } from "@sinclair/typebox";
import { theme } from "../../modes/interactive/theme/theme.js";
import type { ToolRenderResultOptions } from "../extensions/types.js";
import { getTextOutput } from "./render-utils.js";

const webSearchSchema = Type.Object({
  query: Type.String({ description: "Search query" }),
  limit: Type.Optional(Type.Number({ description: "Max results to return (default: 5)" })),
});

export type WebSearchToolInput = Static<typeof webSearchSchema>;

export interface WebSearchResult {
  title: string;
  url: string;
  snippet: string;
}

export interface WebSearchToolDetails {
  results: WebSearchResult[];
  query: string;
  error?: string;
}

async function fetchDuckDuckGo(query: string, limit: number): Promise<WebSearchResult[]> {
  const encoded = encodeURIComponent(query);
  const url = `https://api.duckduckgo.com/?q=${encoded}&format=json&no_redirect=1&no_html=1&skip_disambig=1`;
  const res = await fetch(url, {
    headers: { "User-Agent": "JAE-Agent/1.0" },
    signal: AbortSignal.timeout(10000),
  });
  if (!res.ok) throw new Error(`DuckDuckGo returned ${res.status}`);
  const data = await res.json() as any;

  const results: WebSearchResult[] = [];

  // Instant answer
  if (data.AbstractText && data.AbstractURL) {
    results.push({ title: data.Heading || query, url: data.AbstractURL, snippet: data.AbstractText });
  }

  // Related topics
  for (const topic of (data.RelatedTopics || [])) {
    if (results.length >= limit) break;
    if (topic.FirstURL && topic.Text) {
      results.push({ title: topic.Text.split(" - ")[0] || topic.Text, url: topic.FirstURL, snippet: topic.Text });
    } else if (topic.Topics) {
      for (const sub of topic.Topics) {
        if (results.length >= limit) break;
        if (sub.FirstURL && sub.Text) {
          results.push({ title: sub.Text.split(" - ")[0] || sub.Text, url: sub.FirstURL, snippet: sub.Text });
        }
      }
    }
  }

  // Results section
  for (const r of (data.Results || [])) {
    if (results.length >= limit) break;
    if (r.FirstURL && r.Text) {
      results.push({ title: r.Title || r.Text, url: r.FirstURL, snippet: r.Text });
    }
  }

  return results.slice(0, limit);
}

export const webSearchTool: AgentTool<typeof webSearchSchema, WebSearchToolDetails> = {
  name: "web_search",
  label: "Web Search",
  description: "Search the web for current information using DuckDuckGo. Returns titles, URLs, and snippets.",
  parameters: webSearchSchema,
  async execute(toolCallId, params, signal) {
    const { query, limit = 5 } = params;
    try {
      const results = await fetchDuckDuckGo(query, limit);
      const text = results.length === 0
        ? `No results found for: ${query}`
        : results.map((r, i) => `[${i + 1}] ${r.title}
    URL: ${r.url}
    ${r.snippet}`).join("

");
      return {
        content: [{ type: "text", text }],
        details: { results, query },
      };
    } catch (err: any) {
      const msg = `Web search failed: ${err.message}`;
      return {
        content: [{ type: "text", text: msg }],
        details: { results: [], query, error: err.message },
      };
    }
  },
};
