/**
 * Encyclopedic Presence Detector
 * --------------------------------
 * Checks knowledge graph and encyclopedic entity databases for brand presence.
 * Uses public APIs requiring no authentication.
 *
 * Internal module -- vendor names permitted in code; forbidden in user-facing output.
 */

const USER_AGENT = "meSEO-Audit-Bot/1.0 (https://meseoapp.com)";
const TIMEOUT_MS = 5_000;

export interface WikipediaPresence {
  hasWikipediaPage: boolean;
  wikipediaPageTitle: string | null;
  wikipediaUrl: string | null;
  hasWikidataEntity: boolean;
  wikidataId: string | null;
}

function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
  return Promise.race([
    promise,
    new Promise<T>((_, reject) =>
      setTimeout(() => reject(new Error("timeout")), ms),
    ),
  ]);
}

async function fetchJson(url: string): Promise<unknown> {
  const res = await fetch(url, {
    headers: { "User-Agent": USER_AGENT },
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

function titleMatchesBrand(title: string, brand: string): boolean {
  const t = title.toLowerCase().trim();
  const b = brand.toLowerCase().trim();
  // Exact match or brand name is a leading substring (handles "Brand (disambiguation)" etc.)
  return t === b || t.startsWith(b + " (") || t.startsWith(b + ",");
}

export async function detectWikipediaWikidataPresence(
  brandName: string,
): Promise<WikipediaPresence> {
  const fallback: WikipediaPresence = {
    hasWikipediaPage: false,
    wikipediaPageTitle: null,
    wikipediaUrl: null,
    hasWikidataEntity: false,
    wikidataId: null,
  };

  const encoded = encodeURIComponent(brandName);

  // Wikipedia search
  let hasWikipediaPage = false;
  let wikipediaPageTitle: string | null = null;
  let wikipediaUrl: string | null = null;

  try {
    const wpUrl = `https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encoded}&format=json&srlimit=3&origin=*`;
    const data = await withTimeout(fetchJson(wpUrl), TIMEOUT_MS) as {
      query?: { search?: Array<{ title: string; snippet: string }> };
    };
    const results = data?.query?.search ?? [];
    const match = results.find((r) => titleMatchesBrand(r.title, brandName));
    if (match) {
      hasWikipediaPage = true;
      wikipediaPageTitle = match.title;
      wikipediaUrl = `https://en.wikipedia.org/wiki/${encodeURIComponent(match.title)}`;
    }
  } catch (err) {
    console.warn("[wikipedia-detector] Wikipedia lookup failed:", err instanceof Error ? err.message : err);
  }

  // Wikidata search
  let hasWikidataEntity = false;
  let wikidataId: string | null = null;

  try {
    const wdUrl = `https://www.wikidata.org/w/api.php?action=wbsearchentities&search=${encoded}&language=en&format=json&limit=3&origin=*`;
    const data = await withTimeout(fetchJson(wdUrl), TIMEOUT_MS) as {
      search?: Array<{ id: string; label: string }>;
    };
    const results = data?.search ?? [];
    const match = results.find((r) => r.label?.toLowerCase().trim() === brandName.toLowerCase().trim());
    if (match) {
      hasWikidataEntity = true;
      wikidataId = match.id;
    }
  } catch (err) {
    console.warn("[wikipedia-detector] Wikidata lookup failed:", err instanceof Error ? err.message : err);
  }

  return { hasWikipediaPage, wikipediaPageTitle, wikipediaUrl, hasWikidataEntity, wikidataId };
}
