import { ENGINE_DISPLAY_META, fetchWithTimeout, retryWithBackoff, classifyError, extractDomain, parseJsonSafely } from "./shared";
import type { EngineResponse, Citation } from "./shared";
import { getCachedOrQuery } from "../cache";

const META = ENGINE_DISPLAY_META.Brave;
const API_URL = "https://api.search.brave.com/res/v1/web/search";
const TIMEOUT_MS = 15_000;

interface BraveWebResult {
  title?: string;
  url?: string;
  description?: string;
}

interface BraveSummary {
  text?: string;
}

interface BraveBody {
  web?: { results?: BraveWebResult[] };
  summarizer?: BraveSummary;
}

export async function queryBrave(query: string): Promise<EngineResponse> {
  return getCachedOrQuery("Brave", query, () => _query(query));
}

async function _query(query: string): Promise<EngineResponse> {
  const apiKey = process.env.BRAVE_SEARCH_API_KEY?.trim();
  if (!apiKey) {
    return errorResponse("BRAVE_SEARCH_API_KEY not configured");
  }

  const t0 = Date.now();
  const url = `${API_URL}?q=${encodeURIComponent(query)}&count=10&summary=1`;

  try {
    const res = await retryWithBackoff(
      () =>
        fetchWithTimeout(
          url,
          {
            method: "GET",
            headers: {
              Accept: "application/json",
              "Accept-Encoding": "gzip",
              "X-Subscription-Token": apiKey,
            },
          },
          TIMEOUT_MS,
        ),
      1,
      (err) => err instanceof Error && err.message.includes("fetch"),
    );

    if (!res.ok) {
      const engineError = classifyError(res.status, `Brave HTTP ${res.status}`);
      return errorResponse(engineError.message, Date.now() - t0);
    }

    const body = parseJsonSafely<BraveBody>(await res.text());
    const results = body?.web?.results ?? [];
    const responseText = body?.summarizer?.text ?? buildSyntheticSummary(results);

    const citations: Citation[] = results.slice(0, 10).map((r) => ({
      title: r.title ?? extractDomain(r.url ?? ""),
      url: r.url ?? "",
      snippet: r.description ?? "",
      domain: extractDomain(r.url ?? ""),
    }));

    return {
      engineInternalName: "Brave",
      engineNumber: META.number,
      engineDisplayName: META.displayName,
      engineSubtitle: META.subtitle,
      success: true,
      responseText,
      citations,
      errorMessage: null,
      durationMs: Date.now() - t0,
    };
  } catch (err) {
    return errorResponse(err instanceof Error ? err.message : "Unknown error", Date.now() - t0);
  }
}

function buildSyntheticSummary(results: BraveWebResult[]): string | null {
  if (!results.length) return null;
  return results
    .slice(0, 3)
    .map((r) => `${r.title}: ${r.description ?? ""}`)
    .join(" | ");
}

function errorResponse(message: string, durationMs = 0): EngineResponse {
  return {
    engineInternalName: "Brave",
    engineNumber: META.number,
    engineDisplayName: META.displayName,
    engineSubtitle: META.subtitle,
    success: false,
    responseText: null,
    citations: [],
    errorMessage: message,
    durationMs,
  };
}
