/**
 * Editorial Mentions Detector
 * -----------------------------
 * Discovers brand coverage in editorial and news publications.
 * Uses the Brave Search news endpoint.
 *
 * Internal module -- vendor names permitted in code; forbidden in user-facing output.
 */

const BRAVE_API_KEY = process.env.BRAVE_SEARCH_API_KEY ?? "";
const TIMEOUT_MS = 8_000;

// Internal tier classification -- never surfaced to customers.
const TIER1_DOMAINS = new Set([
  "nytimes.com", "wsj.com", "washingtonpost.com", "bbc.com", "bbc.co.uk",
  "reuters.com", "bloomberg.com", "ft.com", "theguardian.com", "npr.org",
  "ap.org", "apnews.com", "forbes.com", "businessinsider.com", "cnbc.com",
  "cnn.com", "axios.com", "theatlantic.com", "newyorker.com", "time.com",
  "economist.com", "wired.com", "techcrunch.com",
]);

const KNOWN_LOW_QUALITY = new Set([
  "pinterest.com", "reddit.com", "quora.com", "linkedin.com", "facebook.com",
  "twitter.com", "x.com", "instagram.com", "youtube.com",
]);

function classifyPublisherTier(domain: string): 1 | 2 | 3 {
  const d = domain.toLowerCase();
  if (TIER1_DOMAINS.has(d)) return 1;
  if (KNOWN_LOW_QUALITY.has(d)) return 3;
  // Tier 2 heuristic: domain suggests trade/industry/news character
  if (/trade|industry|medical|health|tech|law|finance|dental|dental|hotel|restaurant|retail|pharma|bio|med|dive\.com|today\.com/.test(d)) return 2;
  return 3;
}

function parseDaysAgo(age: string): number {
  if (!age) return 999;
  const m = age.match(/(\d+)\s*(day|week|month|year)/i);
  if (!m) return 999;
  const n = parseInt(m[1], 10);
  const unit = m[2].toLowerCase();
  if (unit.startsWith("day")) return n;
  if (unit.startsWith("week")) return n * 7;
  if (unit.startsWith("month")) return n * 30;
  if (unit.startsWith("year")) return n * 365;
  return 999;
}

function apexDomain(url: string): string {
  try {
    const host = new URL(url).hostname.replace(/^www\./, "");
    return host;
  } catch {
    return url;
  }
}

export interface EditorialMentions {
  mentionCount: number;
  last90DayMentionCount: number;
  tier1Count: number;
  tier2Count: number;
  tier3Count: number;
  topPublishers: string[]; // internal domain list for rawSignalData
}

export async function detectEditorialMentions(
  brandName: string,
): Promise<EditorialMentions> {
  const zero: EditorialMentions = {
    mentionCount: 0, last90DayMentionCount: 0,
    tier1Count: 0, tier2Count: 0, tier3Count: 0,
    topPublishers: [],
  };

  if (!BRAVE_API_KEY) return zero;

  try {
    const query = encodeURIComponent(`"${brandName}"`);
    const url = `https://api.search.brave.com/res/v1/news/search?q=${query}&count=20&freshness=py`;
    const res = await Promise.race([
      fetch(url, {
        headers: {
          "Accept": "application/json",
          "X-Subscription-Token": BRAVE_API_KEY,
        },
      }),
      new Promise<Response>((_, reject) => setTimeout(() => reject(new Error("timeout")), TIMEOUT_MS)),
    ]);
    if (!res.ok) return zero;
    const data = await res.json() as {
      results?: Array<{ url: string; age?: string; meta_url?: { hostname?: string } }>;
    };
    const results = data?.results ?? [];

    const domainCounts = new Map<string, number>();
    let tier1Count = 0, tier2Count = 0, tier3Count = 0;
    let last90DayMentionCount = 0;

    for (const r of results) {
      const domain = r.meta_url?.hostname ? r.meta_url.hostname.replace(/^www\./, "") : apexDomain(r.url);
      const tier = classifyPublisherTier(domain);
      if (tier === 1) tier1Count++;
      else if (tier === 2) tier2Count++;
      else tier3Count++;
      const daysAgo = parseDaysAgo(r.age ?? "");
      if (daysAgo <= 90) last90DayMentionCount++;
      domainCounts.set(domain, (domainCounts.get(domain) ?? 0) + 1);
    }

    const topPublishers = [...domainCounts.entries()]
      .sort((a, b) => b[1] - a[1])
      .slice(0, 5)
      .map(([d]) => d);

    return {
      mentionCount: results.length,
      last90DayMentionCount,
      tier1Count,
      tier2Count,
      tier3Count,
      topPublishers,
    };
  } catch (err) {
    console.warn("[editorial-mentions] lookup failed:", err instanceof Error ? err.message : err);
    return zero;
  }
}
