import { Text } from "@mariozechner/pi-tui";
import { formatSearchOutput } from "../format.ts";
import type { NormalizedSearchResponse, WebProvider } from "../providers/types.ts";
import { WebSearchParamsSchema, type WebSearchParams } from "../schema.ts";

interface SearchToolDeps {
  resolveProvider(providerName?: string): Promise<WebProvider>;
}

function normalizeSearchQuery(query: string) {
  const trimmed = query.trim();
  if (!trimmed) {
    throw new Error("web_search requires a non-empty query.");
  }
  return trimmed;
}

export function createWebSearchTool({ resolveProvider }: SearchToolDeps) {
  return {
    name: "web_search",
    label: "Web Search",
    description: "Search the web through the configured provider. Returns result metadata by default.",
    parameters: WebSearchParamsSchema,

    async execute(_toolCallId: string, params: WebSearchParams) {
      const query = normalizeSearchQuery(params.query);
      const provider = await resolveProvider(params.provider);
      const response = await provider.search({
        query,
        limit: params.limit,
        includeDomains: params.includeDomains,
        excludeDomains: params.excludeDomains,
        startPublishedDate: params.startPublishedDate,
        endPublishedDate: params.endPublishedDate,
        category: params.category,
        provider: params.provider,
      });

      return {
        content: [{ type: "text" as const, text: formatSearchOutput(response) }],
        details: response,
      };
    },

    renderCall(args: Partial<WebSearchParams>, theme: any) {
      let text = theme.fg("toolTitle", theme.bold("web_search "));
      text += theme.fg("muted", args.query ?? "");
      return new Text(text, 0, 0);
    },

    renderResult(result: { details?: NormalizedSearchResponse }, _options: unknown, theme: any) {
      const details = result.details;
      if (!details) {
        return new Text("", 0, 0);
      }

      const lines = [
        `${theme.fg("success", "✓ ")}${details.results.length} result${details.results.length === 1 ? "" : "s"} via ${details.providerName}`,
      ];

      for (const [index, item] of details.results.slice(0, 5).entries()) {
        lines.push(`  ${theme.fg("muted", `${index + 1}.`)} ${item.title ?? "(untitled)"} ${theme.fg("dim", item.url)}`);
      }

      return new Text(lines.join("\n"), 0, 0);
    },
  };
}
