import type { AgentTool } from "@jaeswift/jae-agent-core";
import { type Static, Type } from "@sinclair/typebox";

const webFetchSchema = Type.Object({
	url: Type.String({ description: "URL to fetch" }),
	selector: Type.Optional(Type.String({ description: "CSS selector to extract specific content (optional)" })),
});

export type WebFetchToolInput = Static<typeof webFetchSchema>;

export interface WebFetchToolDetails {
	url: string;
	status: number;
	contentType: string;
	truncated: boolean;
}

const MAX_CHARS = 20000;

function htmlToText(html: string): string {
	return html
		.replace(/<script[\s\S]*?<\/script>/gi, "")
		.replace(/<style[\s\S]*?<\/style>/gi, "")
		.replace(/<[^>]+>/g, " ")
		.replace(/&amp;/g, "&")
		.replace(/&lt;/g, "<")
		.replace(/&gt;/g, ">")
		.replace(/&quot;/g, '"')
		.replace(/&nbsp;/g, " ")
		.replace(/&#39;/g, "'")
		.replace(/[ \t]+/g, " ")
		.replace(/\n{3,}/g, "\n\n")
		.trim();
}

export const webFetchTool: AgentTool<typeof webFetchSchema, WebFetchToolDetails> = {
	name: "web_fetch",
	label: "Web Fetch",
	description: "Fetch and read the text content of any web page or URL. Strips HTML to plain text.",
	parameters: webFetchSchema,
	async execute(toolCallId, params, signal) {
		const { url } = params;
		try {
			const res = await fetch(url, {
				headers: { "User-Agent": "JAE-Agent/1.0", Accept: "text/html,application/xhtml+xml,text/plain,*/*" },
				signal: signal ?? AbortSignal.timeout(15000),
				redirect: "follow",
			});
			const contentType = res.headers.get("content-type") || "";
			const body = await res.text();
			let text: string;
			if (contentType.includes("html")) {
				text = htmlToText(body);
			} else {
				text = body;
			}
			const truncated = text.length > MAX_CHARS;
			if (truncated) text = text.slice(0, MAX_CHARS) + "\n... [truncated]";
			return {
				content: [{ type: "text", text: `URL: ${url}\nStatus: ${res.status}\n\n${text}` }],
				details: { url, status: res.status, contentType, truncated },
			};
		} catch (err: any) {
			return {
				content: [{ type: "text", text: `Fetch failed for ${url}: ${err.message}` }],
				details: { url, status: 0, contentType: "", truncated: false },
			};
		}
	},
};
