/**
 * 网络工具（2 个）
 *
 * web_search, web_extract
 *
 * @see docs/MetonaAI-Desktop 架构与交互设计.html — 9 个基础工具
 * @see standard/开发规范.md — 使用原生 fetch（允许在工具层使用）
 */

import type { IMetonaTool, ToolExecutionContext } from '../../types/metona-tool';
import type { MetonaToolDef } from '../../../harness/types';
import { MetonaToolCategory, MetonaRiskLevel } from '../../../harness/types';

// ===== 5. web_search =====

export class WebSearchTool implements IMetonaTool {
  readonly definition: MetonaToolDef = {
    name: 'web_search',
    description: 'Search the web for information. Returns titles, snippets, and URLs. Supports search operators (site:, filetype:, etc.).',
    parameters: {
      type: 'object',
      properties: {
        query: { type: 'string', description: 'Search query. Supports operators like site:domain filetype:pdf' },
        limit: { type: 'number', description: 'Number of results (default 5, max 100)' },
      },
      required: ['query'],
    },
    category: MetonaToolCategory.NETWORK,
    riskLevel: MetonaRiskLevel.LOW,
    requiresPermission: false,
    timeoutMs: 30_000,
  };

  async execute(args: Record<string, unknown>, _context: ToolExecutionContext): Promise<unknown> {
    const query = args.query as string;
    const limit = Math.min(100, Math.max(1, (args.limit as number) ?? 5));

    // 使用 DuckDuckGo Instant Answer API（免费，无需 API Key）
    try {
      const url = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_html=1&skip_disambig=1`;
      const response = await fetch(url, {
        signal: AbortSignal.timeout(15_000),
        headers: { 'User-Agent': 'MetonaAI/1.0' },
      });

      if (!response.ok) {
        throw new Error(`Search API error: ${response.status}`);
      }

      const data = await response.json() as Record<string, unknown>;
      const results: Array<{ title: string; snippet: string; url: string }> = [];

      // 提取 AbstractText
      if (data.AbstractText) {
        results.push({
          title: (data.Heading as string) ?? query,
          snippet: (data.AbstractText as string).slice(0, 300),
          url: (data.AbstractURL as string) ?? '',
        });
      }

      // 提取 RelatedTopics
      const related = data.RelatedTopics as Array<Record<string, unknown>> | undefined;
      if (related) {
        for (const topic of related.slice(0, limit - results.length)) {
          if (topic.Text && topic.FirstURL) {
            results.push({
              title: ((topic.Text as string) ?? '').slice(0, 100),
              snippet: (topic.Text as string) ?? '',
              url: (topic.FirstURL as string) ?? '',
            });
          }
        }
      }

      return { query, results, count: results.length };
    } catch (error) {
      return { query, results: [], count: 0, error: (error as Error).message };
    }
  }
}

// ===== 6. web_extract =====

export class WebExtractTool implements IMetonaTool {
  readonly definition: MetonaToolDef = {
    name: 'web_extract',
    description: 'Fetch web page content and convert to plain text. Supports HTML pages. Content over 5000 chars is auto-summarized.',
    parameters: {
      type: 'object',
      properties: {
        urls: { type: 'array', description: 'URL list to fetch (max 5)', items: { type: 'string', description: 'URL to fetch' } },
      },
      required: ['urls'],
    },
    category: MetonaToolCategory.NETWORK,
    riskLevel: MetonaRiskLevel.LOW,
    requiresPermission: false,
    timeoutMs: 30_000,
  };

  async execute(args: Record<string, unknown>, _context: ToolExecutionContext): Promise<unknown> {
    const urls = (args.urls as string[]).slice(0, 5);
    const results: Array<{ url: string; content: string; success: boolean; error?: string }> = [];

    for (const url of urls) {
      try {
        const response = await fetch(url, {
          signal: AbortSignal.timeout(15_000),
          headers: {
            'User-Agent': 'MetonaAI/1.0',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
          },
        });

        if (!response.ok) {
          results.push({ url, content: '', success: false, error: `HTTP ${response.status}` });
          continue;
        }

        const html = await response.text();
        const text = this.htmlToText(html);
        const truncated = text.length > 5000 ? text.slice(0, 5000) + '\n\n[Content truncated at 5000 characters]' : text;

        results.push({ url, content: truncated, success: true });
      } catch (error) {
        results.push({ url, content: '', success: false, error: (error as Error).message });
      }
    }

    return { results, count: results.length };
  }

  /**
   * 简单 HTML → 文本转换
   * @see standard/开发规范.md — < 20 行纯函数，允许自写
   */
  private htmlToText(html: string): string {
    return html
      .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
      .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
      .replace(/<[^>]+>/g, ' ')
      .replace(/&nbsp;/g, ' ')
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"')
      .replace(/\s+/g, ' ')
      .trim();
  }
}
